• ベストアンサー

変数に入っているHTMLから特定のidのDIVの範囲を取得したい

変数に入っているHTMLから 特定のidのDIVから、そのDIV閉じまでを取得したいのですが、 良い方法が思いつきません・・・。 ***.getElementsById(***);は、変数には使えないようですし・・・ かといって、変数の内容を、表示されているHTMLにぶちこんでから document.body.getElementsById(***);するのも気がすすみません・・・。 繰り返しと、正規表現のマッチを使って、 目的の<div="***">までの回数とその文字位置をかぞえ、 同じ回数目の</div>の文字位置を調べ、 切り取るというのも考えましたが、それは考えがあまかったようで・・・うまくいきませんでした。 例えば・・・bodyというidのDIVを取得したいとして・・・ 次のようなソースだとすると、あたりまえですけどうまくいきません。 <div id="body"> <div id="a"> テスト1 </div> <div id="b"> テスト2 </div> </div> <div id="footer"> テスト3 </div> 何か良い方法がありませんでしょうか・・・。 みなさんのお知恵をお貸し下さい。どうかよろしく御願いします。

質問者が選んだベストアンサー

  • ベストアンサー
noname#84373
noname#84373
回答No.3

こういうやり方が正しいかどうかわかりませんが。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <title>Test</title> <body> <script> var n; var ht='<div><div id="boody"><h3>abc</h3><p>abcdef</p></div><div>fghj</div></div>'; var node = document.createElement('DIV'); node.innerHTML = ht; if( n = getNodeById( node, 'boody' ) ) alert( n.innerHTML ); function getNodeById( node, nid ){ var r = node; while( r = getNextNode( r ) ) if( r.id == nid ) break; return r; } function getNextNode( node ){ if( !node ) return null; if( node.hasChildNodes() ) return node.firstChild; if( node.nextSibling ) return node.nextSibling; return getNextNode( node.parentNode ); } </script>

masapiyochan
質問者

お礼

ありがとうございます。 私も正しいか正しく無いかはわかりませんが、 _pipi_さんがご回答いただいたもので、十分いけそうです。 ありがとうございました。

masapiyochan
質問者

補足

すみません。Firefoxで・・・それ単体では動作するのですが、 私が書いたソースに組み込むと、うまく動かなくなります。 (いつまでもループになってしまいます。) 指定回数でループから抜けるようにしてみたところ、結果がundefinedになっていました。 GoogleChromeなどではごく正常に動作したようです・・・。 何か、そうなってしまう理由として思い当たるようなことがあったら、教えていただけるとありがたいです。

その他の回答 (5)

  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.6

修正だけですが function getNodeById(n, nid){ return n ? n.id == nid ? n : getNodeById(n.nextSibling, nid) || getNodeById(n.firstChild, nid) : null; } #4 TEXT_NODE → non child & non nextSiblng → parentNode → childNode(TEXT_NODE) → non child & non nextSiblng → ...

masapiyochan
質問者

お礼

ありがとうございます!! 今のところ、yuu_xさんのもので正常に動いているようです。 感謝です。

noname#84373
noname#84373
回答No.5

役に立てないね~;_; bodyに追加してみて正常に機能するか? するのならば、display:hidden;のオブジェクトに追加して にごす。 もしくは、ハイレベルの人の回答を得るため、新たに立ち上げる。 もしくは、HTMLの中にidをふって、getNodeByIdの関数の中にr.idを表示させてすべてチェックする もしくは、id="body"をやめる^^; あぁ~ なんもいえねぇ~;_;

masapiyochan
質問者

お礼

返信が遅れましてすみませんでした。 今のところ、yuu_xさんの回答で成功しましたが、 こんな質問に付き合っていただいた_pipi_さんにも本当に感謝しております。 本当にありがとうございました。

noname#84373
noname#84373
回答No.4

変数のなかのHTML構造がおかしいとか・・・。

masapiyochan
質問者

