11480 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Hier j'ai fais une MAJ de jQuery de la version 2.1.3 à la version 2.2.3... et j'ai bien galèré. Les problèmes se situaient essentiellement au niveau de l'utilisation des sélecteurs liés à la fonction .on(), pour la plupart des scripts... mais pas pour tous...

Exemple de sélection inutilisable avec la version 2.2.3 (et déjà depuis la version 2.2.0 en fait) :
$(document).on('click', '[id^="cmd-tab-"]', function() {


L'une de mes solution de remplacement, la suppression de la sélection du document courant quand c'est possible :
$('[id^="cmd-tab-"]').on('click', function() {


Ou pour certains autres de mes scripts, l'utilisation de .find() :
$(document).find('.cmd-print').on('click', function() {


Cependant certains scripts fonctionnent encore avec l'ancienne méthode :
$(document).on('focus', 'input, textarea', function() {


La feuille complète avec l'historique des modif's pour comprendre le contexte d'utilisation.

J'ai réglé mon problème donc, mais j'avoue que je n'y comprends pas grand chose. J'ai ouvert ce topic autant pour vous faire un partage de mes solutions que pour avoir un éventuel éclairage sur cette interrogation.

----------

PS : Un dernier point (qui ne me pose pas question) : les sélecteurs n'acceptent plus cette syntaxe :
'a[href*=#]:not([href=#])'

Il faut obligatoirement des guillemets sur la chaîne à vérifier :
'a[href*="#"]:not([href="#"])'

Modifié par Olivier C (01 May 2016 - 10:11)
Salut,

C'est une observation intéressante mais je n'arrive pas à trouver de référence officielle sur cette modification.
As-tu fais un test en délégant l'événement 'click' non pas sur 'document' mais sur un élément plus bas ? Par exemple le body ou bien un élément encore plus proche de l'élément selectionné :
$('body').on('click', '[id^="cmd-tab-"]', function() {}

C'est rare de recharger l'ensemble du document... et en plus tu gagnes en performance.
Je ne vois pas cependant pourquoi ça aurait changé depuis la version 2.2.0.

Plus étonnant encore, ton dysfonctionnement sur le $(document).find('.cmd-print') avec un sélecteur simple. D'ailleurs je ne vois pas l'intérêt de faire comme ça alors que $('.cmd-print') suffit (et est en plus plus performant). Si tu procèdes comme ce dernier exemple, retrouves-tu ton comportement normal ?
MatthieuR a écrit :
Je ne vois pas cependant pourquoi ça aurait changé depuis la version 2.2.0.

Depuis les versions 2.1.x en fait...

MatthieuR a écrit :
Plus étonnant encore, ton dysfonctionnement sur le $(document).find('.cmd-print') avec un sélecteur simple. D'ailleurs je ne vois pas l'intérêt de faire comme ça alors que $('.cmd-print') suffit (et est en plus plus performant). Si tu procèdes comme ce dernier exemple, retrouves-tu ton comportement normal ?

C'est essentiellement pour faire en sorte qu'un élément appelé après le chargement de la page, via Ajax, puisse fonctionner tout de même.
Administrateur
Bonjour,

yop pour celles et ceux qui ont connu, c'est la même différence que .live() et .click() par exemple (dépréciés il y a fort fort longtemps quelque part entre 1.6 et 1.9). Pour celles et ceux qui ont pas connu, non ça n'aidera pas Smiley langue

Dans un cas l'évènement ne concerne que les éléments existants au moment où le script s'exécute, dans l'autre cas l'élément peut apparaître après coup ou disparaître et réapparaître...
Felipe a écrit :
yop pour celles et ceux qui ont connu, c'est la même différence que .live() et .click() par exemple (dépréciés il y a fort fort longtemps quelque part entre 1.6 et 1.9).

Hem... et si on a connu la version 1.4.4, c'est grave ?
Olivier C a écrit :
C'est essentiellement pour faire en sorte qu'un élément appelé après le chargement de la page, via Ajax, puisse fonctionner tout de même.

Oui, je suis au courant... Smiley biggrin mais rencontres-tu le même souci en écrivant $('.class').on(); au lieu de $(document).find('.class').on(); ?
Je pense encore que déléguer un événement à un élément en l'attachant à 'document' reste une mauvaise idée et peut-être le souci vient de là. D'autant que c'est inutile et gourmand en perf, l'idéal est de déléguer la propagation à un élément le plus proche de l'élément sur lequel on souhaite attacher l'événement (au max sur le body).
Quant à la version de mise à jour, tu parles d'une mise à jour de la 2.1.3 à la 2.2.3 et tu écris que en fait le changement de comportement remonte à la 2.1.0... Ton code ne fonctionnait déjà plus avant ta mise à jour ?
Modifié par MatthieuR (01 May 2016 - 15:13)
Ou alors $(container).find('.class').on(); où container est le proche ancêtre de .class resté dans le DOM lors de ta requête AJAX, ça fonctionne ou pas ?
Comme je me suis planté !

Au final il semble que seul l'un de mes scripts (chargeant un attribut target="_blank" au clique de la souris) ait réellement souffert du changement de version. C'est ce premier bug qui m'a mal orienté, d'autant plus que mes modifications avec .find() fonctionnaient avec la v.2.1.3 et pas avec 2.2.3. Les autres scripts semblent avoir été affectés par la mauvaise syntaxe d'un script les précédant, le même que j'avais cité dans le post scriptum de mon premier message. Quand je pense au temps que j'ai passé dessus hier soir je P-E-T-E un boulon...

En tout les cas merci à vous, notamment à toi Matthieu. Je me pencherai aussi sur ces histoires de perf's, mais à priori, étant donné que je veux produire un code généraliste, je ne pense pas descendre en dessous de main, ce serait déjà ça.
Modifié par Olivier C (01 May 2016 - 19:39)