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()如果有其他处理程序使用事件委托,则调用可能会产生不希望的副作用,因为这些处理程序可能不会被调用。

事件处理的基础之一是它们不应该尽可能地影响或依赖其他处理程序,例如,如果您有两个按钮需要显示两个不同的 div。通过调用e.stopPropagation()单击其中一个弹出窗口不会隐藏另一个弹出窗口。请参阅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';
    }  
}

您可以将此模式抽象为创建文档点击处理程序的函数

/**
 * 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每次单击hoverage元素时,您的单击事件都会冒泡,gallerymake() 因此 gallerytake()被调用。有关事件的说明,请参阅此页面

为了防止这种使用e.stopPropagation()请参阅此小提琴以获取工作示例

于 2012-12-06T21:25:04.917 回答