13 votes

Le clic sur la gâchette de jQuery donne "trop de récurrence".

J'essaie de rendre le lien de l'article cliquable sur tout l'espace de l'article.

D'abord, j'ai fait le truc du survol, en changeant la couleur au passage de la souris et ainsi de suite... puis au clic, cela devrait déclencher le lien, mais cela donne un "too much recursion".

Je pense que c'est un event bubbling problème. J'ai essayé de travailler avec event.cancelBubble = true; o stopPropagation() sans succès. Pire que ça !

quelqu'un ?

    $("div.boxContent").each(function() {
        if ($(this).find(".btn").length) {

            var $fade = $(this).find("div.btn a > span.hover");
            var $title = $(this).find("h1, h2, h3, h4, h5");
            var $span = $(this).find("span").not("span.hover");
            var $text = $(this).find("p");

            var titleColor = $title.css('color');
            var spanColor = $span.css('color');

            $(this).css({'cursor':'pointer'}).bind({
                mouseenter:function() {
                    $text.stop().animate({color:linkHover},textAnim);
                    $title.stop().animate({color:linkHover},textAnim);
                    $span.stop().animate({color:linkHover},textAnim);
                    $fade.stop(true,true).fadeIn(textAnim);
                }, mouseleave:function() {
                    $text.stop().animate({color:linkColor},textAnim);
                    $title.stop().animate({color:titleColor},textAnim);
                    $span.stop().animate({color:spanColor},textAnim);
                    $fade.stop(true,true).fadeOut(textAnim);
                }, focusin:function() {
                    $text.stop().animate({color:linkHover},textAnim);
                    $title.stop().animate({color:linkHover},textAnim);
                    $span.stop().animate({color:linkHover},textAnim);
                    $fade.stop(true,true).fadeIn(textAnim);
                }, focusout:function() {
                    $text.stop().animate({color:linkColor},textAnim);
                    $title.stop().animate({color:titleColor},textAnim);
                    $span.stop().animate({color:spanColor},textAnim);
                    $fade.stop(true,true).fadeOut(textAnim);
                }
            }).click(function() {
                $(this).find("div.btn a").trigger('click');
            });
        }
    });

37voto

lonesomeday Points 95456

La partie problématique de votre code est la suivante :

$("div.boxContent") /* miss the each function */
.click(function() {
    $(this).find("div.btn a").trigger('click');
});

Cela signifie "chaque fois qu'un événement de clic est reçu sur cet élément, déclenche un clic sur l'élément descendant". Cependant, le bouillonnement d'événements signifie que l'événement déclenché dans cette fonction est ensuite traité à nouveau par ce gestionnaire d'événements, à l'infini . La meilleure façon d'empêcher cela est, je pense, de voir si l'événement a été créé sur le site Web de l'entreprise. div.btn a élément. Vous pouvez utiliser is y event.target pour ça :

$("div.boxContent") /* miss the each function */
.click(function(event) {
    if (!$(event.target).is('div.btn a')) {
        $(this).find("div.btn a").trigger('click');
    }
});

Cela dit "si le clic provient d'un élément autre qu'un div.btn a déclenche un événement de clic sur div.btn a . Cela signifie que les événements causés par le trigger ne sera pas traité par cette fonction. Ceci est supérieur à la vérification de event.target == this (comme La réponse d'Andy l'a ) parce qu'il peut faire face à d'autres éléments existant au sein de l'UE. div.boxContent .

-1voto

pachanka Points 381

Une façon plus propre de résoudre ce problème est de prendre l'élément sur lequel vous déclenchez le clic et de le placer en dehors de l'élément déclenché :

Donc si vous avez ça :

<div class="boxContent">

    <div class="btn">
        <a href="#">link</a> <!-- move this line... -->
    </div>
</div>
<!-- ... to here. -->

<script>
$("div.boxContent") /* miss the each function */
    .click(function() {
    $(this).find("div.btn a").trigger('click');
});
</script>

En déplaçant la balise "div.btn a" en dehors de la div "boxContent". Vous évitez la boucle de récursion tous ensemble.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X