Saya mencoba memasukkan data html secara dinamis ke daftar yang dibuat secara dinamis, tetapi ketika saya mencoba untuk melampirkan acara onclick untuk tombol yang dibuat secara dinamis, acara tersebut tidak diaktifkan. Solusi akan sangat dihargai.
Kode Javascript:
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('btnSubmit').addEventListener('click', function () {
var name = document.getElementById('txtName').value;
var mobile = document.getElementById('txtMobile').value;
var html = '<ul>';
for (i = 0; i < 5; i++) {
html = html + '<li>' + name + i + '</li>';
}
html = html + '</ul>';
html = html + '<input type="button" value="prepend" id="btnPrepend" />';
document.getElementsByTagName('form')[0].insertAdjacentHTML('afterend', html);
});
document.getElementById('btnPrepend').addEventListener('click', function () {
var html = '<li>Prepending data</li>';
document.getElementsByTagName('ul')[0].insertAdjacentHTML('afterbegin', html);
});
});
Kode HTML:
<form>
<div class="control">
<label>Name</label>
<input id="txtName" name="txtName" type="text" />
</div>
<div class="control">
<label>Mobile</label>
<input id="txtMobile" type="text" />
</div>
<div class="control">
<input id="btnSubmit" type="button" value="submit" />
</div>
</form>
javascript
Manju
sumber
sumber
Jawaban:
Ini karena fakta bahwa elemen Anda dibuat secara dinamis. Anda harus menggunakan delegasi acara untuk menangani acara tersebut.
document.addEventListener('click',function(e){ if(e.target && e.target.id== 'brnPrepend'){ //do something } });
jquery membuatnya lebih mudah:
$(document).on('click','#btnPrepend',function(){//do something})
Berikut adalah artikel tentang artikel acara delegasi acara delegasi
sumber
Ada solusi dengan menangkap klik
document.body
dan kemudian memeriksa target acara.document.body.addEventListener( 'click', function ( event ) { if( event.srcElement.id == 'btnSubmit' ) { someFunc(); }; } );
sumber
Anda harus melampirkan acara setelah menyisipkan elemen, seperti itu Anda tidak melampirkan acara global pada Anda
document
tetapi acara tertentu pada elemen yang disisipkan.misalnya
document.getElementById('form').addEventListener('submit', function(e) { e.preventDefault(); var name = document.getElementById('txtName').value; var idElement = 'btnPrepend'; var html = ` <ul> <li>${name}</li> </ul> <input type="button" value="prepend" id="${idElement}" /> `; /* Insert the html into your DOM */ insertHTML('form', html); /* Add an event listener after insert html */ addEvent(idElement); }); const insertHTML = (tag = 'form', html, position = 'afterend', index = 0) => { document.getElementsByTagName(tag)[index].insertAdjacentHTML(position, html); } const addEvent = (id, event = 'click') => { document.getElementById(id).addEventListener(event, function() { insertHTML('ul', '<li>Prepending data</li>', 'afterbegin') }); }
<form id="form"> <div> <label for="txtName">Name</label> <input id="txtName" name="txtName" type="text" /> </div> <input type="submit" value="submit" /> </form>
sumber
javascript document.addEventListener('click',function(e){ if(e.target && e.target.id== 'brnPrepend'){ //do something } });
Perbedaannya terletak pada cara Anda membuat dan menambahkan elemen di DOM.
Jika Anda membuat elemen melalui
document.createElement
, tambahkan event listener, dan tambahkan ke DOM. Acara Anda akan aktif.Jika Anda membuat elemen sebagai string seperti ini: html + = "<li> test </li>" `, elemen secara teknis hanyalah string. String tidak boleh memiliki pemroses acara.
Salah satu solusinya adalah membuat setiap elemen dengan
document.createElement
dan kemudian menambahkannya ke elemen DOM secara langsung.// Sample let li = document.createElement('li') document.querySelector('ul').appendChild(li)
sumber
Anda dapat melakukan sesuatu yang mirip dengan ini:
// Get the parent to attatch the element into var parent = document.getElementsByTagName("ul")[0]; // Create element with random id var element = document.createElement("li"); element.id = "li-"+Math.floor(Math.random()*9999); // Add event listener element.addEventListener("click", EVENT_FN); // Add to parent parent.appendChild(element);
sumber
var __ = function(){ this.context = []; var self = this; this.selector = function( _elem, _sel ){ return _elem.querySelectorAll( _sel ); } this.on = function( _event, _element, _function ){ this.context = self.selector( document, _element ); document.addEventListener( _event, function(e){ var elem = e.target; while ( elem != null ) { if( "#"+elem.id == _element || self.isClass( elem, _element ) || self.elemEqal( elem ) ){ _function( e, elem ); } elem = elem.parentElement; } }, false ); }; this.isClass = function( _elem, _class ){ var names = _elem.className.trim().split(" "); for( this.it = 0; this.it < names.length; this.it++ ){ names[this.it] = "."+names[this.it]; } return names.indexOf( _class ) != -1 ? true : false; }; this.elemEqal = function( _elem ){ var flg = false; for( this.it = 0; this.it < this.context.length; this.it++ ){ if( this.context[this.it] === _elem && !flg ){ flg = true; } } return flg; }; } function _( _sel_string ){ var new_selc = new __( _sel_string ); return new_selc; }
Sekarang Anda dapat mendaftarkan acara seperti,
_( document ).on( "click", "#brnPrepend", function( _event, _element ){ console.log( _event ); console.log( _element ); // Todo });
Dukungan Browser
chrome - 4.0, Edge - 9.0, Firefox - 3.5 Safari - 3.2, Opera - 10.0 dan yang lebih baru
sumber
Saya telah membuat perpustakaan kecil untuk membantu ini: Sumber perpustakaan di GitHub
<script src="dynamicListener.min.js"></script> <script> // Any `li` or element with class `.myClass` will trigger the callback, // even elements created dynamically after the event listener was created. addDynamicEventListener(document.body, 'click', '.myClass, li', function (e) { console.log('Clicked', e.target.innerText); }); </script>
Fungsinya mirip dengan jQuery.on ().
Pustaka menggunakan metode Element.matches () untuk menguji elemen target terhadap selektor yang diberikan. Ketika sebuah peristiwa dipicu, callback hanya dipanggil jika elemen target cocok dengan selektor yang diberikan.
sumber
Saya tahu bahwa topiknya terlalu lama tetapi saya memberi diri saya beberapa menit untuk membuat kode yang sangat berguna yang berfungsi dengan baik dan sangat mudah menggunakan pure
JAVASCRIPT
. Berikut kode dengan contoh sederhana:String.prototype.addEventListener=function(eventHandler, functionToDo){ let selector=this; document.body.addEventListener(eventHandler, function(e){ e=(e||window.event); e.preventDefault(); const path=e.path; path.forEach(function(elem){ const selectorsArray=document.querySelectorAll(selector); selectorsArray.forEach(function(slt){ if(slt==elem){ if(typeof functionToDo=="function") functionToDo(el=slt, e=e); } }); }); }); } // And here is how we can use it actually ! "input[type='number']".addEventListener("click", function(element, e){ console.log( e ); // Console log the value of the current number input });
<input type="number" value="25"> <br> <input type="number" value="15"> <br><br> <button onclick="addDynamicInput()">Add a Dynamic Input</button> <script type="text/javascript"> function addDynamicInput(){ const inpt=document.createElement("input"); inpt.type="number"; inpt.value=Math.floor(Math.random()*30+1); document.body.prepend(inpt); } </script>
sumber
Saya telah membuat fungsi sederhana untuk ini.
The
_case
Fungsi memungkinkan Anda untuk tidak hanya mendapatkan target, tetapi juga mendapatkan elemen induk di mana Anda mengikat acara pada.Fungsi callback mengembalikan peristiwa yang menampung target (
evt.target
) dan elemen induk yang cocok dengan selector (this
). Di sini Anda dapat melakukan hal-hal yang Anda butuhkan setelah elemen diklik.Saya belum memutuskan mana yang lebih baik,
if-else
atau yangswitch
var _case = function(evt, selector, cb) { var _this = evt.target.closest(selector); if (_this && _this.nodeType) { cb.call(_this, evt); return true; } else { return false; } } document.getElementById('ifelse').addEventListener('click', function(evt) { if (_case(evt, '.parent1', function(evt) { console.log('1: ', this, evt.target); })) return false; if (_case(evt, '.parent2', function(evt) { console.log('2: ', this, evt.target); })) return false; console.log('ifelse: ', this); }) document.getElementById('switch').addEventListener('click', function(evt) { switch (true) { case _case(evt, '.parent3', function(evt) { console.log('3: ', this, evt.target); }): break; case _case(evt, '.parent4', function(evt) { console.log('4: ', this, evt.target); }): break; default: console.log('switch: ', this); break; } })
#ifelse { background: red; height: 100px; } #switch { background: yellow; height: 100px; }
<div id="ifelse"> <div class="parent1"> <div class="child1">Click me 1!</div> </div> <div class="parent2"> <div class="child2">Click me 2!</div> </div> </div> <div id="switch"> <div class="parent3"> <div class="child3">Click me 3!</div> </div> <div class="parent4"> <div class="child4">Click me 4!</div> </div> </div>
Semoga membantu!
sumber
Saya telah menemukan solusi yang diposting oleh jillykate bekerja, tetapi hanya jika elemen target adalah yang paling bersarang. Jika ini tidak terjadi, ini dapat diperbaiki dengan mengulangi orang tua, yaitu
function on_window_click(event) { let e = event.target; while (e !== null) { // --- Handle clicks here, e.g. --- if (e.getAttribute(`data-say_hello`)) { console.log("Hello, world!"); } e = e.parentElement; } } window.addEventListener("click", on_window_click);
Perhatikan juga bahwa kami dapat menangani acara dengan atribut apa pun, atau melampirkan pendengar kami di tingkat mana pun. Kode di atas menggunakan atribut khusus dan
window
. Saya ragu ada perbedaan pragmatis antara berbagai metode.sumber