JS上的Noob - 为什么document.onclick无法正常工作?

时间:2012-12-06 21:14:29

标签: javascript function events onclick handler

我正在尝试在单击链接时显示图片库,并在此后单击浏览器窗口中的任何位置时消失。我可以更改与单击“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";
  }

由于

2 个答案:

答案 0 :(得分:3)

freejosh的回答有效。但是,如果有其他处理程序使用事件委托,则调用e.stopPropagation()可能会产生不良副作用,因为这些处理程序可能无法被调用。

事件处理的基础之一是它们不应该尽可能地影响或依赖其他处理程序,比如说你有两个按钮需要显示两个不同的div。致电e.stopPropagation()clicking on one of the popups would not hide the other popup。请参阅document.click keep toggling the menu,了解它与灯箱事件处理程序发生冲突后无法正常工作的示例。因此,不影响任何其他代码的解决方案是安装文档单击处理程序,只有在单击不是来自按钮或弹出窗口时才会执行其工作。

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';
    }  
}

您可以将此模式抽象为function that creates the doc click handlers

/**
 * 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);

答案 1 :(得分:2)

每次点击document元素时,您的点击事件都会冒充hoverage,因此正在调用gallerymake() gallerytake()。有关事件的说明,请参阅this page

要防止这种情况使用e.stopPropagation()See this fiddle for a working example