JavaScript +事件传播

时间:2012-05-09 16:41:35

标签: javascript javascript-events

我有一个成功切换隐藏div的输入框。但是,当用户点击div本身以外的任何内容时,我也希望div隐藏。我怎么能这样做?

HTML

<input id="inputID" type="text" readonly />
<div id="divID"></div>

JS

var divObj = document.getElementById('divID');
var inputObj = document.getElementById('inputID');

inputObj.addEventListener('click', toggleDiv, false);
function toggleDiv(){
    divObj.style.display = (divObj.style.display == 'none') ? 'block' : 'none'; 
}

3 个答案:

答案 0 :(得分:4)

document.body元素上创建一个事件监听器,检查事件是否来自div中的元素,如果不隐藏它。您可以通过不检查原点来简化此作业,但只需通过调用事件对象上的.stopPropagation()来阻止div中的点击事件冒泡。

divObj.addEventListener('click', function(e) {
    e.stopPropagation();
}, false);
document.body.addEventListener('click', function(e) {
    divObj.style.display = 'none';
}, false);

演示:http://jsfiddle.net/ThiefMaster/D7YnS/

答案 1 :(得分:0)

ThiefMaster的方法有效但如果你有多个地方需要做同样的事情,那么需要考虑一个小问题。假设您需要使用两个单独的div执行相同的操作,然后调用e.stopPropagation()会导致div1在单击div2时不被隐藏

实施例

div1.addEventListeners('click', function(e){
    e.stopPropagation();
}, false);
div2.addEventListener('click', function(e) {
    e.stopPropagation();
}, false);
document.body.addEventListener('click', function(e) {
    div1.style.display = 'none';
    div2.style.display = 'none';
}, false);

因此,更安全的替代方案是(为简单起见,我将使用jQuery)http://jsfiddle.net/qzMnj/1/

$(function() {
    function hideWhenClickOutside(element) {
      $(document).click(function(e){
        if ( !element.contains(e.target)) {
            $(element).hide();
        }
      });
    }

    hideWhenClickOutside(document.getElementById('div1'));    
    hideWhenClickOutside(document.getElementById('div2'));
})

我的观点是,调用stopPropagation()会产生不必要的副作用,如果你不必这样做,最好不要这样做,除非你确定没有人会关心那次点击。

答案 2 :(得分:0)

让我们看看这是否有效

  1. 调用普通侦听器隐藏div
  2. 向正文添加一个额外的侦听器,以隐藏您的div(如果没有隐藏)
  3. 向div本身添加一个监听器以停止该事件(2.上面)
    • 这称为Event Propagation
    • 点击div,最后点击身体
    • 当你点击div
    • 时,你不想打电话给你
  4. 另外,请注意上面的代码(你的)和下面的代码(我的代码)不是跨浏览器的(addEventListener在IE8中不起作用) 希望你忽略了这一点,这里是带有JS的HTML

    <!DOCTYPE HTML>
    <html>
    <head>
        <title>Lab</title>
        <style type="text/css">
            #divID {
                width: 100px;
                height: 100px;
                margin: 0 auto;
                margin-top: 85px;
                border: 1px solid #020202;
    
                // Unnecessary stuff
                -moz-border-radius:     2px;
                -webkit-border-radius:  2px;
    
                -moz-box-shadow:    0 0 8px #565656;
                -webkit-box-shadow: 0 0 8px #565656;
            }
        </style>
    </head>
    <body>
        <input id="inputID" type="text" readonly="readonly" />
        <div id="divID"></div>
    </body>
    
    <script type="text/javascript">
    
        var divObj = document.getElementById('divID'),
            inputObj = document.getElementById('inputID');
    
        inputObj.addEventListener('click', toggleDiv, false);
        document.body.addEventListener('click', docClick, false);
        divObj.addEventListener('click', divClick, false);
    
        function divClick(e) {
            // if you click any element inside the div
            // when the click reaches the div, stop going above
            e.stopPropagation();
        }
    
        function docClick(e){
            if (divObj.style.display !== 'none') {
                divObj.style.display = 'none';
            }
        }
    
        function toggleDiv(e) {
            e.stopPropagation();
            divObj.style.display = (divObj.style.display === 'none') ? 'block' : 'none'; 
        }
    
    </script>
    
    </html>