Question

J'installe une page FAQ très simple avec jQuery. Comme ceci:

<h2>What happens when you click on this question?</h2>
<p>This answer will appear!</p>

Ceci est tout à l'intérieur d'un div très spécifique, donc je vais être à sélectionner l'en-tête avec $('#faq h2'). Simple, non? Cliquez sur le H2 et utiliser pour faire le this.next() prochain spectacle de paragraphe vers le haut.

(La mise en garde avec cette page est qu'un non-programmeur sera de maintenir, ce qui est la raison pour laquelle je ne suis pas en utilisant des classes. Il n'y a aucune garantie que les nouvelles entrées auraient les bonnes classes en eux)

Alors! Le problème:

<h2>What happens when you click on the next question?</h2>
<p>That is an interesting conundrum.</p>
<p>Because the maintainer is kind of long-winded</p>
<p>and many answers will span a few paragraphs.</p>

Alors, comment, sans ajouter à s et les classes div et tout le reste, je peux avoir ma routine tout <=> sélection entre la question qui a été-cliqué sur-et la question suivante (en-tête H2)?

Était-ce utile?

La solution

Problème intéressant. Tout d'abord permettez-moi de dire que je pense que la meilleure stratégie consiste à enfermer toute réponse dans un div et le problème trivial à résoudre devient:

<h2>Question here</h2>
<div>
<p>Answer here</p>
</div>
</h2>Next Question</h2>
...

avec:

$(function() {
  $("h2").click(function() {
    $(this).next().toggleClass("highlighted");
  });
});

Mais cela étant dit, il est résoluble sans cela.

$(function() {
  $("h2").click(function() {
    $(this).nextAll().each(function() {
      if (this.tagName == 'H2') {
        return false; // stop execution
      }
      $(this).toggleClass("highlighted");
    });
  });
});

Non, mais grande élégance que ça va marcher.

Remarque: Cela suppose que les questions sont frères et sœurs. Si elles ne sont pas il est beaucoup plus compliqué.

Autres conseils

Je me rends compte que c'est une question ancienne, mais jQuery 1.4 a maintenant nextUntil . Donc, quelque chose comme ça devrait fonctionner:

$('h2').click(function(){
    $(this).nextUntil('h2').show();
})

ne serait-il plus judicieux d'utiliser un style css Liste DL ?

<dl class="faq">
    <dt>Question?</dt>
    <dd>
         <p>Answer</p>
         <p>Answer</p>
         <p>Answer</p>
    </dd>
</dl>

Et puis une sélection facile en utilisant:

$('+ dd', this); 

étant le courant dt sélection.

Ou tout simplement envelopper chaque réponse dans une div, car il est logique sémantiquement aussi. Cependant, je pense une liste de DL fait beaucoup plus de sens sémantiquement.

Bien sûr! Il suffit de faire une boucle while.

$('h2').click(function() {
    var next = $(this).next();
    while (next.length != 0 && next[0].nodeName == 'P')
    {
        next.toggle();
        next = next.next();
    }
});

Cela suppose que vous avez uniquement les balises p après votre h2. Vous pouvez ajouter des exceptions à la boucle while si vous voulez ajouter quelque chose comme img.

Ou si vous ne vous souciez pas ce qui est entre les balises H2 vous pouvez vérifier pour ne pas égal à H2.

$('h2').click(function() {
    var next = $(this).next();
    while (next.length != 0 && next[0].nodeName != 'H2')
    {
        next.toggle();
        next = next.next();
    }
});

Cela permet de masquer tout ce qui suit le H2 qui est cliqué sur jusqu'à ce que soit le prochain H2 se trouve ou vous remonter d'un niveau dans le dom.

Peut-être que ce n'est pas vraiment répondre à votre question, mais vous pouvez envelopper chaque élément de FAQ (à savoir toutes les questions / paire de réponse) dans un élément DIV. Ce serait logique sémantiquement, et le non-programmeur en maintenant la page devrait simplement copier une pleine <=> (pas besoin pour les classes).

HTML:

