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>