11540 sujets

JavaScript, DOM et API Web HTML5

Salut à tous,

J'ai une fonction jQuery qui injecte du code HTML dans mon document (à travers la fonction jQuery after()).
Et mon fichier javascript contient du code non intrusif censé exécuté une fonction sur un de ces éléments HTML (qui vient d'être injecté).

Et... ça ne fonctionne pas !!! Pourquoi? Est-ce normal? Existe-t-il une astuce? Comment faites-vous?

Exemple typique de code :
// Document is ready
$(document).ready(function() {
	$('img#fermer-bloc-1').on('click', function() {
		console.log('test');
		alert('test');
	});
}); // end ready

$('.bloc-1').after('<img id="fermer-bloc-1" src="fermer.png" alt="Fermer" width="16" height="16">');

Edit: les fonctions console.log() et alert() ne seront JAMAIS exécutées! Et ça m'embête...
Modifié par Alphonse (12 Jan 2015 - 15:27)
Tu peux être plus précis stp?

Edit: Petite explication, j'injecte du code HTML (= image "fermer.png") et ensuite j'ai du javascript non intrusif qui est exécuté si on clique sur l'image "fermer.png".
Modifié par Alphonse (12 Jan 2015 - 15:46)
Modérateur
Salut,

La doc JQuery de .on() a écrit :

Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on().

To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page.

If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.
Lien : http://api.jquery.com/on/

Je pense que ca viens de là. Du fait que ton élément n'est pas sur ta page quand tu tente de poser le .on()... Je pense que le .click() de JQuery n'a pas le même comportement... et c'est fait pour ça Smiley cligne

De plus, ton rajout d'élément se fait un peu à l'arrache, il devrait se faire aussi dans un $(document).ready non ?

// Document is ready
$(document).ready(function() {
	$('.bloc-1').after('<img id="fermer-bloc-1" src="fermer.png" alt="Fermer" width="16" height="16">');
	$('img#fermer-bloc-1').click(function() {
		console.log('test');
		alert('test');
	});
}); // end ready


Tiens nous au jus Smiley murf
_laurent a écrit :
If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page

Super, ça fonctionne! Bien vu le lien de la doc !! Smiley cligne

_laurent a écrit :
Or, use delegated events to attach an event handler, as described next.

Heu... j'ai essayé mais ça ne fonctionne pas... je n'ai peut-être pas bien compris la marche à suivre... Si quelqu'un a plus d'information, je suis preneur!

_laurent a écrit :
Je pense que ca viens de là. Du fait que ton élément n'est pas sur ta page quand tu tente de poser le .on()... Je pense que le .click() de JQuery n'a pas le même comportement... et c'est fait pour ça

La solution du click() n'est pas mentionnée dans la documentation jQuery, et cette "solution" ne fonctionne pas! (mais ça ne m'étonne pas) Smiley ohwell
Modérateur
Alphonse a écrit :

Heu... j'ai essayé mais ça ne fonctionne pas... je n'ai peut-être pas bien compris la marche à suivre... Si quelqu'un a plus d'information, je suis preneur!

Bonjour, alors c'est relativement simple. Le principe: Imaginons que nous avons une table intitulée «my-table», dans chaque ligne de cette table on a un bouton avec la classe «bt-remove» pour retirer la ligne. D'autres lignes peuvent être ajoutée dynamiquement. On écrira donc:

$('#my-table').on('click', '.bt-remove', function(){
  // suprrimer la ligne
});

Pour définir cet appel il faut que #my-table existe au moment où ce script est exécuté. Il va intercepter les click sur la table, mais les filtrer pour n’exécuter la fonction que si on a clické sur un élément avec la classe «bt-remove», ces éléments peuvent donc ne pas exister au moment où le code ci-dessus est appelé.

C'est très pratique dans ce genre de cas, pour éviter de devoir ré-attacher un nouvel évènement à chaque fois qu'on ajoute un élément dans la page.

L'autre raison est d'optimiser les performances et éviter d'attacher 200 écouteurs d'évènements lorsqu'on peut n'en attacher qu'un. Attention toutefois avec les évènements délégués et les évènements très consommateurs (scroll, mouvements de souris, etc.)
Modérateur
Alphonse a écrit :

La solution du click() n'est pas mentionnée dans la documentation jQuery, et cette &quot;solution&quot; ne fonctionne pas! (mais ça ne m'étonne pas) Smiley ohwell


click(handler) == on('click', handler)

click est juste un raccourci. Toutefois il ne permet pas d'utiliser les évènement délégués => on('click', filter, handler)
Pour la fonction déléguée, j'avais mis ceci mais sans succès...
$('document').on('click', 'img#fermer-bloc-1', function() {
	alert('test');
});

kustolovic a écrit :
L'autre raison est d'optimiser les performances et éviter d'attacher 200 écouteurs d'évènements lorsqu'on peut n'en attacher qu'un.

En effet, j'avais lu pareil dans la doc du coup, j'ai utilisé l'évènement one() (à place de on()) directement après avoir injecté mon code HTML (mais si j'ai bien compris la doc, ça ne change rien, il y aura toujours autant d'écouteurs que de lignes)
$('img#fermer-bloc-1').one('click', function() {
	alert('test');
});
Alphonse a écrit :
Pour la fonction déléguée, j'avais mis ceci mais sans succès...
Bonjour.
$('document').on('click', 'img#fermer-bloc-1', function() {
	alert('test');
});

Il doit juste avoir les quote en trop dans $('document'), mais sinon ça devrait fonctionner.

Alphonse a écrit :
En effet, j'avais lu pareil dans la doc du coup, j'ai utilisé l'évènement one() (à place de on()) directement après avoir injecté mon code HTML (mais si j'ai bien compris la doc, ça ne change rien, il y aura toujours autant d'écouteurs que de lignes)
$('img#fermer-bloc-1').one('click', function() {
	alert('test');
});

L'événement one() est identique à on() à ceci près, que ton événement ne se déclenchera qu'une fois. Après un clic sur sur ton image, le 'clic' d'après ne fera plus rien !
Hello !
SolidSnake a écrit :
Il doit juste avoir les quote en trop dans $('document'), mais sinon ça devrait fonctionner.

Bien vu ! Smiley biggrin Je te confirme que ça fonctionne Smiley cligne