メモを揉め

お勉強の覚書。

evaluable-tagというnpmモジュールを作った

htmlの中の任意の要素のdata-eval属性の値をJavaScriptとして実行するだけのモジュールです。

npm: evaluable-tag

インストール

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]

  • 引数

    • qs: string
      実行したいdata-eval属性を持つ要素のCSSセレクタ
  • 戻り値

    • [res]: array
      • res.result: any
        data-eval属性を評価した結果。
      • res.annotation: HTMLElement
        評価されるdata-eval属性を持つ要素。
      • res.annotated: HTMLElement
        ET.evalByではres.annotationと同じ要素を指す。

html

<span class="et" data-eval="1 + 2">sum</span>

javascript

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

  • 引数

    • qs: string
      実行したいdata-eval属性を持つ要素のCSSセレクタ
  • 戻り値

    • [res]: array
      • res.result: any
        data-eval属性を評価した結果。
      • res.annotation: HTMLElement
        評価されるdata-eval属性を持つ要素。
      • res.annotated: HTMLElement
        res.annotationの次に来る兄弟関係のHTMLElement
        見つからない場合はnullになる。

html

<span class="et-a" data-eval="1 + 2">sum</span>
<div>content</div>

javascript

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のデモではカラースキームのCSSevaluable-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>