evaluable-tagというnpmモジュールを作った
htmlの中の任意の要素のdata-eval
属性の値をJavaScriptとして実行するだけのモジュールです。
インストール
Nodeがあってnpmが使える場合は、
npm install evaluable-tag
npmがない場合はgithub: evaluable-tagからダウンロード。
使い方
ブラウザの場合
browser/et.js
を読み込む。
<script src="browser/et.js"></script> <script> var ET = require('evaluable-tag'); </script>
Browserifyの場合
require
で読み込む。
var ET = require('evaluable-tag');
メソッド
ET.evalBy(qs) -> [res]
引数
戻り値
- [res]: array
- res.result: any
data-eval
属性を評価した結果。 - res.annotation: HTMLElement
評価されるdata-eval
属性を持つ要素。 - res.annotated: HTMLElement
ET.evalBy
ではres.annotation
と同じ要素を指す。
- res.result: any
- [res]: array
html
<span class="et" data-eval="1 + 2">sum</span>
var evaluated = ET.evalBy('.et'); var et = evaluated[0]; console.log(et.result); // 3 console.log(et.annotation.textContent); // sum console.log(et.annotated.textContent); // sum
ET.evalAnnotationsBy
引数
戻り値
- [res]: array
- res.result: any
data-eval
属性を評価した結果。 - res.annotation: HTMLElement
評価されるdata-eval
属性を持つ要素。 - res.annotated: HTMLElement
res.annotation
の次に来る兄弟関係のHTMLElement
。
見つからない場合はnull
になる。
- res.result: any
- [res]: array
html
<span class="et-a" data-eval="1 + 2">sum</span> <div>content</div>
var annotated = ET.evalAnnotationsBy('.et-a'); var et = annotated[0]; console.log(et.result); // 3 console.log(et.annotation.textContent); // sum console.log(et.annotated.textContent); // content
ET.evalAnnotationsBy
が実行されるとdata-eval
属性を持つ要素は不可視な状態になる。
上の例だと、span.et-a
が見えなくなる。
用途
ある意味バッドノウハウの塊です。
特定の投稿のみで実行したいスクリプトをこれで実行しています。
本来はHTML、Markdownで<script>
タグが使えればいいのですが普通は削除されます。というか、色々問題があるから削除されるのだろうからこういうやり方は良くないんだろうけど、ありますよね、スクリプト使いたいこと。
例えばRoomMirrorのデモではカラースキームのCSSをevaluable-tag
で後から読み込んでいます。
記事が含まれるページの時のみスクリプトが走ってCSSが読み込まれます。
<p class="et" data-eval="(function(){ var link = document.createElement('link'); link.setAttribute('rel', 'stylesheet'); var themes = [ 'monokai', 'solarized', 'default', 'ibdknox', 'zenburn', 'paraiso-dark', 'pastel-on-dark', 'the-matrix', 'vibrant-ink' ]; themes.forEach(function(theme) { var l = link.cloneNode(); l.setAttribute('href', 'path/to/theme/' + theme + '.css'); document.head.appendChild(l); }); })()"></p>