2016-09-21 36 views
0

動的に作成する各ボックスにイベントハンドラを割り当てる方法を見つけようとしています。現時点では、ユーザーは「上に追加」または「下に追加」をクリックすることができ、クリックした場所に2行のボックスが表示されます。動的に追加された要素のイベントハンドラが機能しない

また、ユーザーが特定の四角形をクリックすると、colorPickerがポップアップし、その特定の四角形の色を変更できるようにしようとしています。

しかし、何らかの理由で、ユーザーが最初の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

読みます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

新しい要素をコンテナに入れますか? append()を使用してください – poashoas

+0

私は要素を調べるとき、それはコンテナの中にあります – blazerix

-1

あなたのイベントハンドラが実際にうまく働いている、問題はあなたのHTMLのあなたのidの宣言です:私がこれまで試した/やっていること

あなたはどの.REPEATボタンをクリックすると、あなたは現在の#repeatableをクローニングし、そのIDを変更することが、あなたが繰り返されて終わる.startLEDsと.endLEDs要素のidのを、変更することを忘れている、これは最初の#repeatable以下の#repeatable四角形をクリックしたときにピッカーが動作しないのはなぜですか?なぜならブラウザはこれらの四角形の要素を見つけることができず、代わりにページ内の最初のものを見つけるためです。代わりに.startLEDsと.endLEDs要素にidを関連付ける

は、あなたが別のデータは「データ-ID」または繰り返すことができる何かのように、代わりに属性に関連付けることができます。

あなたがピッカーに使用するプラグインは、あなたが#repeatableのクローンを作成する際にクリックされたのピッカーが、ID「#picker_wrapper」で要素)を率い追加ので、あなたはまた、別の問題を抱えています同様にピッカー要素もクローニングしています。同じ理由から、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:あなたはそれが同様に動的に生成された入力のために仕事をしたい場合はは、あなたのプロジェクト何とか

+0

なぜdownvote? – Daniel

0

でそれらを必要とするかもしれないので、私はあなたのクラスのいずれかを変更していなかった、あなたはあなたの関数を変更する必要があります少し。 ([__`Event delegation` __]について

これは、動的に生成された入力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."); 
     } 
    } 
}); 
関連する問題