37

このhtmlをjQueryで解析して、data1、data2、data3を取得しようとしています。data2とdata3を取得していますが、私のアプローチではdata3を取得できません。私はjQueryにかなり慣れていないので、無知を許してください。

<html>
<body>
   <div class="class0">
    <h4>data1</h4>
    <p class="class1">data2</p>
    <div id="mydivid"><p>data3</p></div>    
   </div>
</body>
</html>

これが私のjqueryでこれをどのように呼んでいるかです。

var datahtml = "<html><body><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></body></html>";

alert($(datahtml).find(".class0").text()); // Doesn't Work

alert($(datahtml).find(".class1").text()); // work 

alert($(datahtml).find("#mydivid").text()); // work

動作していないだけalert($(datahtml).find(".class0").text());で、残りは期待どおりに動作しています。class0の中に複数のタグがあるのでしょうか?そのようなシナリオでdata1を取得する方法は?

4

7 に答える 7

58

現在の回答はどれも実際の問題に対処していないので、試してみます。

var datahtml = "<html><body><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></body></html>";

console.log($(datahtml));

$(datahtml)は要素のみを含むjQueryオブジェクトであるdiv.class0ため、このオブジェクトを呼び出すと、期待するHTMLドキュメント全体ではなく、.find実際には子孫を探しています。div.class0

簡単な解決策は、解析されたデータを要素でラップして、.find意図したとおりに機能するようにすることです。

var parsed = $('<div/>').append(datahtml);
console.log(parsed.find(".class0").text());

フィドル


この理由はそれほど単純ではありませんが、jQueryはHTML文字列を別のオンザフライで作成されたDOMフラグメントにドロップするだけで、より複雑なhtml文字列を「解析」し、解析された要素を取得すると思います。この操作では、DOMパーサーがタグhtmlとタグを無視する可能性がありbodyます。この場合は違法であるためです。

これは非常に小さなテストスイートであり、この動作がjQuery1.8.2から1.6.4まで一貫していることを示しています。

編集:この投稿を引用:

問題は、jQueryがDIVを作成し、DIVのinnerHTML子を設定してから取得することですが、BODY要素とHEAD要素は有効なDIVの子ではないため、ブラウザーによって作成されません。

私の理論が正しいことをより確信させてくれます。ここで共有します。うまくいけば、それはあなたにとって何らかの意味があります。これと一緒にjQuery1.8.2の非圧縮ソースを用意します。#は行番号を示します。

