Ich versuche, HTML-Daten dynamisch in eine Liste einzufügen, die dynamisch erstellt wird, aber wenn ich versuche, ein Onclick-Ereignis für die dynamisch erstellte Schaltfläche anzuhängen, wird das Ereignis nicht ausgelöst. Lösung wäre sehr dankbar.
Javascript-Code:
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);
});
});
HTML Quelltext:
<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
quelle
quelle
Antworten:
Dies liegt daran, dass Ihr Element dynamisch erstellt wird. Sie sollten die Ereignisdelegierung verwenden , um das Ereignis zu behandeln.
document.addEventListener('click',function(e){ if(e.target && e.target.id== 'brnPrepend'){ //do something } });
jquery macht es einfacher:
$(document).on('click','#btnPrepend',function(){//do something})
Hier ist ein Artikel über Event Delegation Ereignis Delegation Artikel
quelle
Es gibt eine Problemumgehung, indem Sie Klicks erfassen
document.body
und dann das Ereignisziel überprüfen.document.body.addEventListener( 'click', function ( event ) { if( event.srcElement.id == 'btnSubmit' ) { someFunc(); }; } );
quelle
Sie müssen das Ereignis nach dem Einfügen von Elementen anhängen, sodass Sie kein globales Ereignis an Ihr,
document
sondern ein bestimmtes Ereignis an die eingefügten Elemente anhängen .z.B
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>
quelle
javascript document.addEventListener('click',function(e){ if(e.target && e.target.id== 'brnPrepend'){ //do something } });
Der Unterschied besteht darin, wie Sie Elemente im DOM erstellen und anhängen.
Wenn Sie ein Element über erstellen
document.createElement
, fügen Sie einen Ereignis-Listener hinzu und hängen Sie ihn an das DOM an. Ihre Ereignisse werden ausgelöst.Wenn Sie ein Element als Zeichenfolge wie folgt erstellen: html + = "<li> test </ li>" `, ist das Element technisch nur eine Zeichenfolge. Strings können keine Ereignis-Listener haben.
Eine Lösung besteht darin, jedes Element mit zu erstellen
document.createElement
und diese dann direkt einem DOM-Element hinzuzufügen.// Sample let li = document.createElement('li') document.querySelector('ul').appendChild(li)
quelle
Sie können etwas Ähnliches tun:
// 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);
quelle
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; }
Jetzt können Sie Ereignisse wie registrieren,
_( document ).on( "click", "#brnPrepend", function( _event, _element ){ console.log( _event ); console.log( _element ); // Todo });
Browser-Unterstützung
Chrome - 4.0, Edge - 9.0, Firefox - 3.5 Safari - 3.2, Opera - 10.0 und höher
quelle
Ich habe eine kleine Bibliothek erstellt, um dies zu unterstützen: Bibliotheksquelle auf 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>
Die Funktionalität ähnelt jQuery.on ().
Die Bibliothek verwendet die Element.matches () -Methode, um das Zielelement anhand des angegebenen Selektors zu testen. Wenn ein Ereignis ausgelöst wird, wird der Rückruf nur aufgerufen, wenn das Zielelement mit dem angegebenen Selektor übereinstimmt.
quelle
Ich weiß, dass das Thema zu alt ist, aber ich habe mir einige Minuten Zeit genommen, um einen sehr nützlichen Code zu erstellen, der mit pure gut und sehr einfach funktioniert
JAVASCRIPT
. Hier ist der Code mit einem einfachen Beispiel: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>
quelle
Ich habe eine einfache Funktion dafür gemacht.
Mit dieser
_case
Funktion können Sie nicht nur das Ziel abrufen, sondern auch das übergeordnete Element, an das Sie das Ereignis binden.Die Rückruffunktion gibt das Ereignis zurück, das das Ziel (
evt.target
) und das übergeordnete Element enthält, die mit dem Selektor (this
) übereinstimmen . Hier können Sie die Dinge erledigen, die Sie benötigen, nachdem Sie auf das Element geklickt haben.Ich habe mich noch nicht entschieden, was besser ist, das
if-else
oder dasswitch
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>
Ich hoffe es hilft!
quelle
Ich habe festgestellt, dass die von jillykate veröffentlichte Lösung funktioniert, aber nur, wenn das Zielelement am meisten verschachtelt ist. Ist dies nicht der Fall, kann dies durch Iteration über die Eltern behoben werden, d. H.
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);
Beachten Sie auch, dass wir Ereignisse mit jedem Attribut behandeln oder unseren Listener auf jeder Ebene anhängen können. Der obige Code verwendet ein benutzerdefiniertes Attribut und
window
. Ich bezweifle, dass es einen pragmatischen Unterschied zwischen den verschiedenen Methoden gibt.quelle