セレクタの直下の要素のみ欲しい
セレクタの直下の要素って何?子要素と違うの?はい、違います。今回欲しい要素はコレです!
<html>
<header>
<title>sample</title>
</header>
<body>
<div>親御さん<p>お子さん</p>(田中)</div>
</body>
</html>
『親御さん(田中)』のみ取得したい。テキストのみではなく、NodeListで。なんでNodeListで欲しいのかというとテキストを書き換える需要があるからです。多分。
よくよく考えてみると、この条件に合致する要素っていうのはTEXT_NODEのみなんですな。なので、それ前提の決め打ちコードを書きます。
せっかくだからjQueryを拡張して書きます。
これがソースコードだ!
<html>
<header>
<title>sample</title>
<script src="https://code.jquery.com/jquery-3.4.1.js"></script>
</header>
<body>
取ってきたよ -> <span id="output"></span>
<div>親御さん<p>お子さん</p>(田中)</div>
<div>親御さん<p>お子さん</p>(佐藤)</div>
<div>親御さん<p>お子さん</p>(山田)</div>
<script>
function display( divs ) {
console.log(divs);
var a = [];
for ( var i = 0; i < divs.length; i++ ) {
a.push( divs[ i ].text() );
}
$( "span#output" ).text( a.join(" ") );
}
jQuery.fn.extend({
direct : function _(elem){
let node,
tmp = [],
ret = [],
i = 0;
elem = elem ? elem : this;
let nodeType = elem.nodeType;
if ( !nodeType ) {
while ( (node = $(elem).contents()[i++]) ) {
tmp.push(_(node));
}
} else if (nodeType === Node.TEXT_NODE){
return $(elem);
}
tmp.forEach((item, i) => {
if(!$.isEmptyObject(item))
ret.push(item);
});
return ret;
}
});
display($("div").direct());
</script>
</body>
</html>
これ再帰を使ってるんですけど、本当は$("div")の直下だけ取れればいいんだから再帰は使わなくてもいいんですよね。でもなんで再帰を使っているかというと、参考にした jQuery.text()のソースコード が再帰だったってのと、この再帰を使うなら$("div")の直下のテキストとA要素のテキストのみ取ってくるってこともできるはずなのです。はず。
今の所再帰なのに返り値を配列にしてしまっているので、少し潜ると多重配列になってしまってうまくいっていないのですが、再帰だからこそできるはず。もう少し頑張りたいです。
参考URL
jQuery.text()のソースコード
jQuery 子要素を含まない text() が欲しい時
[JQuery] 直下のテキストノード(TextNode)の値を取得する
HTMLのある要素の直下のテキストだけを取り出す
jQuery拡張の仕組み 〜 JSおくのほそ道 #013
https://api.jquery.com/jQuery.fn.extend/
https://api.jquery.com/get/