2013-07-19 71 views
4

可以說我有一些HTML這樣的:僅獲得與jQuery可見文本

<div id="content">Foo<span style='display:none'>hidden</span>Bar</div> 

在現實中,這是更爲複雜和使用ng-hide和類似的角度產生。我需要從content div中獲取用戶可見的所有文本。在這種情況下,我想獲得FooBar

$('#content').text()是我發現的最接近的東西,但在這種情況下,這給了我FoohiddenBar。有沒有一種很好的方法來獲得div的可見內容?我真的需要一個跳過隱藏元素的text()函數。

回答

8

創建克隆,將它添加到DOM(由slindberg指出的),刪除所有隱藏要素,然後獲取文本:

var clone = $('#content').clone(); 

clone.appendTo('body').find(':hidden').remove(); 

var text = clone.text(); 

clone.remove(); 

FIDDLE

+0

這在這個例子中有效,但在我的實際應用中,整個輸出div由複雜的角標籤組成。使用'clone.find(':hidden'),remove();',幾乎所有東西都會被刪除,即使是可見的項目。很有意思。 – captncraig

+0

如果它不是有效的標記,但由於某些原因包含角標記並且無法使用常規DOM遍歷方法進行分析,則會出現問題。 – adeneo

+0

由於某種原因'clone.find(':hidden')'返回比$('#content')大得多的集合find(':hidden')'這是所有有效的標記。也許是因爲角度沒有完全編譯克隆的元素? – captncraig

5

不幸的是@ adeneo的回答贏得了」在大多數情況下工作,因爲克隆會創建一個文檔片段,其子代在定義時不可見(它們不會附加到文檔中),因此在調用.text()之前全部刪除。這意味着元素的子元素的文本將不會包含在結果中。

我發現要做到這一點的唯一方法是實際遍歷所有節點自上而下,省略了視覺上隱藏的節點。幸運的是這可以在一個相當簡潔的插件來表示:

jQuery.fn.visibleText = function() { 
    return $.map(this.contents(), function(el) { 
    if (el.nodeType === 3) { 
     return $(el).text(); 
    } 
    if ($(el).is(':visible')) { 
     return $(el).visibleText(); 
    } 
    }).join(''); 
}; 

注意,此插件假設選擇的根元素不是文本節點(這幾乎是從來沒有的情況下)。另外請注意,如果您不必支持IE8,則$(el).text()可以替換爲el.textContent

JSFiddle

+2

你是什麼意思,它不會工作?你是否在我的答案中嘗試了小提琴,它似乎工作得很好,這是因爲jQuery的':visible'僞選擇器並不在乎元素是否在DOM中。 – adeneo

+0

問題是,從克隆中移除':hidden'元素最終將刪除所有的孩子,因爲從文檔根中分離時它們都被認爲是隱藏的。我已經創建了[JSFiddle的一個分支](http://jsfiddle.net/7Lrqh/),它演示了這個問題。我已經更新了我的回答,以便更清楚地瞭解問題所在。 – slindberg

+0

我明白你的意思,在這種情況下,這沒什麼關係,但如果有人有其他元素等等,我可能會遇到問題。我其實也在文檔中找到了它,*「不考慮文檔中的元素可見「*,好點。我改變了解決它的答案。 – adeneo

0

關鍵是要修改DOM在地方得到的文本,然後將其恢復爲原來的,當我們用它做。以下是卓有成效的:

function get_visible_text(content) { 
    // Not so easy to get the visible text 
    var saved = $(content).clone(); 
    // Remove the hidden parts 
    $(content).find(':hidden').remove(); 
    // Get the remaining text 
    var visible_text = $(content).text(); 
    // Now revert back to our saved version 
    $(content).replaceWith(saved); 
    return visible_text; 
} 

注意@slindberg是正確的,@ adeneo的回答不會起作用,因爲直到它們被插入到DOM克隆的對象是不可見的。通過修改DOM,我們可以避免這個問題。