2011-06-29 16 views
5

Bu, birçok kez sorulan sorudaki bir varyasyondur. Herhangi bir eleman verildiğinde, belgesinin tamamında belgesinin tamamında başka bir öğe bulabilmek istiyorum. Bir kardeş olabilir ama daha sonra ortaya çıkan başka bir element de olabilir. Örneğin, ben $.fn.nextInDocument denir arıyorum işlevini Diyelim Bu açıklamanın uğruna aşağıdaki işaretlemeyiBelirli öğe sonra * tüm * belgedeki sonraki öğe

<div> 
    <p>Hello</p> 
    <div> 
     <p>Foo</p> 
     <p class="bar">Bar</p> 
     <p>rawr!</p> 
    </div> 
    <p>bop</p> 
    <input/> 
    <div> 
     <p>Another</p> 
     <div> 
      <span>something</span> 
      <p>deep!</p> 
     </div> 
    </div> 
</div> 
<p>last</p> 

verilen. Aradım edin:

$('.bar').nextInDocument('p'); // <p>rawr</p> 
$('.bar').nextInDocument('p').nextInDocument('p'); // <p>bop</p> 

Devam edersek, bu <p>Another</p> ardından <p>deep!</p> ve son olarak <p>last</p> tanınacak.

Böyle bir şey var mı? Bir seçici mi yoksa bir işlev mi olduğu umurumda değil. Sadece işlevselliğe ihtiyacım var.

EDIT Daha fazla zorlu bir soru haline getirmek için DOM yapısını, aradığım şey için daha net hale getirmek üzere güncelledik.

cevap

2

? Sırayla düğümleri çaprazlamak ve her birini jQuery seçicisine karşı test etmek için DOM yöntemlerini kullanan genel bir çözümdür.

jsFiddle: http://jsfiddle.net/PsEdZ/3/

(function($) { 
    function nextNode(node, omitChildren) { 
     var sibling, parentNode; 
     if (!omitChildren && node.hasChildNodes()) { 
      return node.firstChild; 
     } else { 
      sibling = node.nextSibling; 
      if (sibling) { 
       return sibling; 
      } else { 
       parentNode = node.parentNode; 
       return parentNode ? nextNode(parentNode, true) : null; 
      } 
     } 
    } 

    $.fn.nextInDocument = function(selector) { 
     var node = this[0], $node; 
     while ((node = nextNode(node))) { 
      $node = $(node); 
      if ($node.is(selector)) { 
       return $node; 
      } 
     } 
     return null; 
    } 
})(jQuery); 
+0

bu işe yarıyor gibi görünüyor. Şimdi birkaç zor durumu test ediyor ... – Jeff

+0

Bu, bugüne kadar attığım her şeye ayak uydurdu. Şu ana kadar ne kadar iyi performans gösterdiğini merak ediyorum, şu anda aşırı büyük sayfalarda çalışmayı planlamıyorum. çok teşekkürler! – Jeff

+0

@Jeff: Muhtemelen optimize edilmiş olabilir: örneğin, her düğüme ait seçiciyi değerlendirmenin olası performans sorunlarının sebebi olduğunu düşünüyorum. Bir darboğaz ortaya çıkarsa sadece bunu yapmak için rahatsız etmenizi öneririm. –

1

Çalışması gerekir. ... o da, yararlıdır değil gerçekten emin

;(function ($) 
{ 
    $.fn.nextInDocument = function (s) 
    { 
     var self = this, 
      next; 
     do 
     { 
      next = self.nextAll(s).first(); 
      self = self.parent(); 
     } 
     while (self.length && !next.length); 

     return next; 
    }; 
})(jQuery); 

Demo: my kodu http://jsfiddle.net/mattball/HAFn8/

+0

@Matt Topu çünkü olsaydı emin değilim rağmen, bir akım öğeden sonra alt öğeleri girmeden bazı sorunlar vardır hatta böyle işlevselliği sonra: http://jsfiddle.net/niklasvh/HAFn8/3/ – Niklas

+0

