2

リンクをクリックすると写真のギャラリーが表示され、その後ブラウザ ウィンドウのどこかをクリックすると消えるようにしようとしています。「galleryshow」要素のクリックに関連付けられた機能を変更して、クリックするとギャラリーが表示され、もう一度クリックするとギャラリーが消えるようにすることができます。しかし、ウィンドウ(またはドキュメント)をクリックするとギャラリーが閉じるようにしようとすると、何も起こりません。

これは私のコードです:

function gallerymake() {

    document.onclick = function () {gallerytake();};
   // document.getElementById("hoverage").onclick = function() {gallerytake();}; 
    document.getElementById("galleryhold").style.visibility="visible";
}

  function gallerytake(){
    document.getElementById("hoverage").onclick = function () {gallerymake();};
    document.getElementById("galleryhold").style.visibility="hidden";
  }

ありがとう

4

2 に答える 2

3

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);
于 2012-12-06T21:57:22.943 に答える
2

要素documentをクリックするたびにクリックイベントが発生するため、 とが呼び出されます。イベントの説明については、このページを参照してください。hoveragegallerymake() gallerytake()

この使用を防ぐためにe.stopPropagation()実際の例については、このフィドルを参照してください

于 2012-12-06T21:25:04.917 に答える