freejoshの答えは機能します。ただし、e.stopPropagation()
イベント委任を使用する他のハンドラーがある場合、それらのハンドラーは呼び出されない可能性があるため、呼び出しによって望ましくない副作用が生じる可能性があります。
イベント処理の基本の 1 つは、2 つの異なる div を表示する必要がある 2 つのボタンがある場合など、他のハンドラーにできるだけ影響を与えたり依存したりしないことです。を呼び出してe.stopPropagation()
、ポップアップの 1 つをクリックしても、他のポップアップが非表示になりませんでした。ライトボックスのイベント ハンドラーと衝突して機能しなかった例については、document.click がメニューをトグルし続けるを参照してください。したがって、他のコードに影響を与えない解決策は、クリックがボタンまたはポップアップ内からのものではない場合にのみ機能するドキュメント クリック ハンドラーをインストールすることです。
http://jsfiddle.net/b4PXG/2/
HTML
Here is my web page <button id="show-btn"> show popup</button>
<div id="modal" > I will show over everything <a href="http://google.com" target="_blank">Google</a></div>
JS
var modal = document.getElementById('modal');
var btn = document.getElementById('show-btn');
btn.onclick = function() {
modal.style.display = "block";
};
document.onclick = function (e) {
e = e || window.event;
var target = e.target || e.srcElement;
if (target !== btn && (!target.contains(modal) || target !== modal)) {
modal.style.display = 'none';
}
}
このパターンを、doc クリック ハンドラーを作成する関数に抽象化できます。
/**
* Creates a handler that only gets called if the click is not within any
* of the given nodes
* @param {Function} handler The function to call (with the event object as
* as its parameter)
* @param {HTMLElement} exclude... If the click happens within any of these
* nodes, the handler won't be called
* @return {function} A function that is suitable to be
* bound to the document click handler
*/
function createDocClickHandler(handler /* [,exclude, exclude, ...] */) {
var outerArgs = arguments;
return function (e) {
e = e || window.event;
var target = e.target || e.srcElement;
// Only call the original handler if the click was outside all the excluded nodes
var isWithinExcluded = false;
for (var i=1; i < outerArgs.length; i++) {
var excluded = outerArgs[i];
if (target === excluded || excluded.contains(target)) {
isWithinExcluded = true;
break;
}
}
if (!isWithinExcluded) {
handler.call(this, e);
}
}
}
var modal = document.getElementById('modal');
var btn = document.getElementById('show-btn');
btn.onclick = function() {
modal.style.display = "block";
};
// Assign the handler that will hide the popup if the clicked
// happened outside of modal and btn
document.onclick = createDocClickHandler(function (e) {
modal.style.display = 'none';
}, modal, btn);