2016-09-21 2 views
0

Я пытаюсь найти способ назначить обработчики событий для каждого окна, которое я создаю динамически. На данный момент пользователь может нажать «Добавить выше» или «Добавить ниже», и будут отображаться 2 строки ящиков, где бы они ни находились.Обработчик событий не работает для динамически добавленных элементов

Я также пытаюсь сделать так, чтобы, когда пользователь нажимает на определенный квадрат, появляется цветная панель, и цвет определенного квадрата может быть изменен.

По какой-то причине цветовой приказ появляется только тогда, когда пользователь нажимает на первые две строки квадратов. Если добавлено больше строк динамически добавлено ниже или выше текущего набора, ничего не происходит, когда вы нажимаете на квадраты.

Кто-нибудь знает, почему это может произойти?

Что я сделал/пытался до сих пор:

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) (также есть эти строки в моей ссылке на код) – blazerix

+0

вы поместили новый элемент AFTER() в контейнер? Использовать append() – poashoas

+0

Когда я проверяю элемент, он находится внутри контейнера – blazerix

-1

обработчики событий на самом деле работает хорошо, проблема заключается в декларации свой идентификатор в вашем HTML!

При нажатии на любую кнопку .repeat, клонировании текущий #repeatable и изменения его идентификатор, но вы забыли изменить .startLEDs и .endLEDs элемент идентификаторами, который в конечном итоге повторяются, это почему сборщик никогда не работает, когда вы нажимаете # повторяющиеся квадраты ниже первого #repeatable, потому что браузер никогда не находит эти квадратные элементы, а вместо этого найдет первые на странице!

Вместо того чтобы связывать идентификаторы с .startLEDs и .endLEDs элементов, вы можете связать другой атрибут данных вместо этого, например, «данных идентификатора» или что-то, что может быть повторено.

У вас также есть еще одна проблема, так как плагин используется для сборщика присоединяет ловильного к щелкнул привело ( элемент)с идентификатором «» #picker_wrapper, когда вы клонировать #repeatable , вы также клонируете элемент выбора, поэтому по той же причине, даже после изменения идентификатора светодиода на идентификатор данных, сборщики под первым сборщиком на странице после клонирования прекратили бы работать. Чтобы исправить это, мы должны сначала либо уничтожить, либо удалить из 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

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."); 
     } 
    } 
}); 
Смежные вопросы