Bonjour,

J'ai fait un bout de script pour afficher des popover un peu à la bootstrap et je peut les ouvrir de différents façon, au click, à l'hover, ou déjà ouvert quad on arrive !

Pour ajouter le bloc div qui me sert pour le popover, je fait un appendChild à l'élement parent et attribut à cet élement parents les différents évennement dont j'ai besoins entre autres pour l'ouverture au click un eventListener click sauf que mon popover est lui aussi sous le coup de cet évennement et je ne peut pas cliquer sur les liens et bouton à l'interieur !

Je souhaite donc essayer de trouver une solution pour stopper l'évennement sur cet enfant précisement !

...
function poperAdd(poper, el, pos, stateStart) {
    if(stateStart === 'open') {
        el.appendChild(poper)
        poperPosition(poper, el, pos)
    }
    else if(stateStart === 'onHover') {
        el.addEventListener('mouseover', function(e) {
            el.appendChild(poper)
            poperPosition(poper, el, pos)
        })

        el.addEventListener('mouseleave', function(e) {
            el.removeChild(poper)
        })
    }
    else if(stateStart === 'onClick') {
        el.addEventListener('click', function(e) {
            e.preventDefault()

            if(!el.contains(poper)) {
                el.appendChild(poper)
                poperPosition(poper, el, pos)
                // Supprimer l'évennement de click ici !
            }
            else { el.removeChild(poper) }
        }, true)
    }
}
...

Des idées ?

Merci par avance. :P !

6 réponses


Salut, une idée qui me vient en tête est d'utiliser "e.stopPropagation" sur tes éléments popover :

"Évite que l'évènement courant ne se propage plus loin dans les phases de capture et de déploiement."

Pour résumer, si sur ton popover tu utilises stopPropagation quand tu cliques, alors tes évènements parents ne seront pas appelés :)

Merci 3610gaga

Voilà ce que j'ai fait du coup

...
el.addEventListener('click', function(e) {
    e.preventDefault()
    e.stopPropagation()

    if(!el.contains(poper)) {
        el.appendChild(poper)
        poperPosition(poper, el, pos)
    }
    else {
        el.removeChild(poper)
    }
}, true)
...

Sauf que mon popover continue de s'enlever quand je clique dessus !

Précision

Le popover se contruit ainsi au final

<a href="">
    Contenu du lien
    <div></div><!-- POPOVER -->
</a>

Est-ce une bonne idée ou vaut-il mieux faire :

<body>
    <a href="">Contenu du lien</a>
    <div></div><!-- POPOVER -->
</body>

Une "div" dans un "a" O_o..?? Houlà! Mauvais design spotted!.. A moins de savoir exactement ce que tu es en train de faire :-s

Pourquoi est-ce que tu construis ton noeud en js plutôt que de l'intégrer directement à ton html? Tu sais que tu peux le cacher via css? Et ainsi, pour qu'il s'affiche il suffit de modifier la classe css...

Yop.

Il faut effectivement stopper la propagation, ceci étant dit, tu appliques ce comportement sur le mauvais élément, qui est (el: <a>) or, il aurait fallu l'appliquer sur l'élément (poper: <div>); donc créer un événement click sur poper qui lui stop véritablement la propagation.

Maintenant pour répondre à ton questionnement sur la construction de la popover, bien que les deux structures soient valides a>div / a+div, il vaut mieux privilégier la deuxième option, car le contenu de la popover pourrait, elle, rendre invalide a>div.

Par exemple, si ta popover peut contenir comme contenu, des éléments intéractifs (contenu intéractif), style des hyperliens, des boutons html et bien la deuxième option serait plus appropriée, car elle rendrait la première option invalide.

Exemple 1: a>div (valide)

<a href="#">
  Ouvrir la popover
  <div class="popover"> 
    <p>Ceci est valide :-)</p>
    <span>Ceci est valide :-)</span>
  </div>
</a>

Exemple 2: a>div (invalide)

<a href="#">
  Ouvrir la popover
  <div class="popover">
    <a href="#">Ceci est invalide :-(</a>
    <button>Ceci est invalide :-(</button>
  </div>
</a>

Exemple 3: a+div (sera toujours valide)

<a href="#">Ouvrir la popover</a>
<div class="popover">
  <a href="#">Ceci est valide :-)</a>
  <button>Ceci est valide :-)</button>
  <p>Ceci est valide :-)</p>
  <span>Ceci est valide :-)</span>
</div>

À savoir que si tu choisis la deuxième optiona+div, tu n'auras pas besoin de stopper la propagation sur ton élément popover.

Donc voilà voilà ^^

@Psylozoff je génère mon noeud en JS tout simplement pour réduire le DOM, ce qui est mieux en terme de référencement ! (D'après dareboost)

@PhiSyX j'ai juste un soucis dans le cas ou je créer a+div car j'ai des popover qui sont en onHover il faut donc que je puisse passer du lien ou élément au popover et inversement sans que celui ne se ferme !

Alors n'utilise pas des "a"! De toute façon, si tu n'as pas de href dans tes "a", je vois pas l'intérêt... Ensuite, je ne sais pas où tu as vu que les crawlers esquivaient le JS..! Le JS est évalué et le DOM construit dans sa version maximale avant évaluation de ta page! Donc, comme je te le disais : "aucun intérêt"! Et finalement, j'imagine, si tu es logique, que tu ne construis tes noeuds qu'une seule fois et qu'ensuite tu les caches..?? J'imagine qu'en faisant des recherches tu as constaté que le DOM est optimisé en lecture mais très lent en écriture...