11503 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous
Dans la page https://www.alma-musica.net/html/partitions/@index.php il y a une zone qui permet de retrouver une partition par son nom et/ou son nom d'auteur
Pour cela on fait en AJAX une recherche dans la base de donnée qui retourne les identifiants des œuvres correspondant à la recherche.
Par exemple si je cherche "bonjour", je trouve upload/1694854956-48769-recherche-bonjour.png
On voit que deux compositeurs ont écrit de la musique sur le même poème.
Je n'arrive pas à faire que si on clique sur une de ces deux lignes la page scrolle pour mettre les informations correspondantes en haut de la page.

Le design : les informations correspondant à une œuvre sont dans une balise

<div class="progitem" id="deCastro/BonjourMonCoeur">
...
</div>

La valeur de id est celle de l'identifiant unique de chaque œuvre
Le code

class SearchItem {
.....
    scrollTo(event) {
		event.stopPropagation();
		...
		this.itemNode.scrollIntoView();
	}
...

J'ai vérifié que this.itemNode est bien la <div> qui convient, mais this.itemNode.scrollIntoView(); ne produit aucun effet.
Cela fait très longtemps que je n'avais pas utilisé de fonction scrollTo ou scrollIntoView, je ne me souviens plus comment ça marche.

Auriez vous une idée de cette erreur, et surtout une solution à me proposer ?

Merci de votre aide,
Administrateur
Bonjour,

je n'arrive pas à sélectionner l'élément avec son id comportant un slash via document.querySelector(All)
D'après SO, il faut l'échapper avec \\ ou plus simple utiliser document.getElementById()

L'id est <div id="deCastro/BonjourMonCoeur">
Dans la console de Firefox, je peux sélectionner puis scroller via :

document.querySelector('#deCastro\\/BonjourMonCoeur').scrollIntoView()
// ou
document.getElementById('deCastro/BonjourMonCoeur').scrollIntoView()


avec les options de .scrollIntoView() pour ne pas forcément positionner la cible en haut
Quoique la placer au centre sans autre indication doit être assez perturbant, il faut encore la chercher des yeux...
Piste d'amélioration (enfin je crois, je suis assez rouillé ou plutôt c'est dew qui avait écrit cette partie-là quand j'en avais eu besoin, il y a 2 ans...) : pourquoi ne pas utiliser des liens vers une ancre <a href="#deCastro/BonjourMonCoeur"> et ça permettrait une petite animation CSS à l'arrivée pour bien montrer où on tombe, façon https://webdesignernotebook.com/examples/target.html#b1 ?
Modifié par Felipe (17 Sep 2023 - 20:46)
Bonsoir Felipe

Merci pour ces conseils.
Ce qui m’agace c’est de ne pas arriver à faire scroller la page.
J’avais constaté que href=#id marche, mais mettre la cible en haut de page n’est pas idéal pour l’utilisateur, j’ai essayé de faire un scrollTo une certaine distance au dessus de la cible, également sans succès.
Dans un autre contexte j’ai recopié la zone cible dans un cadre au dessous de la liste des œuvres, cadre qui disparaît quand on clique sur le lien. Je crois que je vais plutôt reprendre cette techno.
Il y avait une erreur importante dans le code : la cible de scrollIntoView() n'atait pas le bon nœud.
Après avoir corrigé cette erreur, je constate en pas à pas que le scrollIntoView() s'applique bien au bon nœud, que la page scrolle effectivement au bon endroit mais immédiatement après revient en haut.
En regardant de plus près, on voit que FireFox exécute ensuite un script dans "content_script.js" dont je ne comprends pas très bien la signification, mais qui se termine par le retour à l'affichage pleine page.
Pour en avoir le cœur net, j'ai essayé avec Chrome et j'ai le même résultat.
Il doit donc y avoir quelque chose d'autre qui ne tourne pas correctement dans mon code.

Je laisse https://www.alma-musica.net/html/partitions/@index.php en l'état au cas où quelqu'un aurait une idée de solution.
Je vais créer un autre environnement de tests pour utiliser une autre techno.
Modifié par PapyJP (18 Sep 2023 - 15:37)
Felipe a écrit :

D'après SO, il faut l'échapper avec \\ ou plus simple utiliser document.getElementById()

Dans les versions précédentes j'avais mis les id avec des "_" au lieu de "/", mais c'est inutile et induit des bugs de programmation.
J'utilise MA PROPRE VERSION de $(id) qui ne fait rien d'autre que getElementByID(id), mais c'est plus facile à écrire.
Pour l'histoire j'ai utilisé $() bien avant que jQuery ne me pique la syntaxe Smiley cligne
Modifié par PapyJP (18 Sep 2023 - 11:50)
Administrateur
Là actuellement c'est fonctionnel chez moi avec Firefox (et uBlockOrigin si jamais). Je saisis "Bonjour", valide et clique sur un des 2 résultats => Fx scrolle à l'endroit attendu et la console affiche la div cible.

Ca revient en haut avec vos 2 navigateurs ? Un seul j'aurais suspecté une extension ; 2 un .scrollTo(0) parce qu'une variable vaut 0 ou bien une ancre dont l'id n'existe pas et c'est #top le haut de page qui devient la cible, un truc comme ça. Mais chezmoiçamarche.
Merci Felipe
Je vais regarder à nouveau.
Si le même code fonctionne chez vous et pas chez moi c'est à tomber par terre ! Smiley cligne
Chez moi c'est louche le comportement de ta page Smiley ohwell :
- si je clique une fois je vois bien l'élément pop dans la console mais je bouge pas
- si je fais un double clique la par contre ça descend bien sur l'élément Smiley hum

Et j'ai une erreur si je cherche John : Error: TypeError: this.work is undefined
Merci pour m’avoir signalé l’erreur. Je crois l’avoir corrigé dans la version actuellement sur le site mais je vais vérifier
Je vais regarder cette histoire de double clic, c’est peut-être bien la clef du problème
La raison est que la zone d'affichage de la liste de choix a pour parentNode la balise <label> qui inclut la zone de saisie.
Le programme effectue effectivement le scroll, mais il exécute ensuite l'action par défaut d'un click sur un <label>, c'est à dire qu'il relance l'appel AJAX au serveur
Je pensais m'en tirer avec event.stopPropagation(); mais c'est insuffisant.
Avec

event.preventDefault();
event.stopPropagation();

le fonctionnement est OK

Merci pour m'avoir signalé que ça marchait si on faisait un double clic !
Smiley smile
Modifié par PapyJP (19 Sep 2023 - 17:03)