令人费解的点击事件:为什么会出现这样的行为?

时间:2014-12-22 09:46:15

标签: javascript jquery html

我最近测试了<label>点击事件(点击后查找文本框),发现了一些异常情况。

在HTML标记中,

  • 如果<input>位于<label>内,则点击该事件 标签发射两次
  • 如果<input>位于<label>之外,则点击事件为。{ 按预期运作

为了更好地了解我尝试提出的内容,请参阅JS Fiddle

中的小提琴

我因此而感到困惑,无法弄清楚其背后的原因。任何人?

2 个答案:

答案 0 :(得分:3)

  

如果<input>位于<label>内,则该标签上的点击事件会触发两次

因为事件发生了泡沫&#39;通过DOM,从接收初始事件的元素(event.target,这里是<input />)到祖先。因为侦听器附加到<input />的父级,所以它首先在其后代上检测到的点击时触发,然后再次点击时自动触发。

为防止这种情况发生,您可以使用event.stopPropagation()来阻止冒泡。

因为event(在这种情况下)已经在<label> / event-handler被触发的位置冒泡到alert()元素,所以你必须明确调用event.stopPropagation()本身的<input />,而不是附加到<label>的事件处理程序:

&#13;
&#13;
$(function() {
  $('label input').click(function(event) {
    event.stopPropagation();
  });

  $(".v1 li label").click(function() {
    var ct = $(this).find("input").val();
    alert(ct);
  });

  $(".v2 li label").click(function() {
    var ct = $(this).parent().find("input").val();
    alert(ct);
  });
});
&#13;
ul {
  padding: 10px;
}
li {
  list-style: none;
  margin-bottom: 5px;
}
li label {
  display: block;
  background-color: #f0f0f0;
  padding: 5px;
  cursor: pointer;
  border: 1px solid #ccc;
}
li input {
  display: none;
}
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3><i>input</i> inside <i>label</i></h3>

<ul class="v1">
  <li>
    <label for="l1">
      <input type="radio" name="a" value="1" id="l1" />First</label>
  </li>
  <li>
    <label for="l2">
      <input type="radio" name="a" value="2" id="l2" />Second</label>
  </li>
  <li>
    <label for="l3">
      <input type="radio" name="a" value="3" id="l3" />Third</label>
  </li>
</ul>
<hr />
<h3><i>input</i> outside <i>label<i></h3> 
<ul class="v2">
  <li>
    <label for="ll1">Fourth</label>
    <input type="radio" name="b" value="4" id="ll1" />
  </li>
  <li>
    <label for="ll2">Fifth</label>
    <input type="radio" name="b" value="5" id="ll2" />
  </li>
  <li>
    <label for="ll3">Sixth</label>
    <input type="radio" name="b" value="6" id="ll3" />
  </li>
</ul>
&#13;
&#13;
&#13;

参考文献:

答案 1 :(得分:0)

在您的情况下,点击事件正在从标签传播到输入,然后再传播到标签,因此您可以找到两个警报。

当我们可以检查目标元素标记名称时,您可以使用下面的代码,如果它是INPUT,则返回进一步处理。

$(".v1 li label").click(function(event){
    if(event.target.tagName=='INPUT')
      return false;
   var ct= $(this).find("input").val();     
   alert("first "+ct);      
});

<强> JSFiddle Demo