お礼

HTMLが特におかしいような気はしないのですが・・・。 試してみた所、InternetExplorer7と、GoogleChromeでは正常で、 FirefoxとOperaでは無限ループになってしまいました... 謎です・・・。

masapiyochan
質問者

補足

Firefoxでは、Firebugに。 GoogleChromeでは標準搭載の、デバッグ(JavaScript Debugger)に console.logで、ログを出力させてみたのですが・・・。 GoogleChromeでは次のように出ました。 "[object HTMLDivElement]," source: http://localhost:8080/ (0) "[object Text]," source: http://localhost:8080/ (0) "[object HTMLDivElement]," source: http://localhost:8080/ (0) しかし、FirefoxのFirebugでは・・・ <div> "\n\n" <title> "ページ1" "ページ1" "ページ1" ... のようになってしまっています。 その目的のHTMLに記述された<h1>ページ1</h1>というタグだと思います。 ログは、以後、ずっと、"ページ1"になってしまっています。 スクリプトのgetNodeByIdは次のようにしました。 function getNodeById( node, nid ){ var r = node; count = 0; console.log(r); while(count <= 60){ count = count + 1; r = getNextNode( r ); console.log(r); if( r.id == nid ){ break; } } return r; } 何か、わかりませんでしょうか。

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.2

変数に入っているのはただの文字列なので、その内容がHTML形式だったとしても、HTMLとして認識されることはないでしょう。 基本的には、文字列処理でやるのが正論では? 正規表現は苦手なのですが、ご提示のソース程度に限定したら… window.onload = function(){ var hoge = document.getElementsByTagName('body')[0].innerHTML; var fuga = hoge.match(/<div id="?body"?>[^<]*((<div[^>]*>[^<]*(<[^d][^>]*>[^<]*)*<[/]div>)*[^<]*)*<[/]div>/i); alert("[[ body ]]\n" + hoge + "\n\n[[ match ]]\n" + (fuga?fuga[0]:'no match')); } 簡略化しているので、<div>がさらにネストしていたり、dで始まる<dt><dl>タグなどがあると↑では検出できません。 (もっと、きちんと表現する必要がありますが、苦手なもので…) 実際には、<div id="body">が、<div id='body'>だったり、<div id="body" >(スペースが多い)とかも考えていくと面倒ですね。 あとは、質問者様がすでに書かれていますが、HTMLに吐き出しておいてドキュメントとして扱う方法くらいでしょうか? window.onload = function(){ var hoge = document.getElementsByTagName('body')[0].innerHTML; var fuga = document.createElement('div'); fuga.style.display = 'none'; fuga.innerHTML = hoge.replace('body','bady'); document.body.appendChild(fuga); fuge = document.getElementById('bady'); alert("[[ body ]]\n" + hoge + "\n\n[[ match ]]\n" + fuge.innerHTML); document.body.removeChild(fuga); } 同じものを書くので、↑では、後のものはidをbadyに変えています。実際には同じものを2重書きするわけではないでしょうが、それでもidの一意性が損なわれる可能性は高いですね。 これだと通常のHTMLの扱いにできるので、DOMで扱えますね。 idの重複を避けるためにはiframeでも使うのかなぁ…

masapiyochan
質問者

お礼

ありがとうございます。 やはり、変数はただの文字列ですよね^^; 結局、HTMLに一時的に吐き出すほうが、一番使えそうですね・・・。

  • t_netbug
  • ベストアンサー率34% (15/44)
回答No.1

var div = document.getElementById('body'); child_div = div.getElementsByTagName('div'); for(i=0;i<child_div.length;i++){ alert(child_div.item(i).id); } こういう事じゃなくてですか? いまいち、何が分からないのかが分かりません^^;

masapiyochan
質問者

お礼

すみません。うまく動かないのですが・・・ getElementByIdや、getElementsByTagNameは、変数に対しても使えるのですか??

関連するQ&A