- ベストアンサー
jQueryで特定id以外の下にある要素を削除したい
- HTMLの制御にjQueryを使用しています。作業の流れで、#contents以外の要素に存在する特定のクラスを削除したいと思っています。
- 具体的には、<div id='contents'>以外の要素でclass='test'を持つ要素を削除したいです。
- 既存のコードではうまく動作しないため、別の方法を模索しています。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
id="contents"の上層にもdivがあるからでしょうか? その辺を考慮すると今までの考え方だとソースが少し煩雑になるので、 一度全てのclass="test"要素を取得してからid="contents"下の要素を 除外するのが良いかと思います。 jQuery('.test:not(#contents .test)').removeClass('test'); notメソッドを使う場合は、 jQuery('.test').not('#contents .test').removeClass('test'); 余談ですが、 タグが固定できる場合は固定した方が実行速度が速いです。jQueryは特に。 jQuery('p.test').not('div#contents p.test').removeClass('test');
その他の回答 (3)
- imq
- ベストアンサー率72% (16/22)
補足です。 回答2に書いたものはdiv階層にかかわらず除外するようにできています。 2つめのnotの中にある'#contents div'は、 id="contents"の子孫要素のdivという意味です。 この辺はjQueryというよりCSS Selectorの範疇です。
お礼
失礼しました。 目的id以下のdivの数だけ、排除処理が必要だと勘違いしていました。 今、モバイルからのアクセスなので、パソコンが使える環境になりましたら、改めてご報告いたします。
補足
昨晩戻ってきました。 早速試してみましたが、旨くいきませんでした。 旨く排除できずでいます。 試しに下記のようなコードで反応を見てみました。 jQuery('div').not('#contents').not('#contents div').find('.test').css("border","1px solid red"); jQuery('div').not('#contents').find('.test').css("border","1px solid red"); jQuery('div').not('#contents div').find('.test').css("border","1px solid red"); なぜか全てのクラスに反応してしまいます。 notの動作が思っているような動きではないのかな? と思ったりもします。
- imq
- ベストアンサー率72% (16/22)
質問にあるコンパクト化したソースなら動くはずですが、 div#contentsの中に更にdivがワンクッション入っていると↓ <body> <div id="contents"> <div> <p class="test">moji</p> </div> </div> … </body> 中間のdivは除外されないので、想定した動きにならないです。 中間のdivも除外するなら $('div').not('#contents').not('#contents div').find('.test').removeClass('test'); としてみてください。
お礼
回答ありがとうございます。 #contentsの下のDIV階層は固定できないので、別な方法を考えました。 jQuery("#contents").find(".test").addClass("escape"); jQuery(".test").each( function(){ if( jQuery(this).hasClass("_escape") == false ){ jQuery(this).removeClass("test"); } }); jQuery("#contents").find(".test").removeClass("escape"); あまり綺麗なやり方ではないかも知れません。 とりあえず目的は達することはできました。 もっとシンプルな方法をもう少し考えてみます。
補足
ソースに一部誤りがありました。 jQuery("#contents").find(".test").addClass("escape"); jQuery(".test").each( function(){ if( jQuery(this).hasClass("escape") == false ){ jQuery(this).removeClass("test"); } }); jQuery("#contents").find(".test").removeClass("escape");
- imq
- ベストアンサー率72% (16/22)
hasClassの戻り値はjQueryオブジェクトではなく真偽値なので、 その後にメソッド・チェーンを続けることができません。 子孫要素を指定にはfindメソッドを使います。 あと、全要素指定の"*"はnotと組み合わせると想定した動きにならないので、 divを指定した方がいいです。 $('div').not('#contents').find('.test').removeClass('test'); jQueryの場合CSS3が使えるので、こういう記述もできます。 $('div:not(#contents) .test').removeClass('test'); ちなみに1つのjQueryオブジェクトにまとめられた全ての要素に対して 同じjQueryメソッドを適用する場合、わざわざeachメソッドを使う必要はないです。
補足
回答ありがとうございます。 hasClassは真偽値だったんですね。 確認不足でした。 コードを試してみましたが、残念ながら旨くいきませんでした。 $('div').not('#contents').find('.test').css("border","1px solid red"); $('div:not(#contents) ._test').css("border","1px solid red"); 上記で試してみたところcontentsの下のクラスもborderが適用されます。 さらに jQuery('div').not('#contents').css("border","1px solid green"); というののも試してみたのですが、これでも全ての要素のborderが適用されます。
お礼
できました! ありがごうとざいます。 御返事が遅くなって申し訳ありません。 質問のソースが端折りすぎたためにお手数をおかけしました。 思い通りの動作です。 ずっと悩んでいたので、とても感激です。 ありがとうございました。