<div id="faq">
 <!-- start FAQ item -->
 <div>
  <h2>Question goes here</h2>
  <p>Answer goes here.</p>
  <p>And here.</p>
  <ul>
   <li>Really, use any HTML element you want here.</li>
   <li>It will work.</li>
  </ul>
 </div>
 <!-- end FAQ item -->
 <!-- start FAQ item -->
 <div>
  <h2>Second question goes here</h2>
  <p>Answer to question two.</p>
 </div>
 <!-- end FAQ item -->
</div>

JavaScript (jQuery):

$('#faq div h2').click(function() {
 $(this).parent().find(':not(h2)').show();
});

Juste au cas où il y a encore des gens qui ont besoin d'une réponse pour cette ... Cela inclut également la ligne de h2 dans le groupe.

Ici si l'échantillon html pour lequel fonctionne ma solution:

<h2> text1 </h2>
<p>asd</p>
<p>asd</p>
<p>asd</p>
<p>asd</p>
<h3>kjdf</h3>
<h2>asdk</h2>
<h3>kjdf</h3>
<p>asd</p>
<p>asd</p>
<p>asd</p>
<p>asd</p>
<h2>aqdsa</h2>

solution:

jQuery( function ( $ ) {
//defining groups for wrapping them in custom divs

    $('h2').each( function () {
        var grpForDiv= [];          
        var next = $(this).next();  
        grpForDiv.push(this);
        while ( next.length!==0 && next!== undefined && next[0].nodeName !== 'H2')
            {
            grpForDiv.push(next[0]);
            next = next.next();
            }       
        jQuery(grpForDiv).wrapAll('<div class="Group1" />');

    } );
} );

Notez que la réponse choisie est bonne, mais je suis à la recherche en faisant quelque chose de similaire si je travaillais des heures supplémentaires à ce sujet:)

J'ai mis cela dans un exemple.

Compte tenu de HTML:

<h2>Question 1</h2> 
<p>Answer 1</p> 
<p>Answer 1</p> 
<p>Answer 1</p> 
<h2>Question 2</h2> 
<p>Answer 2</p> 
<p>Answer 2</p> 
<p>Answer 2</p> 
<h2>Question 3</h2> 
<p>Answer 3</p> 
<p>Answer 3</p> 
<p>Answer 3</p> 

Procédez comme suit et vous aurez votre réponse. I pense il est maintenant la plus élégante de toutes les solutions données, mais j'apprécieraient d'autres commentaires sur ce un peu.

jQuery.fn.nextUntilMatch = function(selector) { 
  var result = [];   
  for(var n=this.next();(n.length && (n.filter(selector).length == 0));n=n.next())  
      result.push(n[0]);   
  return $(result); 
} 

$(function() { 
  $('h2~p').hide(); 
  $('h2').click(function() { 
    $(this).nextUntilMatch(':not(p)').toggle(); 
  }) 
});

Vous pouvez aussi le faire sans vous éditer HTML. Ceci est un plugin que je viens d'écrire à cet effet particulier:

(function($){
    $.fn.nextUntill = function(expr){
        var helpFunction = function($obj, expr){
            var $siblings = $obj.nextAll();
            var end = $siblings.index( $siblings.filter(expr) );
            if(end===-1) return $([]);
            return $siblings.slice(0, end);
        }
        var retObject = new Array();
        this.each(function(){
            $.merge(retObject, helpFunction($(this), expr));
        });
        return $(retObject);
    }
})(jQuery);

Vous pouvez l'utiliser comme ceci:

 $('h2').click(function(){
    $(this).nextUntill('h2').show(); //this will show all P tags between the clicked h2 and the next h2 assuiming the p and h2 tags are siblings
 });

Je ne pense pas que votre stratégie pour résoudre le problème est correct, vous avez eu 6 réponses qui permettent de résoudre en partie le problème .....

Mais votre plus gros problème est que vous dites que vous ne pouvez pas faire confiance aux mainteneurs d'utiliser divs / travées / classes etc.

Ce que je pense que vous devriez faire est de simplifier le processus pour eux, et de les former à utiliser votre méthode ou il PAS travail .

ajouter une simple marque jusqu'à votre propre et d'interpréter pour eux.

[Q] What happens when you click this link?[/Q]
[A] This marvellous answer appears [/A]

(jQuery ne résoudra pas le bug 'utilisateur')

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