Bunu işaretlediğiniz için teşekkürler. Bariz bir eksiklik, eğer ihtiyaç duyulursa işleri daha da karmaşıklaştıracaktır. Daha iyi bir ağaç geçişi algoritmasına ihtiyaç duyacaktır. –

+0

Bunun nasıl çalıştığından emin değilim ama umut verici görünüyor. Onu bir kemanın içine koydum ve bir seçiciyle eşleşmenin bir yolu yok. Başka bir deyişle, $ ('.bar'). NextInDocument ('p') == $ ('.' Bar '). NextInDocument (' div ') =='

rawr!

'. – Jeff

1
(function(jQuery) { 
jQuery.fn.extend({ 
    nextInDocument: function(a) { 
     if (jQuery(this).next(a).length === 0) { 
      //console.log($(this).parent().nextInDocument('p')); 
      jQuery(this).parent().nextInDocument(a); 
     } 
     else 
      return jQuery(this).next(a); 
    } 
}); 
})(jQuery); 
+0

Teşekkürler Boopathi.Ben bir şey eksik mi emin değilim.Bunu bir keman içine koydum ve işleviniz her arama için orijinal öğeyi döndürdü, örneğin, $ ('. bar ') .nextInDocument (' div ') ==

rawr

1. http://jsfiddle.net/jeffrod/nHeGU/ – Jeff

+0

bu konuda üzgünüm ... düzeltildi .. kontrol edin .. bir daha küçük hata var. geliştirmek ... –

+0

im bundan geri nulls. hala çalışmıyor – Jeff

0

almak görünüm:

HTML

<div> 
    <p>Hello</p> 
    <div> 
     <p>Foo</p> 
     <p>Fooooo</p> 
     <p class="bar">Bar</p> 
     <p>rawr!</p> 
    </div> 
    <p>bop</p> 
    <input/> 
    <div> 
     <p>Another</p> 
    </div> 
</div> 
<p>last</p> 

<a class="show" href="#">!!!</a> 

JS

$(function() { 
    i = 0; 
    start = 0; 
    $('p').each(function() { 
     if ($(this).hasClass('bar')) { 
      start = i; 
     } 
     i++; 
    }); 
    $('a.show').click(function(){ 
     alert($('p').eq(start+4).text()); 
    }); 
}); 

http://jsfiddle.net/mV8pm/

değişim start+X ve bir sonraki 's' etiketi Burada

+0

çalışmak için görünmüyor.Bu demo verdiğim işaretlemeye sıkı sıkıya bağlı gibi görünüyor, ama "herhangi bir öğe için" çalışabilir bir şey gerekir ve herhangi bir elem ondan sonra. Bu esnek – Jeff

+0

bahis olacağını sanmıyorum :) farklı DOM'larda deneyin. İhtiyacınız olan her şey bu kodu JQ işlevine koymaktır. Bu arada, başlangıç ​​öğesinin etiketi (sınıf tarafından seçilir) ve sonra aradığınız etiketler aynı olmalıdır (örneğin, 'p'). Düz eski js için – bravedick

1

bir POJS versiyonu alacak: Bu nasıl hakkında

function nextInDocument(el, tagName) { 
    var node, nodes = document.getElementsByTagName('*'); 
    var start = false; 
    tagName = tagName.toLowerCase(); 

    for (var i=0, iLen=nodes.length; i<iLen; i++) { 
    node = nodes[i]; 
    if (!start) { 
     if (node == el) start = true; 
    } else { 
     if (node.tagName.toLowerCase() == tagName) { 
     return node; 
     } 
    } 
    } 
} 
+0

güzel bir çözüm. Teşekkürler. jquery daha karmaşık seçicilerden faydalanabilir, ancak diğer bazı parçacıkları özel durumum için daha çekici hale getirir. – Jeff

+0

Bu yaklaşıma dikkat edin, seçicilerin çok karmaşık hale getirilmesi durumunda performans sorunlarını bulabilirsiniz. Bunun yerine sınıfları kullanmayı düşünün, böylece bir sonraki elemanın bulunması daha kolay olur. – RobG

+0

iyi nokta. hasta performansın bir sorun haline gelmesi durumunda düşünün. – Jeff