使 div 的一部分可点击

Make part of div clickable

我在使用弹出窗口 window 时遇到问题,该弹出窗口在可见时需要关闭 当用户单击底层灰色区域 (弹出窗口 window 后面的区域), 不是 弹出窗口 window 本身。

有什么办法可以实现吗?


HTML

<div>
    <div class="b-popup" id="uploader">
    <div class="b-popup-content" id="uploader">
        Text in Popup<br>
        <a href="javascript:PopUpHide()">Hide popup</a>
    </div>
</div>

CSS

*{
    font-family: Areal;
}
.b-container{
    width:200px;
    height:150px;
    background-color: #ccc;
    margin:0px auto;
    padding:10px;
    font-size:30px;
    color: #fff;
}
.b-popup{
    width:100%;
    min-height:100%;
    background-color: rgba(0,0,0,0.5);
    overflow:hidden;
    position:fixed;
    top:0px;
}
.b-popup .b-popup-content{
    margin:40px auto 0px auto;
    width:600px;
    height: 600px;
    padding:10px;
    background-color: #c5c5c5;
    border-radius:5px;
    box-shadow: 0px 0px 10px #000;
}

JavaScript - jQuery

$('div.b-popup').click(function () {
    PopUpHide();
});

样本在这里:http://jsfiddle.net/p7NbX/15/


我已经尝试在 div 单击时设置函数调用,但是如果我单击弹出内容 div,它会关闭弹出窗口。

向整个 .b-popup 添加点击事件侦听器,但仅当事件目标不同于 .b-popup-content 元素(编辑:或其任何子元素时才关闭弹出窗口,正如@BrettCaswell指出的那样),例如:

$('.b-popup').on('click', function(e){
    if( ! $(e.target).is('.b-popup-content, .b-popup-content *') ){
        PopUpHide();
    }

});

http://jsfiddle.net/p7NbX/1515/

这应该有用,它对我有用(由 dystroy 提供):

Original Answer

如果需要,您可能想要使用单击的元素位置和大小,使用 $(this).offset() 、$(this).width() 和 $(this).height()。例如:

$('mydivselector').click(function(e) {
  if (e.pageY > $(this).offset().top + 0.5*$(this).height()) {
      // bottom was clicked

 } else {
      // up of the div was clicked

 }
});

如果您想阻止默认操作和事件传播,return 事件处理程序中的 false。

$(document).ready(function(){
    PopUpHide();
    
    $("#popup1").click(function(e){
        if( e.target !== this ) return;
        PopUpHide();
    });
    
});

function PopUpShow()
{
  $("#popup1").show();
  }

function PopUpHide()
{
  $("#popup1").hide();
  }
*{
    font-family: Areal;
}
.b-container{
    width:200px;
    height:150px;
    background-color: #ccc;
    margin:0px auto;
    padding:10px;
    font-size:30px;
    color: #fff;
}
.b-popup{
    width:auto;
    background-color: rgba(0,0,0,0.5);
    overflow:hidden;
    position:fixed;
    top:0px;
    bottom:0px;
    left:0;
    right:0;
}
.b-popup-content{
    margin: 3em auto 0 auto;
    width: 100px;
    height: 40px;
    padding: 0.9em;
    background-color: #c5c5c5;
    border-radius:5px;
    box-shadow: 0.05cm 0.05cm 1em rgba(0,0,0,0.8);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="b-container">
    Sample Text
    <a href="javascript:PopUpShow()">Show popup</a>
</div>
<div class="b-popup" id="popup1">
    <div class="b-popup-content">
        Text in Popup
    <a href="javascript:PopUpHide()">Hide popup</a>
    </div>
</div>

这是一个替代方案,归结为 <Element>.addEventListener(<eventName>, <function>.bind(<this>[,<arg1>][,<arg2>]));

bind 包装预期的函数,并使用额外的指定参数 (args) 对其执行调用。 bind 的第一个参数将是函数的 this 实例。将其设置为 undefined 将传递原始 this 实例。


简答(jQuery)

$(document).ready(function()
{
    $("#popup1").hide();
    $('.b-popup').on('click', function(targetId, e){
        console.log("%o %o %o", targetId, e.target.id, e);
        if( e.target.id !== targetId ){ return; }
        PopUpHide();
    }.bind(undefined, "popup1"));       
});


function PopUpShow(){
    $("#popup1").show();
}
function PopUpHide(){
    $("#popup1").hide();
}

fiddle: http://jsfiddle.net/p7NbX/1514/


原答案

以下示例确实更适合重用和 oop (ish)。

/* I'm going to declare and keep my initialization code in an object. 
   that I'll run when the document is ready. 
*/
var MyHandlerManager = 
{     
    'elms' : [],
    'init': function()
    {            
        var CssSelector = "div.b-popup";
        var elms = document.querySelectorAll(CssSelector);
        for (var i = 0; i < elms.length; i++)
        {                
            elms[i].addEventListener('click', MyHandlers.HidePopupHandler.bind(undefined, elms[i].id));                
        }

        /* you can skip this. 
           You don't need to keep a reference to elms (NodeList) for the EventListeners to function properly.  
        */
        MyHandlerManager.elms = elms;
    }
};

您可以执行匿名函数而不是将现有函数引用为处理程序,但我喜欢这样声明我的处理程序..

这带来了一些调试和运行时的注意事项;喜欢,

  • 更容易清除 console.logs 行 and/or,
  • 如有必要,稍后会替换处理函数。

var MyHandlers =
{
    "ShowPopupHandler": function (targetId, e)
    {
        console.log("targetId: %o :: e.target.id: %o :: EventArgs: %o", targetId, e.target.id, e);
        if (e.target.id !== targetId) { return; }

        var elm = document.getElementById(targetId);            
        elm.style.display = "block";
    },
    "HidePopupHandler": function (targetId, e) 
    {
        console.log("targetId: %o :: e.target.id: %o :: EventArgs: %o", targetId, e.target.id, e);
        if (e.target.id !== targetId) { return; }

        var elm = document.getElementById(targetId);            
        elm.style.display = "none";
     }
};

$(document).ready(function(){
    PopUpHide();
    MyHandlerManager.init();
    /* Again, you could just take the code in the init() function
       and run it here..
       using 'bind' to wrap the intended function and call it, passing the elm.id as an argument (first arg) into anonymous functions. 
    */
});

function PopUpShow(){
    $("#popup1").show();
}

function PopUpHide(){
    $("#popup1").hide();
}