Pergunta

Vou tentar manter este curto. Eu estou tentando criar caixas de texto que como ocultar ou mostrar quando o usuário clica em um botão de expansão. Eu estou usando o método de alternância ().

A marcação é assim:

<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

O # toggle0 é suposto para alternar a # toggle0Container, o # toggle1 alterna o # toggle1Container e assim por diante. Isso tudo é gerado por PHP por isso não pode ser qualquer número desses recipientes.

Aqui está o código 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('+');
            }
        });
    });
});

Ele funciona com exceção da parte alternância (eu adicionei comentário acima da linha que não está funcionando). Onde está o problema?

Foi útil?

Solução

Gostaria de seguir a abordagem das mgroves mas se você realmente quer fazer a coisa matriz, ou apenas quer descobrir como usar cada () corretamente, aqui está como você deve usá-lo:

$(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('+');
            }
        });
    });
});

Outras dicas

É porque "este" está agora em um escopo diferente, e refere-se ao elemento real #toggleN DOM, não um dos números na matriz.

Eu sugiro que você vala a matriz de números, e usar um seletor diferente, algo como:


$("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
}

Apenas vala aqueles eachs e substituir alternar seletores com aqueles.

Editar

Eu como solução mgroves melhor para o seu caso de uso particular, mas vou deixar a minha resposta até que explica como você pode aceitar o índice e elemento como um parâmetro no método .each

RESPOSTA ORIGINAL

Como já foi dito, o contexto de este não é o que você pensa que é no ponto em que você está fazendo referência a ele. Aqui está um ótimo artigo por Remy afiada intitulado " jQuery é este: desmistificada " que eu recomendo que você leia.

a função .each pode aceitar dois parâmetros que irão ajudá-lo muito para fora e você não vai precisar essa matriz de números.

$('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('+');
        }

    });

});

Eu sugiro colocar uma classe no seu botão de alternância (span) como "toggler" e seu recipiente de alternância como "container" ou algo, a fim de simplificar o seu 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") ? "-" : "+");
    });
});

dar esse um tiro.

Como mgroves disse, o seu âmbito de aplicação é conseguir que todos levantado usando each (). Consulte este para obter mais informações.

Eu estava prestes a postar exatamente o que Max fez sobre o uso de uma classe. Eu só iria melhorar a sua sugestão com este selector mais fácil encontrar o recipiente:

$(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("+");
    }
  });
});

Se você não pode facilmente obter as aulas sobre os vãos, provavelmente você pode construir um seletor similar, usando algo como $ ( '# SpanContainer> intervalo') para selecioná-los pelo nome tag, descendo do seu elemento contendo.

Você deve dar aos seus elementos uma classe que pode ser pesquisado, então fazer uso de next.

Faça a sua marcação algo como isto:

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

Agora, o código para lidar com isso se torna tão simples como isto:

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

Eu escrevi recentemente um script bastante substancial para o comportamento assim. I tomou uma rota um pouco diferente em que eu escolhi para envolver todos os elementos de um determinado elemento hide / show em uma div que contém. Ele permite que você tenha vários "gatilhos" para uma seção se você precisar dele, e você pode adicionar um número arbitrário de hide / show elementos sem se preocupar com a numeração deles. Gostaria de estruturá-lo algo como isto:

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

E, em seguida, o código jQuery seria algo como isto:

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

Você pode adicionar nos restantes JS relevantes para a sua aplicação.

Ele tem algumas limitações, tais como a necessidade de que o corpo hide / show é um descendente direto da embalagem. Pode ser aplicado para menus suspensos, botões de rádio, qualquer que seja. Também é ninho capaz de modo que você pode ter vários níveis, se esconder / show.

Uma última coisa é que você realmente não precisa nem usar o .each iterador para atribuir esse comportamento. Algo como .click () irá atribuir um comportamento a todo um grupo de objetos jQuery. Contanto que você use um seletor que vai pegar todos os seus alvos.

Desculpe, tive que editar que um jovem vezes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top