使用live方法的jquery stopPropagation问题

时间:2010-07-28 13:25:51

标签: jquery

Jquery stopPropagation方法不适用于live方法。下面的代码可以正常使用click而不是live方法。任何帮助非常感谢。

代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Jquery Propagation and preventDetauls Example for Popup</title>
<style type="text/css">
 .icon.white{background:#FFFFFF;}
 .icon{-moz-border-radius:2px 2px 2px 2px;-moz-box-shadow:0 1px 2px #EAEDF4;background-color:#FFFFFF;border:1px solid #E4E8F1;float:left;margin:0 1% 1% 0;text-align:center;}
 .iconlinks{height:20px;}
 .info{float:right;}
 .icon a.infolink, .downloadlinks a, .iconza a.changecolor {color:#718DB5;display:block;font-size:10px;padding:4px 7px;text-decoration:none;}
 .icon .infolink {background-image:url(images/dwn-arrow.gif);background-position:35px center;background-repeat:no-repeat;padding-right:17px !important;position:relative;}
 .downloadlinks{float:left;width:130px;overflow:hidden;}
 .downloadlinks a{float:left;}
 .infolink:hover{background-image:url(images/arrow-white.gif);}
 .infolink:hover{background-color: #1f75cc;color: white !important;text-decoration: none !important;}
 .infolink.selected{z-index: 100;color: white !important;background-color: #1f75cc !important;background-image: url(images/arrow-white.gif) !important;}
 .icon-image{border:0px;}
 .service-name{font-family:Arial, Helvetica, sans-serif;font-size:14px;line-height:24px;color:#74767A;margin:3px;text-align:left;}
 .describe-icons{position:absolute;right:2px;bottom:2px;}
 .infomenu{text-align:left;margin-left:-150px;margin-top:-1px;position:absolute;width:260px;-moz-box-shadow:2px 2px 5px #2F3B4A;background-color:#FFFFFF;border:2px solid #1F75CC;z-index:50;}
</style>
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
 $(function(){
  $(document).click(function(){
   $("a.infolink").removeClass("selected");
   $("div.infomenu").hide();
  });
  $("a.infolink").live("click",function(e){
   $("a.infolink").removeClass("selected");
   $("div.infomenu").hide();
   $(this).addClass("selected");
   $(this).next().show();
   e.stopPropagation();
  });
  $("div.infomenu").live("click",function(e){
   e.stopPropagation();
   //e.preventDefault();
  });
  $("input.clickme").click(function(e){
   alert("I am fired");
  });
 });
</script>
</head>
<body>
<div id="tserviceslist" style="margin:25px;">         
 <div style="height: 178px; width: 178px;" id="icon-12608" class="icon white">            
  <div class="iconlinks">    
   <div class="info">
    <a href="#" class="infolink"  title="Click here to see more information about this Services." rel="nofollow">INFO</a>              
    <div id="infomenu-12608" class="infomenu" style="display: none;"><input type="button" value="clickme" class="clickme" />Information will come here</div>
   </div>
   <div class="downloadlinks">
    <h3 class="service-name">Cricket</h3>            
   </div>
  </div>
  <br />

 </div>        


</div>
</body>
</html>

感谢你, sureace。

3 个答案:

答案 0 :(得分:15)

您只需稍微更改处理程序的顺序,并使用/ check进行传播停止,如下所示:

$("a.infolink").live("click",function(e){
    $("a.infolink").removeClass("selected");
    $("div.infomenu").hide();
    $(this).addClass("selected");
    $(this).next().show();
    e.stopPropagation();
});
$("div.infomenu").live("click",function(e){
    e.stopPropagation();
});
$(document).click(function(e){
    if(e.isPropagationStopped()) return;  //important, check for it!
    $("a.infolink").removeClass("selected");
    $("div.infomenu").hide();
});
$("input.clickme").click(function(e){
    alert("I am fired");
});​

Give it a try here,请注意以下几点:

  • .live()处理程序位于document
  • 事件处理程序按照绑定到任何给定元素的顺序执行

您需要停止并检查传播,因为我们处于同一级别。 .stopPropagation()会阻止冒泡进入任何更高的但是无关紧要,它在DOM中的处于同一级别,因此您需要使用{{3来检查它是否已停止}}。此外,由于处理程序按顺序触发,您需要在其他事件处理程序之后绑定document.onclick ,否则它将首先执行,然后其他人尝试停止传播。

答案 1 :(得分:2)

这是因为.live() 依赖进行事件传播。

事件实际上并不放在元素上,而是放在根节点上。然后该事件冒泡到该节点,检查选择器是否有匹配,如果是,则触发。

因为事件在层次结构顶部之前才被触发,所以没有传播可以停止。

答案 2 :(得分:0)

我使用纯javascript也没有问题。虽然这与OP的问题(看起来很复杂)没有关系,但只是为那些喜欢JS而不是jQuery的人发布这个答案

<强> HTML:

<div class="ac_results">
<ul>
    <li class=""><span class="chkfix">
        <input type="checkbox" value="ABCD" name="sug_0" id="sug_0"><label for="sug_0">ABCD</label></span>
   </li>
   <li class=""><span class="chkfix">
        <input type="checkbox" value="abc" name="sug_1" id="sug_1"><label for="sug_1">abc</labe></span>
   </li>
</ul>

<强> jQuery的:

$(".ac_results li").live('click', function() {
   alert('li called')
});

$(".ac_results li input[type='checkbox']").live('click', function(e) {        
   e.stopPropagation();            //does not work
   alert('check box called');
});

<强>使用Javascript:

//get child elements
var checkbox = document.getElementsByTagName('input');
for(var i=0;i<checkbox.length;i++){ 
     checkbox[i].onclick = callCheck; 
}
//get parent element
var li = document.getElementsByTagName('li');
for(var j=0;j<li.length;j++){ 
     li[j].onclick = liClick; 
}

function liClick(e){ 
    alert('list item clicked'); 
}
//stop the event propagation to parent elements
function callCheck(e){ 
    e.stopPropagation(); 
    alert('checkbox clicked'); 
}

var checkbox = document.getElementsByTagName('input');
for (var i = 0; i < checkbox.length; i++) {
  checkbox[i].onclick = callCheck;
}
var li = document.getElementsByTagName('li');
for (var j = 0; j < li.length; j++) {
  li[j].onclick = liClick;
}

function liClick(e) {
  alert('list item clicked');
}

function callCheck(e) {
  e.stopPropagation();
  alert('checkbox clicked');
}
<div class="ac_results">
  <ul>
    <li class=""><span class="chkfix">
            <input type="checkbox" value="ABCD" name="sug_0" id="sug_0"><label for="sug_0">ABCD</label></span>
    </li>
    <li class=""><span class="chkfix"><input type="checkbox" value="abc" name="sug_1" id="sug_1"><label for="sug_1">abc</label></span>
    </li>
  </ul>
</div>