2016-09-21 33 views
0

我试图找到一种方法来将事件处理程序分配给我动态创建的每个框。目前,用户可以点击“添加上方”或“添加下方”,无论点击哪处,都会出现2行框。事件处理程序不能用于动态添加的元素

我也试图做到这一点,当用户点击特定的方块时,会弹出一个colorPicker,并且该方块的颜色可以改变。

由于某些原因,只有当用户点击前两排正方形时,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(); 
} 
+1

阅读有关[__'Event delegation' __]( https://learn.jquery.com/events/event-delegation/) – Rayon

+1

@Rayon我没有读过关于事件委托的内容,并将侦听器分配给父元素,以便避免绑定给每个子元素添加一个监听器(相当低效) – blazerix

+0

你想传达什么?你为什么觉得效率低下? – Rayon

回答

0
$(document).on('click', '.your-element', function (e) { 
    e.preventDefault(); 

    doSomething(); 
); 
+0

我还是相当新的Javascript,但这是怎么样的: var theParent = document.querySelector(“。container”); theParent.addEventListener(“click”,doSomething,false) (在我的codepen链接中也有这些行) – blazerix

+0

你把新元素AFTER()容器?使用append() – poashoas

+0

当我检查元素时,它在容器内 – blazerix

-1

你的事件处理程序的实际运作良好,问题是你的ID的声明在HTML!

当你点击任何按钮.repeat,你是克隆当前#repeatable并改变其ID,但你忘记更改被重复.startLEDs和.endLEDs元素的ID,它结了,这是为什么当你点击第一个#repeatable下面的#repeatable方块时,选择器从不工作,因为浏览器从来没有找到这些方形元素,而是找到页面中的第一个元素!

相反的ID关联到.startLEDs和.endLEDs元素,可以关联另一个数据属性相反,像“数据-ID”或一些可以重复。

你也有另外一个问题,因为你使用的选择器插件追加选择器的点击的发光二极管(在一个元素)id为“#picker_wrapper”,当你克隆#repeatable ,你也克隆选取元素,所以出于同样的原因,即使在更改领导ID的数据ID后,克隆后页面中第一个选择器下面的选取器将停止工作。为了解决这个问题,我们应该先删除或删除上次在克隆前使用的选取器。

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

// 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>

结论

- 不要使用重复的ID在你的HTML

PS:我并没有改变任何类,因为你可能需要他们在项目中以某种方式

+0

为什么downvote? – Daniel

0

如果你想让它动态生成的输入工作,以及,你必须改变你的功能一点。

这不起作用上动态地生成的输入Demo

$('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."); 
     } 
    } 
}); 
相关问题