2010-11-18 16 views
7

HTML belgelerinde metin seçerken, bir DOM öğesinin içinden başka bir öğeye, muhtemelen yol üzerindeki diğer öğelerin üzerinden geçmeye başlayabilirsiniz. DOM API'yi kullanarak, seçim aralığını, seçilen metinleri ve hatta seçilen tüm DOM öğelerinin ana öğesini (kullanılmış tarayıcıya dayalı olarak commonAncestorContainer veya parentElement() kullanarak) almak mümkündür. Ancak, bunların hepsini içeren tek ana öğeyi almanın dışında seçilen metinlerin öğelerini içeren tüm öğeleri listeleyebileceğinin farkında olmamın bir yolu yoktur. Ebeveynin kullanılması ve çocuk düğümleri arasında geçiş yapmak, bu ebeveynin içinde seçilmeyen başka kardeşler olabileceğinden bunu yapmayacaktır.Seçilen metinler için tüm DOM blok öğelerini al

Seçili metinleri içeren tüm öğeleri alabilmemin bir yolu var. Temel olarak blok elemanlar (p, h1, h2, h3, ... vs) almakla ilgileniyorum ama tüm elementleri elde etmenin bir yolu varsa, o zaman bunlardan geçip neyi elde etmek için onları filtreleyebileceğime inanıyorum. istemek. Herhangi bir fikri ve öneriyi memnuniyetle karşılıyorum.

Teşekkür ederiz.

cevap

16

Anahtar İşte window.getSelection().getRangeAt(0)https://developer.mozilla.org/en/DOM/range

olan istediğini yapmak ile oynayabilir bazı örnek kod. Bunları gerçekten istediğiniz şeyden bahsetmek, insanların daha iyi yanıtlar vermesine yardımcı olacaktır.

var selection = window.getSelection(); 
var range = selection.getRangeAt(0); 
var allWithinRangeParent = range.commonAncestorContainer.getElementsByTagName("*"); 

var allSelected = []; 
for (var i=0, el; el = allWithinRangeParent[i]; i++) { 
    // The second parameter says to include the element 
    // even if it's not fully selected 
    if (selection.containsNode(el, true)) { 
    allSelected.push(el); 
    } 
} 


console.log('All selected =', allSelected); 

Bu en etkili yolu değil, nextSibling/previousSibling ve childNodes birlikte Range en startContainer/endContainer kullanarak DOM kendiniz çapraz olabilir.

+0

Söylediğiniz mükemmel çözüm değil, ama nasıl yapılacağı konusunda bana bir fikir verdi. Bu nedenle, ihtiyacımın en doğru cevabı olarak seçtim. Bunu gerçekten takdir ediyorum. – cria

+0

Bu iyi bir cevaptır, ancak IE <9'da çalışmayacaktır. Seçim, 'selection.getRangeAt (0);' da (seçimin 'rangeCount' özelliği kullanılarak en kolay şekilde) çağırılmadan önce var olduğunu kontrol ederek yapabilir. –

+0

Adreslemediğim bir sürü tuhaflık var, bu sadece doğru yönde ilerlemeye başlıyor. Kitaplığınız gerçekten işlemek için 22k sıkıştırılmamış javascript gerektirir ve gerekirse ona ihtiyacım var. –

0

Traversing from the jQuery API'u kullanabileceğiniz gibi görünüyor.

Muhtemelen .contents() yardımcı

Umut!

+0

Evet, yöntemlerin hepsi harika. Ancak tarayıcıların seçilen metin aralığını bu yöntemler için bir girdi olarak kullanabileceğime inanamıyorum, değil mi? ya da belki bir şey özlüyorum ... Teşekkürler – cria

10

Bunu yapmak için Rangy library sayfamı kullanabilirsiniz. IE dahil tüm tarayıcılar için DOM Aralığı ve Seçim nesnelerinin bir uygulamasını sağlar ve Ekstra Aralığı yöntemleri vardır. Bunlardan biri getNodes() geçerli:

function isBlockElement(el) { 
    // You may want to add a more complete list of block level element 
    // names on the next line 
    return /h[1-6]|div|p/i.test(el.tagName); 
} 

var sel = rangy.getSelection(); 
if (sel.rangeCount) { 
    var range = sel.getRangeAt(0); 
    var blockElements = range.getNodes([1], isBlockElement); 
    console.log(blockElements); 
} 
+0

Bu kodun en doğru olduğunu hiç şüphem yok. Ama lib'inizi kullanmak, lib'in büyüklüğü nedeniyle benim durumum için bir aşırı sıkıntı. Bu nedenle, ele almam gereken bazı sorunları olsa da diğer cevabı seçtim. İki cevap seçmek için bir seçenek olsaydı, ben de seninkini de işaretlerdim. Harika lib/work tutun :) – cria

+0

@cria: Yeterince adil. Benimki ile aldığın şey IE için destek. –

+3

@TimDown, Rangy'deki çalışmalarınız için teşekkür ederiz. Bir dizi karmaşık problemi çok daha kolay hale getirir. –

İlgili konular