IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Récupération d'un événement sur un élément de DOM ciblé par un lien activé (en css *:target)


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Par défaut Récupération d'un événement sur un élément de DOM ciblé par un lien activé (en css *:target)
    Bonjour,

    Loin d'être totalement totalement un bleu (peut être 10 000 à 50 00 lignes de code, on ne sait plus petits bout par petits bouts...) donc pas vraiment un expert et je sèche (une journée de test et de recherche) sur le problème suivant :

    Un lien interne cible un élément d'un document, on doit exécuter une fonction javascript quand le lien est activé. C'est tout.
    Quel événement peut être récupéré sur l'objet de façon à le traiter avec JQuery par une instruction de la forme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $("#monelement"). ? (function () {....}) /* ou */
    $("#monelement"). on(" ?", (function () {....})
    Je n'ai jamais eu à traiter ce sujet. C'est probablement enfantin ou nécessite un astuce, ceci étant la question posée il y a 48h sur le site JQ n'a donné aucun résultat significatif. (les événements suggérés : "hashChange or popState or pathChange" ne sont pas dans le contexte).

    Je viens de faire à nouveau une revue avant de lancer le sujet, il y aurait peut-être à gratter, en l'absence d'un événement "targeted" qui serait si pratique vers "transitionend" en générant une transition fictive ou non, qui, utilisant le moteur CSS générerait en cascade un événement récupérable (set event trigger on) par JS-JQ. Mais que c'est tordu.


    Merci de votre aide.

    Cordialement

    Trebly



    Commentaires :

    1- en css si l'élément est id="monelement"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <style>
    #monelement:target { properties } changera les propriétés de l’élément sans aucune difficulté, effets, transitions, etc.
    </style>
    fonctionne sur tout selecteur

    2- Le navigateur riche de l'événement va positionner l'élément en haut de fenêtre (pose problème si le haut est occupé par un élément fixe de taille variable i.e. menu)

    3- En JS je n'ai pas trouvé d'événement. Ainsi avec JQuery $("#monelement"). ? (function () {....} le "?" ( ou bien .on(" ?", function... ) reste un mystère.

    Rien ne semble permettre d'exécuter une fonction JS sur l'élément cible d'un lien et je n'ai pas réussi à trouver le moindre exemple même voisin.

    Evidemment $("document").[scroll || focus]( function() { $("#monelement:target").each( function .... ) } "excitera" le système de manière quasi permanente (innacceptable) en récupérant des conséquences générant un événement sur le reste du document, puis avec un filtre etc.

    4- Le sujet global est la navigation dans un document à l'aide d'un sommaire, mais chaque fois que l'on cible un élément on doit exécuter plusieurs opérations de recadrage, positionnements relatifs d'objets, mémorisation etc...

  2. #2
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Par défaut
    Par "lien interne ciblant un élément du DOM" j'imagine que tu veux dire que ton lien est une ancre, commençant par # donc.

    L'activation de ces liens va changer le hash dans l'URL, et ça peut être intercepté via l'évènement hashchange sur window :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    window.addEventListener("hashchange", function(){
        if(window.location.hash === "#monelement"){
           // ton code ici
        }
    });
    C'est exactement ce que fait :target en CSS :
    La pseudo-classe CSS :target représente l'élément unique, s'il existe, avec un id correspondant au fragment dans l'URI du document.

  3. #3
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2013
    Messages : 119
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    $(document).on( "click", "a", function(event) {
    console.log("document")
      var  objcbl = $( window.location.hash ).selector;//ancien hash;
      var thishref=$(this).attr("href")//nouveau(actuel) hash
      //comparer 
      console.log(objcbl)
      console.log(thishref);
     
     
    });
     
    $(window).on( "hashchange", function(event) {
      var  objcbl = $( window.location.hash ).selector;//nouveau(actuel) hash
        console.log("hashchange")
        console.log(objcbl )
    });

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Par défaut On avance sur ce sujet de la gestion du hashchange, qui n'est pas si simple finalement
    Bonjour,

    Merci des réponses.

    J'avais lancé une discussion sur le site JQuery qui m' donné des réactions.

    Vos réponses fournissent la piste, dans la pratique il y a plusieurs problèmes rencontrés à la mise en oeuvre.

    Je rapporte et rapporterai ici les avancées et ce qui tourne autour de la question et sa mise en oeuvre.

    Par exemple :
    • il existe une fonction JQMobile .hashchange mais pas dans JQ API principale (donc solution .on( event, target, handler))
    • un doublon dans la création de plugins WordPress (ou autre) fait que l'événement échappe
    • l'exécution interne du navigateur ayant le même événement origine semble pouvoir prendre place avant ou après
    • etc...


    Je teste avec toutes ces pistes pour lever les lièvres, sur un terrain que je connais encore assez mal.

    Cordialement

    Trebly

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Par défaut href= définit un fragment mais le hash récupéré est réencodé....
    Bonsoir,

    Suite des problèmes de mise en oeuvre.

    Lors du debug de mon traitement des hash je tombe sur le problème suivant :

    Les valeurs renvoyées par window.location.hash sont "réencodées" par rapport au href (ce qui n'a pas lieu d'être sauf non ascii) et je ne trouve pas pourquoi :

    - contexte : dans Wordpress actuellement les liens href sont assurés par défaut par les identifiants automatiques basés (encodés pour éviter les réencodages) sur les titres d'articles , ainsi le titre d'un article est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {Les règles font elles l’”esprit de”, ou l’”esprit de” fabrique-t-il des règles qui lui correspondent<br><small>encore une histoire d’oeuf et de poule</small>[L] }
    (note : Les titres acceptent certains tags html affectant les polices et mise en forme simples)

    Cela va donner un href =
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #tocid-les-rgles-font-elles-l8221esprit-de8221-ou-l8221esprit-de8221-fabrique-t-il-des-rgles-qui-lui-correspondentencore-une-histoire-d8217oeuf-et-de-poulel
    (note : "tocid-" est un sélecteur de hash ajouté au titre identifiant de l'article dans la base de données WP)

    il lui correspond le id de la cible généré par le plugin sans aucun encodage (normalement ascii pur).

    Le problème est que le hash qui s'affiche devient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #tocid-les-rgles-font-elles-l82178221esprit-de8221-ou-l82178221esprit-de8221-fabrique-t-il-des-rgles-qui-lui-correspondentencore-une-histoire-d8217oeuf-et-de-poulel
    J'y perds mon latin.

    L'encodage qui n'a pas lieu d'être, me semble-t-il, généré par ? le navigateur vient remplacer une fois sur deux 8221 (double apostrophe droite unicode : Unicode Character 'RIGHT DOUBLE QUOTATION MARK' (U+201D) en (82178221 : Unicode Character 'RIGHT DOUBLE QUOTATION MARK' (U+201D) + Unicode Character 'RIGHT SINGLE QUOTATION MARK' (U+2019))
    qui se trouvent dans le titre étendu d'origine... mais n'a rien à voir.
    Je ne vois pas en quoi l'URI peut être modifiée parce qu'elle contient des valeur numériques unicode valides ?

    Ou est la bidouille. Evidemment l'encodage ascii du titre a viré les cascades de "quotation mark", mais comment ressortent-elles dans le hash ?.

    Avec des coup comme ça, je risque des bugs...

    Si vous avez une idée ?

    Pour l'instant, mon jeu test a fait planter le système, comment ? Sans avoir de réponse, sans savoir pourquoi, j'ai le risque d'autres bizarreries.

    Cordialement

    Trebly

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 145
    Par défaut Une seule solution pour le transcodage entre href et le hash pour gérer : identifiant unique en ascii
    Bonjour,


    25/04/2015, 02h49 #2
    SylvainPV
    a tout à fait raison. Ce qui fournit la base de la solution.
    Le onhashchange $(window).hashchange( function() {}) permet d'effectuer les traitement d'événement utiles.

    Cependant pour traiter correctement le problème global que j'avais, il faut pouvoir analyser le hash et le rapprocher des href et ainsi pouvoir établir une relation d'identité d'objet (élément de texte) à l'origine du hash et du href.

    J'ai retrouvé exactement le même problème pour traiter en callback un contenu de buffer (OB) et changer des identifiants et des href.

    Le problème se rencontre par exemple avec WordPress quand des titres d'article avec notamment des caractères accentués sont utilisés presque comme tels comme identifiants d'éléments notamment dans des plugins (simple remplacement des blancs par "_" en HTML5).

    Je n'ai trouvé aucune solution simple sur table pour convertir dans tous les cas l'un en l'autre (dans un sens, l'un ou l'autre) de manière fiable à cause des encodages totaux ou partiels faits en dehors de mon contrôle. En un mot les transformations ne sont pas réversibles si l'on n'en connait pas le process (à la fois HTML, encodage internes caractères, et données UTF8). Tout ceci malgré la richesse de fonctions.

    Finalement, j'ai adopté la solution d'une fonction qui permet de générer à partir d'une source quelconque issue d'un même texte original un identifiant unique qui permet d'effectuer la comparaison.

    A partir d'un contenu de buffer ou d'une url :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            function collapse_all_no_achars ( $string, $type='none') {
                // $type for future usage
                $pat=array('/\.\.\./','/\\x0D\\x0A/','/\&.+?;/','/[^a-zA-Z0-9]/'); // ellip is the lonely n chars -> one entity allowed
                $repl= array('x','x','x','x');
                return preg_replace($pat,$repl,$string);
            }
    Du coté de la source texte en php tous les caractères [^a-zA-Z0-9] sont convertis en un caractère par défaut "x" puis en minuscules. Ce qui fournit le même résultat pour un titre ou tout élément de texte que la fonction appliquée à ses conversions.

    Un test de doublon (y compris par concordance) ajoute à la chaîne créée une chaine [0-9] de x caractères aléatoires lors de substitutions (cas d'identifiants courts multiples : i.e. générer un id de fragment unique pour le titre "Résumé" ).

    Dans la cas de contenus longs la recherche peut s'avérer pénaliser le temps de traitement, la solution a donc été de n'utiliser dans toute l'application que des noms répondant à la spécification.

    Ainsi il n'y a pas eu de cas ou un titre récupéré par exemple dans une sélection (getSelection()) ne puise être retrouvé dans une url (retrouver le lien correspondant à un titre copié par exemple).

    Il a donc été nécessaire d'appliquer une restriction draconienne à la règle de l'identifiant id d'élément en HTML5.
    La règle de l'unicité devant pouvoir s'étendre en l’occurrence à toutes les formes d'encodage et dans tous les langages que peut prendre le id pouvant faire l'objet de comparaison et de recherche.


    Merci,
    Cordialement

    Trebly

Discussions similaires

  1. Réponses: 3
    Dernier message: 21/07/2011, 00h32
  2. Event/Listener sur un élément du DOM SVG d'une balise <object>
    Par Jarode01 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 14/07/2011, 13h52
  3. Réponses: 3
    Dernier message: 06/05/2010, 10h59
  4. Réponses: 0
    Dernier message: 02/07/2009, 17h00
  5. Réponses: 6
    Dernier message: 23/04/2007, 09h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo