用于复选框和标签的骨干视图事件处理程序

时间:2015-10-28 08:43:35

标签: javascript backbone.js

我试图找出一个复选框ID是否在用户点击之后没有被扯掉。 checkox包裹在一个必须可点击的标签中。我的代码是:

<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第一次是假的。

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

2 个答案:

答案 0 :(得分:9)

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

  • 实际点击<label>
  • 点击<input>上的标签触发。

因此,如果我们在标签上收听点击事件,我们会在这种情况下抓住这两个事件 - 因为<input>上触发的点击也会冒出<label>,因为它是父母

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

您可以使用带有: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

请注意,缓存模板函数是一种很好的做法,而不是每次调用渲染时调用_template

答案 1 :(得分:0)

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