【问题标题】:Clicking on label doesn't trigger click event点击标签不会触发点击事件
【发布时间】:2019-06-06 16:10:21
【问题描述】:

我有这个代码:

<label><input type="checkbox">True?</label>

$("label").click(function () {
  $(this).toggleClass("active");
});

当我单击复选框类切换时,当我单击“True?”时什么都没发生。为什么?

然后,如果我不在标签中包含复选框,一切正常。

<input type="checkbox" id="c1"><label for="c1">True?</label>

这太奇怪了......我是否输入“for”都没关系。

http://jsfiddle.net/zufs6ueh/1/

这里出了什么问题?

【问题讨论】:

  • onclick 会触发两次吗? label 以特定方式与 input 交互。
  • 不知道为什么,我认为标签的点击事件可能会在它包含在标签或类似的东西中时被重新分配给输入,但解决方案可能是将事件绑定到输入和更改父母的标签,如$("label input").click(function () { $(this).parent('label').toggleClass("active"); });
  • @Halcyon 是的,onclick 似乎触发了两次,因为我在网络检查器中看到了空的“类”。这可以解决吗?

标签: javascript jquery


【解决方案1】:

这样使用会更安全:

$(function() {

    $('input[type="checkbox"]').bind('change', function (v) {

        if($(this).is(':checked')) {
            $(this).parent().addClass('active');
        } else {
            $(this).parent().removeClass('active');
        }
    });

});

使用change 而不是click 允许人们使用键盘导航表单。

【讨论】:

  • 您的答案是建议在输入上绑定事件,而不是在所有标签上。无论如何,如果你的意思是使用空格键来检查复选框,当你说“允许人们使用键盘导航表单”时,它认为根本没有问题,因为空格键触发click为出色地。 +1
  • @DontVoteMeDown 谢谢,我不知道空格键触发click。你每天都能学到一些东西!但是是的,你是对的,这里的主要问题是将事件附加到复选框而不是标签。
  • 好的,这很好,但我仍然需要知道我原来的例子有什么问题。
  • @Andrey 如前所述,单击标签时会触发两次“单击”事件。您可以将evt.stopPropagation(); evt.preventDefault(); 添加到click 函数的末尾以防止这种情况发生。 (和evt作为函数的参数)
  • @rwacarter,是的,但为什么它会触发两次?是不是很奇怪?也许这是一个错误? ;-)
【解决方案2】:

单击标签也会触发对输入的单击,因此将更改事件绑定到复选框本身:

$(function(){
    $("label input").on("click",function(){
	$(this).parent().toggleClass("active");
    });
});
.active {color:red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<label><input type="checkbox" />True?</label>

或使用 CSS 3

如果您不需要支持旧浏览器,您可以使用 CSS 中的 :checked 伪类:

input[type=checkbox]:checked + label {color:red;}
<input type="checkbox" id="demo" name="demo"> 
<label for="demo">True?</label> 

【讨论】:

  • 我总是喜欢在不必要的时候避免使用 javascript,但请注意 :checked 伪类在 IE 中不起作用
  • @rwacarter - 同意。是不是很烦人?理想情况下,您会测试支持,然后使用 JS 后备。
  • @Moob,您的代码执行与@rwacarter 建议的相同的操作,但仍不清楚为什么onclick 会触发两次... 至于JS,我需要它在单击标签后执行其他操作,所以无法避免。
【解决方案3】:

你真的很接近@Andrey,关于 HTML 的一些值得注意的事情 inputs;

  • radiocheckbox HTML types 可以有一个 onclick 调用 JavaScript

  • radiocheckbox HTML types 都有可能被 JavaScript 检查的 .checked 属性和 CSS 中的 :checked 伪类

  • radio HTML types上使用names允许分组事物

这里有一些示例代码stuffcheckbox...

/**
 * Example JavaScript function for HTML input radio or checkbox types to call
 * @returns {boolean}
 */
function checkCheckbox(checkbox) {
  if (checkbox.checked != true) return false;
  /* Do JavaSript things when checkbox is checked */
  console.log('checkbox.checked -> ' + checkbox.checked);
  window.alert('checkbox.value -> ' + checkbox.value);
  return true;
}
/**
 * Hide things that should not be seen by just anyone
 */
.menu__checkbox,
.menu__container {
  display: none;
  visibility: hidden;
  opacity: 0;
  filter: alpha(opacity=0); /* Old MS compatibility */
}

/**
 * Stylize the label some
 */
.menu__label {
  display: block;
  width: 20px;
  height: 100%;
  transform: rotate(90deg);
}


/**
 * Show some things when checkbox is checked
 * Note, if feeling adventurous try using a `~` instead of `+`
 */
.menu__checkbox:checked + .menu > .menu__container {
  display: block;
  visibility: visible;
  opacity: 1;
  filter: alpha(opacity=100);
}

/**
 * Oh and un-rotate label when checkbox is checked too
 */
.menu__checkbox:checked + .menu > .menu__label {
  transform: rotate(0deg);
}
<input type="checkbox"
       class="menu__checkbox"
       value="valuable_checkbox"
       onclick="checkCheckbox(this);"
       id="trigger-menu">


<div class="menu">

  <div class="menu__container">
    <p class="menu__description">
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
      proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </p>
  </div>

  <label for="trigger-menu"
         class="menu__label">
         &#x25B2;
  </label>

</div>

...如果你看起来真的很近,定位通过trigger-menu在上述labelfor@987654341之间共享@'s id 正在使用 CSS 和 HTML 做一些很多人可能会求助于 JavaScript 的事情……尽管将复选框放在菜单范围之外只是为了演示;只是因为某事可以做并不总是意味着应该换句话说。

就像我逃避问题的代码真的很接近......

<input type="checkbox" id="c1"><label for="c1">True?</label>

...可能会与...一起使用

<input id="c1" type="checkbox" onclick="window.alert('this.checked -> ' + this.checked);">
<label for="c1">Is checked?</label>

正如我还暗示radio typed inputs 可以类似使用,以下是可能制作的东西的预览某天在一些荒谬的事情中公开......

    <div class="menu__style">
      <input type="radio"
             name="colorize"
             value="Default"
             onclick="color_picker.unsetAlternateStyleSheet()"
             class="menu__style__item"
             id="style-default">
      <label for="style-default"
             class="menu__style__label">Default Style</label>
      <br>

      <input type="radio"
             name="colorize"
             value="AlternateStyleOne"
             onclick="color_picker.setAlternateStyleSheet(title = this.value)"
             class="menu__style__item"
             id="style-one">
      <label for="style-one"
             class="menu__style__label">First Alternative Style</label>
      <br>

      <input type="radio"
             name="colorize"
             value="AlternateStyleTwo"
             onclick="color_picker.setAlternateStyleSheet(title = this.value)"
             class="menu__style__item"
             id="style-two">
      <label for="style-two"
             class="menu__style__label">Second Alternative Style</label>
    </div>

【讨论】:

    猜你喜欢
    • 2019-03-03
    • 2018-04-18
    • 2020-12-27
    • 2013-06-15
    • 2011-11-19
    • 1970-01-01
    • 2013-05-19
    • 2015-12-19
    相关资源
    最近更新 更多