非表示の要素を無視するためにjqueryテキスト()関数が必要です
-
29-10-2019 - |
質問
私はこのようなものをセットアップしています:
<div id="test"> <p>Hello</p> <p style="display: none">Goodbye</p> </div>
編集:明確にするために、これが最も単純な例です。 divには、任意の数のn深い巣のある子供を持つことができます。
$('#test').getText()
「こんにちはさようなら」を返します。これがFirebugでテストする1つのライナーです: jQuery('<div id="test"> <p>Hello</p> <p style="display: none">Goodbye</p> </div>').text()
これは、jQueryが内部で使用するもの、TextContent(非IEの場合)がテキストの一部として非表示の要素を返すためです。 hrmph。
ディスプレイを無視してテキストコンテンツを返す方法はありますか:なし要素はありませんか?基本的に、マウスでDIVを強調表示し、システムクリップボードにコピーすることから得られるテキストを模倣しようとしています。それは隠されたテキストを無視します。
興味深いことに、選択範囲を作成してテキストを取得すると、表示:なしの要素の内部にテキストを返します。
var range = document.body.createTextRange();
range.moveToElementText($('#test')[0]);
range.select();
console.log(range.toString()); // Also logs Hello Goodbye!
したがって、ドキュメントの選択範囲を作成すると、表示:なしの要素の観点からマウスでハイライトするのと同じことは見えません。この汚い漬物の難問を回避するにはどうすればよいですか?
編集:使用 .filter(':visible').text
提案されていますが、このシナリオでは機能しません。マウスの選択からまさに届くものであるために、返されたテキストが必要です。したがって、例:
$('<div>test1 <p>test2</p>\r\n <b>test3</b> <span style="display:none">none</span></div>').appendTo(document.body).children().filter(':visible').text()
戻り値
"test2test3"
私が実際に望む出力はいつですか
test1 test2
test3
r nから来るラインブレイク、白人、そしてすべて
解決
使用して要素をフィルタリングします .filter(":visible")
.
またはこれを使用してください:
$("#test :visible").text();
しかし jQueryドキュメント 使用することをお勧めします .filter()
代わりは:
なぜなら :visible
jQuery拡張機能であり、CSS仕様の一部ではなく、使用を使用してクエリ :visible
ネイティブDOMが提供するパフォーマンスブーストを利用できません querySelectorAll()
方法。使用するときに最適なパフォーマンスを実現するには、以下を使用するときに目に見える要素を選択するには、まず純粋なCSSセレクターを使用して要素を選択し、次に使用します。 .filter(":visible")
.
他のヒント
使用する :visible
そのようなセレクターで:
$("#test > p:visible").text()
関数の例:
- 編集:
http://jsfiddle.net/8h5ka/ (結果として「こんにちは」を表示するChromeで動作します)
上記が機能しない場合:
スペースが大きな懸念事項でない場合は、マークアップをコピーし、隠された要素を削除し、そのテキストを出力できます。
var x = $('#test').clone();
x.filter(':not(:visible)').remove();
return x.text();
私はこの問題を抱えていて、この質問を見つけましたが、実際の解決策は提供された回答に基づいているようですが、実際には書かれていません。したがって、私の状況に合わせて機能する完全なソリューションがあります。これは、DOMの位置に基づいた外部スタイルのために要素が見えない可能性がある追加の提供があるOPと同じです。例:
<style>.invisible-children span { display: none; }</style>
<div class="invisible-children">
<div id="test">Hello <span>Goodbye</span></div>
</div>
解決策は次のとおりです。
- オブジェクト全体のクローンを作成します。
- 目に見えないオブジェクトを所定の位置に削除します。私たちが取るなら
#test
目に見えないオブジェクトを削除する前にDOMから外れて、jQueryはCSSルールと一致しなくなるため、目に見えないことを知らないかもしれません。 - オブジェクトのテキストを取得します。
- 元のオブジェクトを作成したクローンに置き換えます。
コード:
var $test = $('#test');
// 1:
var $testclone = $test.clone();
// 2: We assume that $test is :visible and only remove children that are not.
$test.find('*').not(':visible').remove();
// 3:
var text = $test.text();
// 4:
$test.replaceWith($testclone);
// Now return the text...
return text;
// ...or if you're going to keep going and using the $test variable, make sure
// to replace it so whatever you do with it affects the object now in DOM and
// not the original from which we got the text after removing stuff.
$test = $testclone;
$test.css('background', 'grey'); // For example.
これが私がMootoolsでそれをした方法です:
$extend(Selectors.Pseudo, {
invisible: function() {
if(this.getStyle('visibility') == 'hidden' || this.getStyle('display') == 'none') {
return this;
}
}
});
Element.implement({
getTextLikeTheBrowserWould = function() {
var temp = this.clone();
temp.getElements(':invisible').destroy();
return temp.get('text').replace(/ |&/g, ' ');
}
})
私はそれを検索し、この質問を見つけましたが、解決策はありませんでした。私にとっての解決策は、jqueryから出てDOMを使用することです。
var $test = $('#test').get(0).innerText
または、セレクターの配列の要素よりも多くの場合、ループとマージが必要ですが、ほとんどの場合、それはあなたが必要とする最初のバージョンであると思います。
var $test = $('#test').get().map(a => a.innerText).join(' ');