如何在JavaScript / jQuery中只有没有默认值时执行操作?

3

我被要求在div中的任何位置点击都会执行特定操作(例如折叠它),除非点击了链接、按钮等...

基本上,我想要的是event.preventDefault()的相反效果。

有没有好的简单方法来实现这个功能?

在这里,我正在寻找一个通用的解决方案;我希望不假设关于div内容的太多信息。

可能看起来像:

<div id="click_me>
<p>Clicking here should do stuff
   <a href="http://stackoverflow.com">but not here, nor on the following image</a>
   <a href="/xyz"><img url="/icon.png"/></a>
   imagine buttons... input areas, ...
</p>
</div>

使用以下JavaScript:

$("#click_me").click(function(){
  if(black_magic) {
    $("#click_me").toggleClass("collapsed");
  }
});
4个回答

4

您只需要确保事件的target不是链接或按钮。

$('#click_me').click(function(e) {
  interactive = 'a, button, input, textarea, video, map, object';
  if($(event.target).closest(interactive).length == 0) ) {
    $("#click_me").toggleClass("collapsed");
  }
});

不起作用,例如如果点击的是 a 标签内部的图像。 - Marc-André Lafortune
1
越来越接近了!我编辑了你的答案,使其更完整。不过,我仍然希望有一种更简单的方法,而且不会强制我停止冒泡,如果我想将事件处理程序附加到某些嵌套的divs上。也许其他人可以想出更好的答案。 - Marc-André Lafortune
为什么不使用.closest('.keepDefault'),并将该类添加到需要执行默认行为的每个元素,而不是使用interactive="a、button、input"等呢? - resopollution
@resopollution:我觉得容器的行为方式并不是内容的责任。容器可以非常通用,就像网站上可以在许多地方使用的GUI一样。 - Marc-André Lafortune

2

只需将此处理程序添加到您的链接中:

$("#click_me a,button,input,textarea,video,map,object").click(function(e){
   e.stopPropagation();
});

为了防止事件冒泡到div中,需要停止事件,这样链接才能正常工作。点击预览可以查看实例

华丽的预览!那么a里面的东西呢? - Marc-André Lafortune
2
<div>标签内部的内容会一直冒泡到<a>标签,所以如果<span>标签位于<a>标签内并被点击,<a>标签也会被点击,但是通过e.stopPropagation()可以阻止进一步的冒泡,因此在这种情况下,<a>标签外的<div>标签不会被折叠。 如果你不希望当<a>标签内部的元素(比如<span>标签)被点击时<a>标签也被点击,你可以给<span>标签绑定一个点击事件处理程序,并使用e.stopPropagation来停止冒泡。 - resopollution
@galambalaz:第一次使用jsbin,非常好。完全没有愤世嫉俗的感觉。实际上,即使是嵌入式的东西也可以很好地工作。我已经修改了它以允许添加按钮等等... - Marc-André Lafortune

1

事件冒泡是关键词。将事件处理程序绑定到div并检查事件目标以指定要执行的操作。

$('div.mydivclass').bind('click', function(event){
    switch(event.target.id){
        case 'id_of_an_anchor':{
              alert('anchor was clicked');
              break;
        }
        case 'id_of_a_span':{
              alert('span was clicked');
              break;
        }
        default: {
              alert('something else was clicked within me');
        }
    }
});

当然,你甚至可以检查目标是否为tagNamenodeType

如果目标在a标签内部,怎么办? - Marc-André Lafortune

0
function onClick(e){
    var gates = "A,INPUT,TEXTAREA,SELECT";
    var bound = this;
    var isCollapse = function ( node ){ 
    if( node == bound ){ return true; }
        var re = new RegExp( "\\b" +node.nodeName+ "\\b", "g" );
        return re.test( gates ) ? false : isCollapse( node.parentNode );
    };

    if( isCollapse( event.srcElement || e.target ) ){
        alert( "collapse" )
        // collapse()
    }
}
document.getElementById("click_me").onclick = onClick;

*修复*针对以下情况:<a href="_"><span><strike> a link </strike></span></a>


我更喜欢其他解决方案的风格,而且我认为当点击我时它不起作用:例如 <select>选择<b>我</b></select> - Marc-André Lafortune

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接