Stringクラスに対する拡張(2)

evalScriptsメソッド

【抜粋】
  evalScripts: function() {
    return this.extractScripts().map(eval);
  },

文字列(this)から、前述extractScriptsメソッドで取得したscriptコードすべてを、eval関数で実行しています。

要素のinnerHTMLプロパティへソースを設定すると、タグ等が評価されて表示されますが、scriptブロックは実行されません。これを実行させるのにevalScriptsメソッドが役に立ちます。

【例】
<html>
<head>
<title></title>
<script language="javascript" src="prototype.js" charset="utf-8"></script>
<script language="javascript">
<!--
function load(){
  var str = "<div id='msg'>none<\/div>"
          + "<script>$('msg').innerHTML = 'hello!';<\/script>";
  $('box').innerHTML = str; //この時点では'none'と表示される。
  str.evalScripts(); //scriptブロックが実行され、'hello!'が表示される。
}
//-->
</script>
</head>
<body>
<div id="box"></div>
<button onclick="load();">LOAD</button>
</body>
</html>

str.evalScripts();をコメントアウトすると、'none'が表示されます。

Operaでのバグ (2006/08/02追記 )

evalScriptsメソッドはOperaでエラーとなるバグがあります。eval関数を引数として渡すことに問題があるそうです。v1.5.0_rc0では改善されています。

【参考URL】Hawk's Laboratory » prototype.js 1.4.0を読む:string.js
【参考】v1.5.0_rc0
  evalScripts: function() {
    return this.extractScripts().map(function(script) { return eval(script) });
  },

escapeHTMLメソッド

【抜粋】
  escapeHTML: function() {
    var div = document.createElement('div');
    var text = document.createTextNode(this);
    div.appendChild(text);
    return div.innerHTML;
  },

文字列(this)のHTML文字をエスケープして返却します。つまり「<p>text</p>」という文字列を「&lt;p&gt;text&lt;/p&gt;」に変換します。このやり方は知らなかったです。div要素のテキストノードに文字列を設定すると、innerHTMLでエスケープした文字列が得られるんですね・・・。*1

【例】
alert("<p>text</p>".escapeHTML());
//「&lt;p&gt;text&lt;/p&gt;」と表示される。

unescapeHTMLメソッド

【抜粋】
  unescapeHTML: function() {
    var div = document.createElement('div');
    div.innerHTML = this.stripTags();
    return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
  },

escapeHTMLメソッドの逆。文字列(this)のタグを取り除いた上で、アンエスケープして返却します。innerHTMLに入れる前にstripTagsメソッドでタグを取り除いているのは、ワーク用div要素の子要素を一つだけにするためです。これによりdiv.childNodes[0].nodeValueでアンエスケープした文字列を取得することができます。

【例】
alert("\<p\>&lt;test</p>".unescapeHTML());
//'<test'と表示される

*1:以前、ワークとして作成したdiv要素を消したほうがよいような気がしていたのですが、bodyにappendChildしているわけでもないので、メソッド実行終了後にガベージコレクトの対象になりそうですね。