(定義済み@#6122)を介して作成されたすべてのドキュメントフラグメントは(#6151)を通過し(キャッシュされたフラグメントであっても、作成時にすでに通過しています)、上記の引用テキストが示すように、(定義済み@# 6275)解析されたデータのコンテナとして機能する新しいフラグメントを安全なフラグメント内に作成します- #6301-6303で作成され、#6344で取得され、クリーンアップのために#6347でdivが削除されました(さらにバグ修正として#6359-6361)、#6351-6355で戻り配列にマージされ、#6406で返されました。jQuery.buildFragmentjQuery.cleanjQuery.cleanjQuery.cleandivdivchildNodeschildNodes

したがって、を呼び出すすべてのメソッドはjQuery.buildFragment、を含み、そのjQuery.parseHTMLjQuery.fn.domManipには.append()、jQueryオブジェクトメソッドを呼び出す .after()、、およびで処理されます(定義済み@#97、複雑な[複数のタグ] html文字列の処理@#125 、 @#131を呼び出します)。.before()domManip$(html)jQuery.fn.initjQuery.parseHTML

事実上すべてのjQueryHTML文字列の解析(単一タグのhtml文字列を除く)は、div要素をコンテナーとして使用して行われ、html/bodyタグは要素の有効な子孫ではないdivため、削除されます。


補遺:新しいバージョンのjQuery(1.9以降)では、HTML解析ロジックがリファクタリングされています(たとえば、内部jQuery.cleanメソッドは存在しません)が、全体的な解析ロジックは同じままです。

于 2012-10-09T21:49:28.863 に答える
26

htmlとbodyタグを無視し、class = "class0"の最初のdivから開始するため、その動作は奇妙です。htmlはDOM要素として解析されますが、DOMには追加されません。DOMに追加された要素の場合、セレクターは本文タグを無視せず、ドキュメントにセレクターを適用します。以下に示すように、HTMLをDOMに追加する必要があります。

ライブデモ

$('#div1').append($(datahtml)); //Add in DOM before applying jquery methods.

alert($('#div1').find(".class0").text()); // Now it Works too

alert($('#div1').find(".class1").text()); // work   

alert($('#div1').find("#mydivid").text()); // work

class = "class0"を使用した最初のdivではなく開始点にするためにhtmlをhtml要素でラップすると、セレクターは期待どおりに機能します。

ライブデモ

var datahtml = "<html><body><div><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></div></body></html>";

alert($(datahtml).find(".class0").text()); // Now it Works too

alert($(datahtml).find(".class1").text()); // work   

alert($(datahtml).find("#mydivid").text()); // work

jQueryのドキュメントがjQuery解析関数jQuery()、つまり$()について言っていること

複雑なHTMLを渡す場合、一部のブラウザは、提供されたHTMLソースを正確に複製するDOMを生成しない場合があります。前述のように、jQueryはブラウザの.innerHTMLプロパティを使用して、渡されたHTMLを解析し、現在のドキュメントに挿入します。このプロセス中に、一部のブラウザは、、、または要素などの特定の要素を除外し <html>ます <title><head>その結果、挿入された要素は渡された元の文字列を表すものではありません。

于 2012-10-09T21:57:00.513 に答える
3

私にはもっと良い方法があると思います:

あなたがあなたのhtmlを持っているとしましょう:

var htmlText = '<html><body><div class="class0"><h4>data1</h4><p class="class1">data2</p><div id="mydivid"><p>data3</p></div></div></body></html>'

これがあなたがやりたいと思っていたことです:

var dataHtml = $($.parseXML(htmlText)).children('html');

dataHtmlこれで、使い慣れた通常のjqueryオブジェクトとまったく同じように機能します。

このソリューションの素晴らしい点は、本文、ヘッド、またはスクリプトのタグが削除されないことです。

于 2014-05-26T19:45:06.977 に答える
2

これを試して

alert($(datahtml).find(".class0 h4").text());

参照しているテキストが..h4の要素 内にあるためclass0、セレクターは機能しません。、、またはコンテンツに直接アクセスします。

alert($(".class0 h4").text()); 

alert($(".class1").text()); 

alert($("#mydivid").text()); 

編集

var datahtml = "<html><body><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></body></html>";

$('body').html(datahtml);

   alert($(".class0 h4").text()); 

    alert($(".class1").text()); 

    alert($("#mydivid").text()); 

デモをチェック

于 2012-10-09T21:40:14.850 に答える
1

HTMLを一時的に非表示のコンテナに配置する以外の方法はわかりません。

$(document).ready(function(){
  var datahtml = $("<html><body><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></body></html>".replace("\\", ""));
  var tempContainer = $('<div style="display:none;">'+ datahtml +'</div>');
  $('body').append(tempContainer);
  alert($(tempContainer).find('.class1').text());
  $(tempContainer).remove();                                                                                                                                                        
});
​

これがjsfiddleのデモです。

于 2012-10-09T21:44:34.373 に答える
0

<div>withクラスにclass0は直接の子としてのテキストノードがないため、機能しません。クラスをに追加する<h4>と、機能します

于 2012-10-09T21:39:58.970 に答える
0

主な問題は、jqueryにhtmlを含めることができないことだと思います。あなたの場合、Jqueryに何が起こるかというと、最初のhtmlタグを見つけようとします。あなたの場合、それはclass0のdivです。

これをテストして、私が正しいことを確認します。

if($(datahtml).hasClass('class0'))
    alert('Yes you are right :-)');

つまり、htmlやbodyタグを、クエリを含めるためのパーツとして追加することはできません。

それを機能させたい場合は、コードのこの部分を追加してみてください。

<div>
    <div class="class0">
        <h4>data1</h4>
        <p class="class1">data2</p>
        <div id="mydivid"><p>data3</p></div>    
   </div>
</div>

だからこれを試してみてください:

var datahtml = "<div><div class=\"class0\"><h4>data1</h4><p class=\"class1\">data2</p><div id=\"mydivid\"><p>data3</p></div></div></body></div>";

alert($(datahtml).find(".class0").text()); // work

alert($(datahtml).find(".class1").text()); // work 

alert($(datahtml).find("#mydivid").text()); // work
于 2012-10-09T21:40:12.017 に答える