Pregunta

Soy la creación de una página de preguntas frecuentes muy sencillo con jQuery. De esta manera:

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

Esto es todo dentro de un div muy específico, así que voy a ser la selección de la cabecera con $('#faq h2'). Simple, ¿verdad? Haga clic en el H2, y utilizar this.next() para hacer el siguiente párrafo apareció.

(La advertencia de esta página es que un no-programador será el mantenimiento, lo cual es por eso que no estoy usando clases:. No hay ninguna garantía de que las nuevas entradas tendrían las clases correctas en ellos)

Así! El problema:

<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>

Entonces, ¿cómo, sin añadir en div s y las clases y todo eso, puedo tener mi <=> rutina de selección de todo lo que entre la pregunta-que-se ha hecho clic-en-Y la siguiente pregunta (cabecera H2)?

¿Fue útil?

Solución

Problema interesante. En primer lugar quiero decir que creo que la mejor estrategia es encerrar la respuesta completa en un div y luego el problema se vuelve trivial para resolver:

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

por:

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

Pero una vez dicho esto, es solucionable sin eso.

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

No es sumamente elegante, sino que va a trabajar.

Nota: Esto supone que las preguntas son hermanos. Si no es así, el fichero es mucho más complicado.

Otros consejos

Me doy cuenta de que esto es una vieja pregunta, pero jQuery 1.4 ahora tiene nextUntil . Así que algo como esto debería funcionar:

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

¿no tendría más sentido utilizar un estilo css lista DL

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

Y a continuación, una selección fácil usando:

$('+ dd', this); 

siendo este el actual dt selección.

O simplemente envolver cada respuesta en un div, ya que tiene sentido semántico también. Sin embargo, creo una lista DL hace mucho más sentido semántico.

Por supuesto! Sólo hacer un bucle while.

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

Esto supone que sólo tiene etiquetas p después de su h2. Se pueden añadir más excepciones al bucle while si quieres añadir algo como img.

O si no le importa lo que hay entre las etiquetas H2 se puede comprobar por no igual a H2.

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

Esto ocultará todo después de que el H2 que se ha hecho clic hasta la próxima sea H2 se encontró o subir un nivel en el DOM.

Tal vez esto no está realmente respondiendo a su pregunta, pero se puede envolver cada artículo FAQ (es decir, cada pregunta / respuesta par) en un elemento de DIV. Esto tendría sentido semántico, y la no-programador de mantenimiento de la página simplemente tendría que copiar un <=> completa (sin necesidad de clases).

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

Sólo en caso de que todavía hay gente que necesitan una respuesta para esto ... Esto también incluye la línea h2 en el grupo.

Aquí, si el código HTML muestra para la que trabaja mi solución:

<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>

solución:

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" />');

    } );
} );

Tenga en cuenta que la respuesta seleccionada es buena, pero estoy buscando para hacer algo similar, por lo que trabajé horas extras en él:)

He puesto esto en un ejemplo.

Dado 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> 

Haga lo siguiente y obtendrá su respuesta. I piensan Es ahora el más elegante de todas las soluciones dadas, pero me gustaría valorar a los demás entrada en esta un poco.

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

También puede hacer esto sin necesidad de editar que HTML. Este es un plugin que acabo de escribir para este propósito particular:

(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);

Puede utilizar de esta manera:

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

No creo que su estrategia para resolver el problema es correcto que usted ha tenido 6 respuestas que, en parte a resolver su problema .....

Pero el mayor problema es que se dice que no puede confiar en los mantenedores de usar divs / luces / clases, etc.

Lo que creo que usted debe hacer es simplificar el proceso para ellos, y de enseñarles a usar el método o no trabajo.

añadir un poco simple marca de su propio e interpretar para ellos.

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

(jQuery no reparar el fallo 'usuario')

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top