J'essaie d'insérer des données html dynamiquement dans une liste créée dynamiquement, mais lorsque j'essaie de joindre un événement onclick pour le bouton qui est créé dynamiquement, l'événement ne se déclenche pas. La solution serait vraiment appréciée.
Code 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);
});
});
Code 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
la source
la source
Réponses:
Cela est dû au fait que votre élément est créé dynamiquement. Vous devez utiliser la délégation d'événements pour gérer l'événement.
document.addEventListener('click',function(e){ if(e.target && e.target.id== 'brnPrepend'){ //do something } });
jquery facilite les choses:
$(document).on('click','#btnPrepend',function(){//do something})
Voici un article sur l'article sur la délégation d' événements sur la délégation d' événements
la source
Il existe une solution de contournement en capturant les clics sur
document.body
puis en vérifiant la cible de l'événement.document.body.addEventListener( 'click', function ( event ) { if( event.srcElement.id == 'btnSubmit' ) { someFunc(); }; } );
la source
Vous devez attacher l'événement après avoir inséré des éléments, de sorte que vous n'attachez pas d'événement global à votre
document
mais un événement spécifique sur les éléments insérés.par exemple
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>
la source
javascript document.addEventListener('click',function(e){ if(e.target && e.target.id== 'brnPrepend'){ //do something } });
La différence réside dans la façon dont vous créez et ajoutez des éléments dans le DOM.
Si vous créez un élément via
document.createElement
, ajoutez un écouteur d'événement et ajoutez-le au DOM. Vos événements se déclencheront.Si vous créez un élément sous forme de chaîne comme celle-ci: html + = "<li> test </li>" `, l'élément n'est techniquement qu'une chaîne. Les chaînes ne peuvent pas avoir d'écouteurs d'événements.
Une solution consiste à créer chaque élément avec
document.createElement
, puis à les ajouter directement à un élément DOM.// Sample let li = document.createElement('li') document.querySelector('ul').appendChild(li)
la source
Vous pouvez faire quelque chose de similaire à ceci:
// 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);
la source
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; }
Maintenant, vous pouvez enregistrer un événement comme,
_( document ).on( "click", "#brnPrepend", function( _event, _element ){ console.log( _event ); console.log( _element ); // Todo });
Prise en charge du navigateur
chrome - 4.0, Edge - 9.0, Firefox - 3.5 Safari - 3.2, Opera - 10.0 et supérieur
la source
J'ai créé une petite bibliothèque pour vous aider: Source de la bibliothèque sur 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>
La fonctionnalité est similaire à jQuery.on ().
La bibliothèque utilise la méthode Element.matches () pour tester l'élément cible par rapport au sélecteur donné. Lorsqu'un événement est déclenché, le rappel n'est appelé que si l'élément cible correspond au sélecteur donné.
la source
Je sais que le sujet est trop ancien mais je me suis donné quelques minutes pour créer un code très utile qui fonctionne très bien et très facile à utiliser pure
JAVASCRIPT
. Voici le code avec un exemple simple: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>
la source
J'ai créé une fonction simple pour cela.
La
_case
fonction vous permet non seulement d'obtenir la cible, mais également d'obtenir l'élément parent sur lequel vous liez l'événement.La fonction de rappel retourne l'événement qui contient la cible (
evt.target
) et l'élément parent correspondant au sélecteur (this
). Ici, vous pouvez faire ce dont vous avez besoin après avoir cliqué sur l'élément.Je n'ai pas encore décidé lequel est le meilleur, le
if-else
ou leswitch
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>
J'espère que cela aide!
la source
J'ai trouvé la solution publiée par jillykate fonctionne, mais seulement si l'élément cible est le plus imbriqué. Si ce n'est pas le cas, cela peut être corrigé en itérant sur les parents, c'est-à-dire
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);
Notez également que nous pouvons gérer les événements par n'importe quel attribut, ou attacher notre auditeur à n'importe quel niveau. Le code ci-dessus utilise un attribut personnalisé et
window
. Je doute qu'il y ait une différence pragmatique entre les différentes méthodes.la source