Question

Je vais essayer de garder ce court. Je suis en train de créer des zones de texte qui masquer ou afficher lorsque l'utilisateur clique sur un bouton de développement. J'utilise la méthode bascule ().

Le balisage est comme ceci:

<span id="toggle0">+</span>
<div id="toggle0Container">
    blablabla...
<div>

<span id="toggle1">+</span>
<div id="toggle1Container">
    blablabla...
<div>

<span id="toggle2">+</span>
<div id="toggle2Container">
    blablabla...
<div>

// etc

Le # toggle0 est censé basculer le # toggle0Container, le # toggle1 le # toggle1Container permet de basculer et ainsi de suite. Tout cela est généré par PHP donc il peut y avoir un certain nombre de ces conteneurs.

Voici le code JQuery:

$(document).ready(function() {
    // array of numbers, it's pretty redundant, there will never be more than 30 containers
    var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9 , 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36];
    // hide all containers first
    jQuery.each(arr, function() {
        $('#toggle' + this + 'Container').hide();
    });
    // now the toggle buttons
    jQuery.each(arr, function() {
        $('#toggle' + this).click(function() {
            // this line is not working
            $('#toggle' + this + 'Container').slideToggle('slow');
            // and this just changes the toggle button from + to -
            if ($(this).html() == '+') {
                $(this).html('-');
            } else {
                $(this).html('+');
            }
        });
    });
});

Il fonctionne à l'exception de la partie de basculement (j'ai ajouté un commentaire au-dessus de la ligne qui ne fonctionne pas). Où est le problème?

Était-ce utile?

La solution

Je suivrais l'approche de mgroves mais si vous voulez vraiment faire la chose du tableau, ou tout simplement envie de comprendre comment utiliser each () correctement, voici comment vous devez l'utiliser:

$(document).ready(function() {
    // array of numbers, it's pretty redundant, there will never be more than 30 containers
    var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9 , 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36];
    // hide all containers first
    jQuery.each(arr, function(index, item) {
        $('#toggle' + item + 'Container').hide();
    });
    // now the toggle buttons
    jQuery.each(arr, function(index, item) {
        $('#toggle' + item).click(function() {
            // this line is not working
            $('#toggle' + item + 'Container').slideToggle('slow');
            // and this just changes the toggle button from + to -
            if ($(this).html() == '+') {
                $(this).html('-');
            } else {
                $(this).html('+');
            }
        });
    });
});

Autres conseils

Il est parce que « ce » est maintenant dans un cadre différent, et fait référence à l'élément #toggleN DOM réel, pas un des numéros dans le tableau.

Je vous suggère de fossé le tableau de nombres, et utiliser un sélecteur différent, quelque chose comme:


$("div[id^=toggle][id$=container]").hide();

$("span[id^=toggle]").click(function() {
     $(this).find("span[id^=toggle][id$=container]").slideToggle("slow");
     // .. do your other html stuff
}

Juste fossé ces eachs et remplacer sélecteurs à bascule avec ceux-ci.

EDIT

J'aime solution mgroves mieux pour votre cas d'utilisation particulière, mais je vais laisser ma réponse en ce qui explique comment vous pouvez accepter l'index et de l'élément en tant que paramètre sur la méthode .each

RÉPONSE ORIGINAL

Comme d'autres l'ont dit, le contexte de ce est pas ce que vous pensez qu'il est au point où vous référençant. Voici un article de Remy de Sharp intitulé « jQuery de ceci: démystifié » que je vous recommande de lire.

la fonction .each peut accepter deux paramètres qui va grandement vous aider et vous ne aurez pas besoin que tableau de nombres.

$('span[id^=toggle']').each(function(idx, elem) {

    // idx is the current index of the jQuery object
    $('#toggle' + idx).click(function() {

        // elem is the current element
        $(elem).next('#toggle' + idx + 'Container').slideToggle('slow');

        if ($(elem).html() == '+') {
            $(elem).html('-');
        } else {
            $(elem).html('+');
        }

    });

});

Je suggère de mettre une classe sur votre bouton à bascule (span) comme « toggler » et votre conteneur à bascule comme « contenant » ou quelque chose afin de simplifier votre javascript:

$(function() {
    // hide all containers first
    $(".container").hide();
    // now the toggle buttons
    $(".toggler").click(function() {
          var container = $("#" + $(this).attr("id") + "Container");
          container.slideToggle("slow");

          $(this).html(container.is(":visible") ? "-" : "+");
    });
});

Donnez un coup de feu.

Comme dit mgroves, votre champ devient tout mis sur cric en utilisant each (). Voir cette pour plus d'informations.

J'étais sur le point de poster exactement ce que Max a fait sur l'utilisation d'une classe. Je n'améliorer sa suggestion avec ce sélecteur plus facile de trouver le conteneur:

$(function() {
  // hide all containers first
  $(".container").hide();
  // now the toggle buttons
  $(".toggler").click(function() {
    $(this).next().slideToggle("slow");

    if (container.is(":visible")) {
      $(this).html("-");
    }
    else {
      $(this).html("+");
    }
  });
});

Si vous ne pouvez pas obtenir facilement les classes sur les portées, vous pouvez probablement construire un sélecteur similaire en utilisant quelque chose comme $ ( '# SpanContainer> durée) pour les sélectionner par nom de la balise, descendant de leur élément contenant.

Vous devez donner vos éléments une classe qui peut être recherché sur, puis utiliser next.

Faites votre quelque chose comme markup ceci:

<span class="toggleButton">+</span>
<div class="toggleContainer">
   blablabla...
<div>

Maintenant, votre code pour gérer cela devient aussi simple que cela:

$('.toggleButton').click(function() {
    $(this).next('.toggleContainer').slideToggle('slow');
});

J'ai écrit récemment un script assez important pour le comportement comme ça. Je pris une route légèrement différente que j'ai choisi d'envelopper tous les éléments d'un élément disparaissant / spectacle donné dans un div contenant. Il vous permet d'avoir plusieurs « déclencheurs » pour une section si vous en avez besoin, et vous pouvez ajouter un nombre arbitraire d'éléments cacher / spectacle sans se soucier de leur numérotation. Je structurer quelque chose comme ceci:

<div class="expSecWrapper">
    <div class="expSecTrigger">Insert Trigger Here</div>
    <div class="expSecBody">
        Content to hide/show
    </div>
</div>

Et puis le code jQuery serait quelque chose comme ceci:

$(document).ready(function(){
    var targets = $(".expSecWrapper")
    targets.find(".expSecTrigger").click(function(){
        targets.find(".expSecBody").hide()
        $(this).parents(".expSecWrapper").eq(0).children(".expSecBody").toggle();
    })
})

Vous pouvez ajouter dans les JS pertinentes pour votre application restant.

Il a quelques limitations, comme la nécessité que le corps cacher / show est un descendant direct de l'emballage. Il peut être appliqué à listes déroulantes, boutons radio, peu importe. Il est également en mesure nid-de sorte que vous pouvez avoir plusieurs niveaux si cacher / montrer.

Une dernière chose est que vous avez réellement besoin même de ne pas utiliser la iterator .each pour attribuer ce comportement. Quelque chose comme .cliquez () attribue un comportement à un groupe entier d'objets jQuery. Tant que vous utilisez un sélecteur qui saisira toutes vos cibles.

Désolé, a dû modifier qu'une ou deux fois.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top