11521 sujets

JavaScript, DOM et API Web HTML5

Bonsoir
En faisant des modifications dans un site ancien je tombe sur le problème suivant:
- une fonction est appelée par "onclick=" dans une balise
- j’ai besoin de faire en sorte que l’événement ne "remonte" pas aux éléments parents
- la fonction stopPropagation nécessite, si j’ai bien compris, doit s’appliquer à un objet "event"
- je voudrais évier de devoir changer la façon dont l’événement est attribué à la balise par addEventListenerer(), ce qui nécessiterait de nombreuses modifications dans le code.
Y a-t-il une solution à ce problème ?

Merci de votre aide
Modifié par PapyJP (16 Sep 2018 - 14:02)
Ce n'est pas un problème au sens: "j'ai quelque chose qui ne marche pas et je ne sais pas pourquoi", c'est un problème au sens "comment faire?".
Supposons que j'ai un code HTML comme ceci:

<div onclick="fonction1(x)">
    <h2>.....</h2>
    <img src="..." onclick="fonction2(y)">
</div>

ce que je veux faire c'est, dans fonction2, dire de ne pas "remonter" l'évènement au niveau <div> de façon à ne pas exécuter fonction1(x).
Pour cela il faudrait que dans fonction2 il y ait une commande event.stopPropagation()
Mais pour cela il faut que fonction2 ait un objet "event" disponible.
Une façon de faire serait que au lieu de
<img src="..." onclick="fonction2(y)">

on ait quelque chose comme
<img id="image123" src="..." data-truc="Y">

et ailleurs un code javascript
qui
1) définisse une fonction qui traite l'évènement "click" sur l'image, en prenant le paramètre Y dans l'attribut data-truc
2) déclare que cet évènement ne remonte pas par event.stopPropagation()

Beaucoup de travail pour peu de choses, en fait ça veut dire reprendre toutes ces anciennes pages et les refaire.
L'utilisation de onclick est à éviter. Il vaut utiliser un écouteur d'événement (addEventListener)
<div class="fonction1">
    <h2>.....</h2>
    <img src="..." class="fonction2">
</div>
<script type="text/javascript">
const imgs = document.querySelectorAll('img.fonction2');
for(var i=0, iMax=imgs.length; i<iMax; i++) {
  imgs[i].addEventListener('click', function(event) {
    alert("T'as cliqué sur sur la balise " + event.target.tagName);
    event.preventDefault(); // évite que l'évènement ne se propage aux parents
  });
}
const divs = document.querySelectorAll('div.fonction1');
for(var i=0, iMax=divs.length; i<iMax; i++) {
  divs[i].addEventListener('click', function(event) {
    alert("T'es dans la balise "+ event.target.tagName);
    event.preventDefault(); // évite que l'évènement ne se propage aux parents
  });
}
</script>

Modifié par bazooka07 (16 Sep 2018 - 19:53)
Désolé, quand ces pages ont été écrites, au début des années 2000, les eventListeners n’existaient pas. Et du reste ça ne fait pas longtemps que IE les supporte de la même façon que les autres navigateurs.
Comme je l’ai dit plus haut, je voudrais éviter de réécrire toutes ces pages.
Sinon, bien entendu, j’utilise cette technique assez souvent, bien qu’elle soit à mon avis souvent inutilement lourde, mais c’est un autre sujet dont nous pourrons débattre une autre fois
Est ce du javascript où du jquery qui est utilisé ? jquery est-il "utilisable" pour développer ta solution ?
Js ou jQuery, c’est du pareil au même. Après quelques mois j’ai cessé d’utiliser jQuery car il aurait fallu là aussi que je reprenne tout le code js de mes pages. Par ailleurs je n’ai rien trouvé qu’on sache faire en jQuery et qu’on ne sache pas faire en js, du moins avec les navigateurs d’aujourd’hui.
J’ai fini par faire une solution batarde qui combine onclick pour la balise enveloppante et un eventListener pour la balise interne, car il se trouve que dans ce cas précis c’était faisable, mais il faudra que je réinvente une solution la prochaine fois.
J’esperais qu’il y avait un moyen que je ne connaisse pas pour retrouver l’événement déclencheur dans une fonction appelée par onclick, mais il semble bien que ça ne soit pas le cas.
Modérateur
Bonjour, à ma connaissance il faut utiliser l'event ou le passer en paramètre:


<img src="..." onclick="fonction2(event, y)">
<img src="..." onclick="event.stopPropagation();fonction2(y)">
Meilleure solution
PapyJP a écrit :
Par ailleurs je n’ai rien trouvé qu’on sache faire en jQuery et qu’on ne sache pas faire en js, du moins avec les navigateurs d’aujourd’hui.


Absolument d'accord. Mais faire un truc en 2 lignes au lieux de 20 je préfère.
kustolovic a écrit :
Bonjour, à ma connaissance il faut utiliser l'event ou le passer en paramètre:


<img src="..." onclick="fonction2(event, y)">
<img src="..." onclick="event.stopPropagation();fonction2(y)">

Bien entendu!
J'avais vaguement l'impression que ça existait, mais impossible de me rappeler comment ça marche.
Merci une fois de plus pour ton aide!
Modifié par PapyJP (18 Sep 2018 - 17:35)
JENCAL a écrit :
Absolument d'accord. Mais faire un truc en 2 lignes au lieux de 20 je préfère.

Je deviens (très) vieux, j'ai mes habitudes... et aussi mon propre sac à outils sous la forme d'un fichier js que je traîne avec moi depuis des années (bien avant la naissance de jQuery) et qui contient les fonctions qui me permettent de faire ce genre de choses en quelques lignes. Il contient par exemple des tas de choses qui datent du temps où il n'y avait à prendre en compte que IE et Netscape et fait en sorte de gommer les différences. Ne me demande pas comment ça marche, ça fait belle lurette que je n'ai pas mis mon nez dans ce fichier.
PapyJP a écrit :

Je deviens (très) vieux, j'ai mes habitudes... et aussi mon propre sac à outils sous la forme d'un fichier js que je traîne avec moi depuis des années (bien avant la naissance de jQuery) et qui contient les fonctions qui me permettent de faire ce genre de choses en quelques lignes. Il contient par exemple des tas de choses qui datent du temps où il n'y avait à prendre en compte que IE et Netscape et fait en sorte de gommer les différences. Ne me demande pas comment ça marche, ça fait belle lurette que je n'ai pas mis mon nez dans ce fichier.


haha pratique !
JENCAL a écrit :
haha pratique !

Ça fait plus de 50 ans que j'écris des programmes dans une foultitude de langages.
Quand on a galéré sur un algorithme pendant des jours, on a tendance à le conserver dans des archives. Je ne compte plus le nombre de fois où j'ai repris un algorithme et je l'ai converti en un autre langage. Bien évidemment, des années plus tard, on a oublié l'algorithme, et même le langage, mais si on a un code "bien écrit", on arrive à retrouver le fil.
Bon, cessons de radoter !