繁体   English   中英

事件处理程序不适用于动态添加的元素

[英]Event handler not working for dynamically added elements

我正在尝试找到一种将事件处理程序分配给动态创建的每个框的方法。 现在,用户可以单击“在上方添加”或“在下方添加”,无论他们单击何处,都会出现两行框。

我还试图做到这一点,以便当用户单击特定的正方形时,将弹出colorPicker并可以更改特定正方形的颜色。

但是由于某种原因,仅当用户单击前两行正方形时才会弹出选色器。 如果在当前集的下方或上方动态添加了更多行,则单击正方形将无任何反应。

有谁知道为什么会这样?

到目前为止我已经做过/尝试过的是:

http://codepen.io/anon/pen/bwBRmw

var theParent = document.querySelector(".container");
theParent.addEventListener("click", doSomething, false)
function doSomething(e) {
   console.log("gets inside doSomething")
   console.log(e.target)
   console.log(e.currentTarget)
if (e.target !== e.currentTarget && e.target.id !== "") {
    var clickedItem = e.target.id;
    console.log("Clicked on " + clickedItem);
    var led = document.getElementById(clickedItem)

    if(!picker){
        console.log("new picker initialized")
        picker = new Picker(led)
    }
    else{
        console.log("gets inside else case")
        picker.settings.parent = led;
    }
    picker.show();

}
 picker.on_done = function(colour) {
    $(led).css('background-color',colour.rgba().toString());
    picker.hide()
    }

//e.stopPropagation();
}

如果您希望它也适用于动态生成的输入,则必须稍作更改。

这不适用于动态生成的输入演示

$('input').keyup(function() {
    for (var i = 0; i < triggerWords.length; i++) {
        if ($(this).val().toLowerCase().indexOf(triggerWords[i]) != -1) {
            alert("Alert! You've typed a blocked word.");
        }
    }
});

但这确实是Demo

 $(document).on('keyup', 'input', function() {
    for (var i = 0; i < triggerWords.length; i++) {
        if ($(this).val().toLowerCase().indexOf(triggerWords[i]) != -1) {
            alert("Alert! You've typed a blocked word.");
        }
    }
});
$(document).on('click', '.your-element', function (e) {
  e.preventDefault();

  doSomething();
);

您的事件处理程序实际上运行良好,问题在于您的ID在HTML中的声明!

当您单击任何.repeat按钮时,您正在克隆当前的#repeatable并更改其ID,但是却忘记更改.startLEDs和.endLEDs元素ID ,而这些ID最终会重复出现,这就是为什么选择器在您无法使用时在第一个#repeatable下面的#repeatable正方形中单击,因为浏览器从未找到这些正方形元素,而是在页面中找到第一个正方形!

无需将id关联到.startLEDs和.endLEDs元素,而是可以关联另一个数据属性 ,例如' data-id '或可以重复的内容。

您还会遇到另一个问题,因为用于选择器的插件会将选择器附加到ID为'#picker_wrapper'的单击的led a元素)中 ,因此当您克隆#repeatable时, 您还将克隆选择器元素 ,因此,出于同样的原因,即使将led id更改为data-id, 克隆后页面中第一个选择器下方的选择器也将停止工作 要解决此问题,在克隆之前,我们应该首先销毁或从DOM中删除上次使用的选择器。

这是一个可能的解决方案:

 // vars var repeatableId = 0, picker, $led; // functions function removePicker () { if (picker) { $led.removeClass('selected').find('#picker_wrapper').remove(); picker = null; } } function onPickerDone (color) { $led.css('background-color', color.rgba().toString()); removePicker(); } $(document).ready(function () { // event listeners $('body').on('click', '.repeat', function (e) { var $self = $(this), $parent = $self.parent(), $parentClone; removePicker(); $parentClone = $parent.clone(true).attr('id', 'repeatable' + ++repeatableId); if ($self.hasClass('add-bottom')) { $parent.after($parentClone); } else { $parent.before($parentClone); } }); $('.container').on('click', function (e) { var $target = $(e.target); if ($target.hasClass('js-led')) { removePicker(); $led = $target; $led.addClass('selected'); picker = new Picker($led[0]); picker.on_done = onPickerDone; picker.show(); } }); }); 
 .bottomdiv { clear: both; position: fixed; bottom: 0; height: 50%; width: 100%; font-size: 16px; text-align: center; overflow: auto; } .bottomdiv > .container { margin-top: 60px; float: left } .bottomdiv > .container > .repeatable > .timeMilli { display: inline-block; } .bottomdiv > .container > .repeatable > .repeat { display: block; } .bottomdiv > .container > .repeatable a { position: relative; display: inline-block; width: 30px; height: 30px; background-color: #ccc; border: 1px solid #000000; z-index: 0; } .bottomdiv > .container > .repeatable a.selected { z-index: 1; } 
 <script src="http://iamsaravieira.com/picker.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <div class="bottomdiv"> <div class="container"> <div class="repeatable"> <button class="repeat add-top">Add above</button> <div class="startLEDs"> <a class="js-led startLEDs" data-id="sLED1"></a> <a class="js-led startLEDs" data-id="sLED2"></a> <a class="js-led startLEDs" data-id="sLED3"></a> <a class="js-led startLEDs" data-id="sLED4"></a> <a class="js-led startLEDs" data-id="sLED5"></a> <a class="js-led startLEDs" data-id="sLED6"></a> <a class="js-led startLEDs" data-id="sLED7"></a> <a class="js-led startLEDs" data-id="sLED8"></a> <a class="js-led startLEDs" data-id="sLED9"></a> <a class="js-led startLEDs" data-id="sLED10"></a> <a class="js-led startLEDs" data-id="sLED11"></a> <a class="js-led startLEDs" data-id="sLED12"></a> </div> <div class="endLEDs"> <a class="js-led endLEDs" data-id="eLED1"></a> <a class="js-led endLEDs" data-id="eLED2"></a> <a class="js-led endLEDs" data-id="eLED3"></a> <a class="js-led endLEDs" data-id="eLED4"></a> <a class="js-led endLEDs" data-id="eLED5"></a> <a class="js-led endLEDs" data-id="eLED6"></a> <a class="js-led endLEDs" data-id="eLED7"></a> <a class="js-led endLEDs" data-id="eLED8"></a> <a class="js-led endLEDs" data-id="eLED9"></a> <a class="js-led endLEDs" data-id="eLED10"></a> <a class="js-led endLEDs" data-id="eLED11"></a> <a class="js-led endLEDs" data-id="eLED12"></a> </div> <div class="timeMilli">Time(ms): <input type="text" name="time" form="form1"></div> <button class="repeat add-bottom">Add below</button> </div> </div> </div> 

结论

-切勿在HTML中使用重复的ID

PS: 我没有更改任何班级,因为您可能以某种方式在项目中需要它们

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM