【问题标题】:Backbone view event handler for checkbox and labels复选框和标签的主干视图事件处理程序
【发布时间】:2015-10-28 08:43:35
【问题描述】:

我正在尝试找出用户单击复选框后是否不勾选。该复选框被包裹在一个标签中,该标签也必须是可点击的。我的 HTML 代码是:

<div id="view_container">a</div>

<script type="text/template" id="view_template">
  <ul>
        <li>
            <label>
                <input type="checkbox" checked="" value="a">A option
           </label>
        </li>
        <li>
            <label>
              <input type="checkbox" value="b">B option
            </label>
       </li>
        <li>
           <label>
             <input type="checkbox" value="c">C option
          </label>
        </li>
     </ul> 
</script>

回答 JavaScript:

View = Backbone.View.extend({
  initialize: function() {
    console.log('in the init');
    this.render();
  },
  render: function() {
    var template = _.template($("#view_template").html(), {});
    this.el.html(template);
  },
  events: {
    'click ul li label': 'clicked',
  },

  clicked: function(e) {
    e.stopPropagation();

    console.log('e.target is ' + e.target);
    console.log('e.currentTarget is ' + e.currentTarget);

    var isChecked = $(e.currentTarget).find('input:first').is(':checked');
    var selected = $(e.currentTarget).find('input:first').val().trim();

    console.log('isChecked is ' + isChecked);

  },
});

var view = new View({
  el: $("#view_container")
});

jsfiddle 是here

有几个问题。如果我单击输入,它工作正常,isChecked 的值为 true。但是,如果我单击标签,函数clicked 会执行两次,console.log 输出为:

e.target is [object HTMLLabelElement]
e.currentTarget is [object HTMLLabelElement]
isChecked is false
e.target is [object HTMLInputElement]
e.currentTarget is [object HTMLLabelElement]
isChecked is true

所以isChecked 第一次是假的。

那么,无论用户是点击标签还是直接点击输入,我如何知道复选框是否被选中?当用户点击标签时,如何阻止处理程序执行两次?

【问题讨论】:

    标签: javascript html backbone.js


    【解决方案1】:

    问题在于,本质上,包含&lt;input&gt;s 或通过for 属性连接到它们的标签会触发相关输入上的点击事件。所以有2个点击事件:

    • 实际点击&lt;label&gt;
    • 标签在&lt;input&gt; 上触发的点击。

    因此,如果我们监听标签上的点击事件,我们将在这种情况下同时捕获它们 - 因为在 &lt;input&gt; 上触发的点击也会冒泡到 &lt;label&gt;,因为它是父级。

    我们可以通过监听复选框本身而不是标签的点击来解决这个问题。

    您可以使用带有:checkbox:checked 选择器的jQuery is 方法执行以下操作,如下所示。

        View = Backbone.View.extend({
        initialize: function () {
            this.render();
        },
        template: _.template($("#view_template").html()),
        events: {
            'click ul li :checkbox': 'clicked',
        },
        render: function () {
            this.$el.append(this.template({}));
        },
        clicked: function (e) {
            var $target = $(e.target);
            var selected = $target .is(':checked');
            console.log('selected: ', selected, 'value: ', $target.val());
        }
    });
    
    var view = new View({
        el: $("#view_container")
    });
    

    Updated fiddle

    请注意,最好将模板函数缓存起来,而不是在每次调用 render 时调用_template

    【讨论】:

      【解决方案2】:

      请在此处查看最佳答案 Why Does a Label Inside an Input Trigger a Click Event 。 简而言之,就是对标签元素的一种规范。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多