【问题标题】:Click event handler not persisting for dynamically created checkboxesClick 事件处理程序不会为动态创建的复选框保留
【发布时间】:2016-08-02 22:33:00
【问题描述】:

我有一个 Javascript 脚本,我在其中定义了一个名为“Layer”的类。我将代码放在Layer 构造函数中,这样每次创建一个新的Layer 对象时,都会将与该层关联的复选框添加到HTML 文档中。我还在构造函数中创建了一个 JQuery 事件处理程序,以便在单击新复选框时,根据复选框的状态在文档中显示或隐藏图层。然而,由于某种原因,事件处理程序仅适用于最近创建的层。不知何故,旧的事件处理程序正在被覆盖。我在这里搜索了类似的问题,发现使用 JQuery 中的 on 函数而不是 click 是可行的方法,但我仍然遇到同样的问题。这是我的代码...

Layer2D.prototype.addToUI = function() {
    if (this.firstLayer()) {
        var layerDiv = document.createElement('div');
        layerDiv.className = 'content';
        layerDiv.id = 'layerNames';
    }
    else {
        var layerDiv = document.getElementById('layerNames');
    }

    layerDiv.innerHTML += '</br>' +
                          '<div class="ui toggle mini checkbox" id="layer' + this.name +'">' +
                          '<input type="checkbox" name="' + this.name + '" checked>' +
                          '</input>' +
                          '<label>' + this.name + '</label>' +
                          '</div>';

    if (this.firstLayer()) {
        var parentDiv = document.getElementById('layerMenu');
        parentDiv.appendChild(layerDiv);
    };
    $('#layer' + this.name).after('<br/>');

    var This = this;
    $('#layer' + this.name).on('click', ':input', function(e) {
        checked = $(this).is(':checked');
        console.log(This);
        if (checked === true) {
            This.show();
        }
        else { 
            This.hide();
        }
    });
};

【问题讨论】:

  • @MikeMcCaughan 我不这么认为。那里的解决方案是使用我已经在这里使用的 JQuery on() 方法。
  • 请阅读完整答案。它讨论了事件委托,使用on 的三个参数。
  • 我做到了,但我仍然对它如何应用在这里有一个模糊的概念。我认为我的问题(从答案看来是与 innerHTML 相关的)与该问题中的问题足够不同,足以保证它自己的帖子。

标签: javascript jquery


【解决方案1】:

您应该使用 $(document).on('click', '#layer' + this.name, function(){...}) 它通常适用于动态添加的 HTML。

【讨论】:

  • 太好了,这对我有用!我猜关键是在文档对象本身而不是在复选框上调用on() 方法。仍然不确定为什么一种方法会起作用而另一种不会。
  • 一个简短/简单的解释是 js 只知道您设置的属性过滤器已经存在的内容。如果您希望 js 超出此范围,则需要扩大它的范围,以便它可以找到您新创建的元素。
【解决方案2】:

innerHTML 有这个问题。如果您使用 Document.create 方法创建动态元素,我认为监听器将被附加。在任何情况下,您都可以将 evenListener(s) 放入 addEventListenerToBeer() 之类的函数中,并在 innerHTML 调用之后调用它。

var d = document.createElement("div")
var t = document.createTextNode("i like beer");
d.id = "myId";
d.appendChild(t); 

【讨论】:

  • 谢谢,我认为您对innerHTML 的问题是正确的。我很确定您的修复会起作用,但上述解决方案要简单一些。不过感谢您的帮助!
  • 另外,现在我很想用不同的 IPA 名称来标识我的所有 div 元素。
【解决方案3】:

你需要更换:

layerDiv.innerHTML += '</br>' +
                      '<div class="ui toggle mini checkbox" id="layer' + this.name +'">' +
                      '<input type="checkbox" name="' + this.name + '" checked>' +
                      '</input>' +
                      '<label>' + this.name + '</label>' +
                      '</div>';

为:

let element="";
//****
element = '</br>' +
                      '<div class="ui toggle mini checkbox" id="layer' + this.name +'">' +
                      '<input type="checkbox" name="' + this.name + '" checked>' +
                      '</input>' +
                      '<label>' + this.name + '</label>' +
                      '</div>';
$(element).appendTo(layerDiv);

appendTo 插入元素并使它们成为要查询的 DOM 的一部分...

【讨论】:

  • 好的,谢谢,我从没想到这是一个 innerHTML 问题。您的解决方案有点工作,但在这种情况下,每次添加新复选框时都会复制整个 innerHTML。
  • 是的,你是对的,它不需要 elements=layerDiv.innerHTML; 抱歉...我会更新我的答案...
猜你喜欢
  • 2019-01-29
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
  • 2011-12-21
  • 2010-12-04
  • 1970-01-01
  • 1970-01-01
  • 2019-04-13
相关资源
最近更新 更多