IEの開発者コンソールで見るテキストノードについて
IEの開発者コンソールで
var textNodeIterator = document.createNodeIterator( document, NodeFilter.SHOW_TEXT, function(node){ return /^\s*$/.test(node.textContent) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP; }, false); textNodeIterator.nextNode();
ってやるとコンソールにEmptyTextNode
って表示される。
あー空のテキストノードに特別に名前つけてんだーって思いました。っていうそれだけのお話。
それだけだと寂しいので少しだけ解説。
Document#createNodeIterator
でNodeIterator
っつーオブジェクトが作られる。
これはDOM Level 2で定義されたインターフェースで、ドキュメント全体から条件に一致したDOMノードを自由に取ってこれる便利なアレ。
イテレータなので、nextNode()
previousNode()
で内部のポインタが動き、逐一ポインタが指すノードを返す。
ポインタが終端・または始端にある状態でそれぞれnextNode()
previousNode()
を実行するとnull
を返す。
このインターフェースには現在のポインタに位置するノードを返すメソッド・プロパティはないので、
var currentNode;
currentNode = textNodeIterator.nextNode();
などとしないと値を保持できない。
ちなみにNodeIterator
には上記2つ以外にdetach()
を加えた3つしかメソッドが存在しない。
以下、引数について書く。
第一引数がルートノード。
ここに指定したノード、およびその子孫から条件に一致したものを抜き取る。
第二引数がどの属性のノードを持ってくるか。
ここでまた新しくNodeFilter
インターフェースが出てきたけど、ここにNodeIterator
とTreeWalker
*1で使われる定数が保持されてる。
今回はテキストノードのみが欲しかったのでNodeFilter.SHOW_TEXT
とした。
第三引数には、第一引数と第二引数の条件にマッチしたノードを引数としたコールバック関数を置く。*2
この関数の戻り値としてNodeFilter.FILTER_ACCEPT
を受け取るとそのノードはパスされ、逆にNodeFilter.FILTER_SKIP
を受け取るとそのノードは弾かれる。
他にNodeFilter.FILTER_REJECT
というのもあるが、これはNodeIterator
を使っている場合、NodeFilter.FILTER_SKIP
と同じ意味を持つ。
違いが出てくるのはTreeWalker
の場合だけど、ここでは割愛。
ちなみに、フィルタリングなんか必要ねぇよっていう場合は、第三引数はnull
でいいです。
第四引数は、エンティティ参照を文字列で置き換えるかの真偽値。だと思う。
true
にすると、例えば「♠」が「♠」に置き換えられる。たぶん。
実は試したことない。
勝手に置き換わると後々面倒だし、無難にfalse
にしとくのがいいと思う。
正規表現部分については今更説明必要ないと思うけど、一応。
/^\s*$/
の意味するところは、最初から最後まで半角スペースやタブ文字、改行コードのみになっていればマッチ。
プラスではなくアスタリスクなので0回以上の出現、つまり空文字の場合もマッチする。
これらを総合して、冒頭のコードの意味を見ると、
ドキュメント全体から、半角スペース・タブ文字・改行文字のみで構成された文字列、あるいは空文字のテキストノードをイテレータとして抽出し、イテレータの最初の1つを取り出した。
と言った感じ。
以上。
少しだけ解説のつもりが、記事の大半が解説になってしまった。
Ancia向けのCSSエディタ書きました
まだ中途半端な実装だし暇があればまだ改良するつもりだけど、ひとまず公開。
ここに置いておきます。
UserExtension for Ancia
以下のスクリプトは軽量Webブラウザ「Ancia(アンシア)」向けのものです。
公式サイト: 名称未決定 - FrontPage
特定のURLで自動的に発動するタイプ
- nicosearch.js2013/12/04
- niconicoの検索窓にサジェスト機能を付与します。
- visibleExtIcon.js2013/12/07
- リンクのURLの拡張子がスクリプトに内蔵された一覧に合致すると、そのカーソルの近くに拡張子アイコンを表示します。
- searchWiki.js2013/12/09
- サイト内検索を拡張します。
文字列を選択すると「検索」ボタンがマウスカーソルの近くに表示されます。
- サイト内検索を拡張します。
能動的に呼び出すタイプ
- userStylesheetEditor.js2013/12/19
- Ancia向けUserStyleSheetの編集に特化したエディターを提供します。
スクリプトについて
これらの一部、または全部は公式サイトでも配布されています。
ただし公式サイトのものはバージョンが古い場合があります。
Surface重量計算機
ありそうでなかったっぽい(もしかしたら検索力不足かも)ので作りました。
自分が調べたかったので、そのついでです。
FAQ
動きませんが?
あなたが使っているブラウザが古いと思います。
DOMParser と XMLSerializer
DOMParser
は覚えてるけどXMLSerializer
をしょっちゅう忘れちゃうのでメモ。
var parser, serializer; var input, output; var dom; input = '<div id="test"><p>hogehoge</p></div>'; parser = new DOMParser(); try { dom = parser.parseFromString(input, "text/html").getElementById("test"); }catch(e){ dom = parser.parseFromString(input, "application/xml").documentElement; } document.body.appendChild(document.adoptNode(dom)); serializer = new XMLSerializer(); output = serializer.serializeToString(document.getElementById("test")); input === output; //==> true // IEやFxはxmlns属性が付いてfalseが返ることが稀によくある
XMLSerializer
はDOM標準ではないっぽいけどinnerHTML
よりはマシでしょ…。
速度的には、innerHTML
を参照するのに比べてseliarizeToString
を使うと3〜10倍くらい*1高速化します。
*1:ブラウザによる