2012-03-31 7 views
0

2つのdiv要素で構成される非常に単純なjQueryの "ドロップダウンリスト"を作成しました。最初のdivをクリックすると、2番目のdivが表示されます。今度は、divの外側をクリックすると、2番目のdivが再び閉じられるようにします。しかし、私がすることはできません(と、それは必要ではない場合、実際にしたくない)このようなdocument-または身体・イベント・リスナーを使用します。文書/ボディーイベントリスナーなしでクリックしたときに要素を隠す

$('#div2').click(function(e) { 
    doSomething(); 
    e.stopPropagation(); 
}); 
$(document).click(function() { 
    $("#div2").hide(); 
}); 

理由:私が使用してページ上の他の要素を持っていますe.stopPropagation();とし、ドロップダウンを開いた後にユーザーがこれらの要素をクリックした場合、再び閉じることはありません。

e.stopPropagation();をクリックしてもドロップダウンを閉じるために何らかの形で処理されたこのプラグインjalDropdownが見つかりました。ページやブラウザの外のどこかであっても、ドキュメント/ body-event-リスナー:http://india.assigninfo.com/assignlabs/jaldropdown

嫌なことに、Operaで動作しないので、使用できません。そして私は最小化されていないソースコードのバージョンを見つけられなかったので、どのように動作するかを知ることができませんでした。

ドキュメント/ボディイベントリスナーなしで要素、ページ、またはブラウザの外をクリックすると、ドロップダウンが閉じられる(要素が非表示になる)ように、この動作を実現する方法はありますか?ありがとう!今

+0

はい、これは簡単に行うことができます。 Lemmeは私が書いた、あなた自身のために使ういくつかのユーティリティメソッドをつかまえます。 –

答えて

1

なぜ、あなたのコードにこの機能を追加し、代わりにするevent.stopPropagation(のそれを呼び出す、あなたの部門を非表示にするには、$(文書).click()関数を保持しない):

function stopPropAndCloseDiv2(event) { 
    $('#div2').hide(); 
    event.stopPropagation(); 
}; 

私はそれをテストしたところ、うまくいくと思われます。あなたはそれを覚えておく必要があります。

UPDATE:

これは私でかじって、私は私が知っているこの偉大なウェブサイト上で別の答えを見つけました。ここにリンクです:

add code to a function programatically with JS

が、私はそのアプローチを試みたが、動作しているようです:

jQuery.Event.prototype.stopPropagation = (function() { 
    var cached_function = jQuery.Event.prototype.stopPropagation; 

    return function() { 
     if (this.type == "click") { 
      // Your logic here. 
      console.log("I am a modified version of event.stopPropagation()!"); 
     } 
     cached_function.apply(this, arguments); // use .apply() to call it. 
    }; 
}()); 

$(document).click(function() { console.log("The document caught the event, too."); }); 
$('#clicker').click(function() { console.log("I'm going to let this event bubble."); }); 
$('#anotherClicker').click(function(event) { event.stopPropagation(); }); 

:ここ

http://jsfiddle.net/kXkFS/8/コードです(テストページのマークアップ内の2つのボタンがあります) Spoiler: "clicker"ボタンをクリックすると、ドキュメントもコンソールに記録されます。 「anotherClicker」ボタンをクリックすると、カスタムevent.stopPropagation()関数がコンソールにログを記録し、というドキュメントはコンソールにログを記録しません。これで、クリックイベントハンドラをドキュメントに追加できます。

1つのこと:オーバーヘッドがいくらか増加する可能性がありますが、stopPropagation()を頻繁に呼び出している場合に限ります。

誰かがこのようなjQueryオブジェクトを使用していることの賢明さを知りたい場合は、それをしてください。私は思っていますが、このような無害な変化が将来ウェブページを爆破することはないと思います。

+0

うーん、それはうまくいくでしょうが、この新しい関数でstopPropagation呼び出しを置き換えます。可能であれば、私はそれをやりたくはありませんが、$(document/body/window).click()を使わずに試してみてください.JALDropdownのようにしてください。 –

+0

@RenéSchubert:私が追加したアップデートでは、他のイベントハンドラだけを残すことができます。代わりに、渡されたイベントオブジェクトが変更されます。 – jCyCle

+0

興味深い、ありがとう!論理的な問題が1つしかありません。ドロップダウン内をクリックした場合(通常のドロップダウンの動作ではありませんが、まだユースケースのシナリオかもしれません)、ドロップダウンを終了しないためにはstopPropagation関数が必要です。また、 '$(document).click(function(){$( '#div2')。hide();});'を定義すると、ドロップダウンを開くことはできません。これは、関数のパラメータを次のように拡張した理由です。 'return function(noHide){if(this.type == 'click' &&!noHide)... 'このようにしてドロップダウンが閉じられるのを防ぐことができます。他のイベントハンドラに触れる必要はありません。 –

0
//generic drop-down menu 
//NOTE: only pass a menu object if there are multiple menus per toggle object 
var dropDown = function(toggle, menus) 
{ 
    toggle.click(function(e) { 
    e.preventDefault(); 
    //NOTE: container is assuming that the next sibling is the dropdown. 
    //change container to suit your needs 
    var container = $(this).next(); 
    if(menus !== undefined && !container.is(':visible')){ menus.hide(); } 

    if(!container.is(':visible')) 
    { 
     container.fadeIn('fast'); 
    } 
    else 
    { 
     container.fadeOut('fast'); 
    } 
    }); 
} 

//close stuff when the window is clicked 
var window_click = function(obj) 
{ 
    $(window).click(function(e) { 
    if(obj.is(':visible')) 
    { 
     obj.fadeOut(250); 
    } 
    }); 
} 

//override the window_click function when needed 
var stop_prop = function(obj) 
{ 
    obj.click(function(e) { 
    e.stopPropagation(); 
    }); 
} 

、ちょうどあなたがこのように好きな場所にそれらを使用する:あなたの散乱のstopPropagationを回避するために

<span class='toggle_name'></span> 
<ul class='menu_name' style='display:none;'> 
    <li>cool man</li> 
</ul>  

:私のドロップダウンマークアップのために

var toggle = $('#myToggle'); 
var menu = $('#myMenu'); 

dropDown(toggle, menu); 
window_click(menu); 
stop_prop(toggle); 
stop_prop(menu); 

、私はほとんど常にこのモデルを使用()では、すべてのメニュークラスを手動で閉じた小さな関数を作成することもできます。スーパーシンプル:

var menus = { 
    //add any dropdown menu ids or classes here 
} 

//run this method on any conflicting stopProp clicks 
var closeMenus = function() 
{ 
    for(var key in menus) 
    { 
    if(menus.hasOwnProperty(key)) 
    { 
     menus[key].hide(); 
    } 
    } 
} 
+0

私はこれを試しましたが、全く動作していないようです。ドロップダウンをトグルしますが、外をクリックするとドロップダウンしません。実際のjsfiddle-exampleを提供していただけますか? $(window).click()は、他の要素で使用されているstopPropagationで動作しません(closeMenus関数を使用している場合を除いていますが、私が触れる必要のないソリューションを探しています)。他のイベントハンドラ)。そして、jALDropdownもそのようなものなしで動作します。 –

+0

ここに行く:) http://jsfiddle.net/tpbjV/9/ –

+0

ありがとう。私がそれをクリックすると伝播を停止する要素を追加すると、あなたのソリューションはもはや動作しません:http://jsfiddle.net/Dg2UN/3/それは、要素イベントに余分なコードを追加することなく回避したいものです伝播を停止する-listener。 –

関連する問題