【JavaScriptで】ニコ動の上でネギを振らせてみた【ふるみっく】
むしゃくしゃして(初投稿を)やった。(出来の悪さに対する)反省はしていない。
魔法の言葉:
javascript:(function(){var d=document,ti=0,tj=1,a=new Array(),ta="<span style='display:none'>",tb="</span>",tc=tb%2Bta,mt=d.createElement("span");mt.style.fontFamily = "monospace";mt.innerHTML=ta%2B"\"%2Btc%2B"("%2Btc%2B"\"%2Btc%2B"_"%2Btb%2B"( ゜△ ゜ )";function f1(p,n){if(n.firstChild)f1(n,n.firstChild);if(n.nextSibling)f1(p,n.nextSibling);if(n.nodeName=="#text"){t=n.nodeValue.replace(/初音|はちゅね|ミク|ネギ|ねぎ|、/g,"。").split("。");p.insertBefore(d.createTextNode(t.shift()),n);while(t.length){p.insertBefore(a[a.push(mt.cloneNode(true))-1],n);p.insertBefore(d.createTextNode(t.shift()),n);}p.removeChild(n);}};f1(null,d);function fs(){ti=tj;if(%2B%2Btj==4)tj=0;for(i=0;i<a.length;i%2B%2B){a[i].childNodes[ti].style.display="none";a[i].childNodes[tj].style.display="inline";}};fs();setInterval(fs, 300);})();
魔法の言葉(改造版):
javascript:(function(){var d=document,ti=0,tj=1,a=new Array(),ta="<span style='display:none'>",tb="</span>",tc=tb%2Bta,mt=d.createElement("span");mt.style.fontFamily="monospace";mt.innerHTML=ta%2B"\"%2Btc%2B"("%2Btc%2B"\"%2Btc%2B"_"%2Btb%2B"( ゜△ ゜ )";function fr(p,n){if(n.firstChild)fr(n,n.firstChild);if(n.nextSibling)fr(p,n.nextSibling);if(n.nodeName=="#text"){t=n.nodeValue.replace(/[ \t\r\n]%2B/g,"").length/10;while(t-->0)p.insertBefore(a[a.push(mt.cloneNode(true))-1],n);p.removeChild(n);}};fr(null,d);function fs(){ti=tj;if(%2B%2Btj==4)tj=0;for(i=0;i<a.length;i%2B%2B){a[i].childNodes[ti].style.display="none";a[i].childNodes[tj].style.display="inline";}};fs();setInterval(fs,300);})();
【JavaScriptで】ニコ動の上でネギを振らせてみた【ふるみっく】 - ニコニコ動画
ちなみに、この魔法の言葉はブックマークレットとして使えます。たぶん。(Firefox2は大丈夫だった。)
というか、この程度の動画仕上げるのに5時間以上かかるってどうよ? orz
以下、舞台裏。
あれ? 初投稿は電子工作ネタじゃなかったの?
始めてのニコニコ動画の投稿は、以前ネタにした「はちゅね小型化戦争」に関連した電子工作ネタでやろうかと思って、色々と準備はしてたんですが、今のところちょっとした事情で中断しちゃってます。
このJavaScriptのネタに関しては、先週JavaScriptでのネギ振りを見た時点で「ブックマークレットで出来るよなぁ……」と思いはしたのですが、「まー、誰かやってくれるよね。つか、私、JavaScriptでまともなプログラム書いたことないし」とか思って放置してました。
で、先週は仕事の関係が忙しくて、殆ど余暇時間がとれなかったので、あんまりニコニコ技術部もウォッチしてなかったんですが、先週末に見てみると、このネタを使った動画が上がってない事に気付き、ついかっとなってJavaScriptプログラミングを開始していた……と。
JavaScriptってなかなか良い言語だね
JavaScriptは、IE4とかの時代にステータスバーを書き換えて遊んでいたぐらいで*1、まともにつかったことは殆どありません。
で、リファレンスを引き引き、なんとか書いてみたのが前述のスクリプトです。
圧縮された状態では読みにくいと思いますので、以下に展開して書きます。
javascript:(function(){ var d=document,ti=0,tj=1,a=new Array(), ta="<span style='display:none'>",tb="</span>",tc=tb+ta,mt=d.createElement("span"); mt.style.fontFamily = "monospace"; mt.innerHTML=ta+"\"+tc+"("+tc+"\"+tc+"_"+tb+"( ゜△ ゜ )"; function f1(p,n){ if(n.firstChild) f1(n,n.firstChild); if(n.nextSibling) f1(p,n.nextSibling); if(n.nodeName=="#text") { t=n.nodeValue.replace(/初音|はちゅね|ミク|ネギ|ねぎ|、/g,"。").split("。"); p.insertBefore(d.createTextNode(t.shift()),n); while(t.length) { p.insertBefore(a[a.push(mt.cloneNode(true))-1],n); p.insertBefore(d.createTextNode(t.shift()),n); } p.removeChild(n); } }; f1(null,d); function fs() { ti=tj; if(++tj==4) tj=0; for(i=0;i<a.length;i++) { a[i].childNodes[ti].style.display="none"; a[i].childNodes[tj].style.display="inline"; } }; fs(); setInterval(fs, 300); })();
ざっと解説します。
f1関数はHTMLの中を巡回してテキストノードを探し、そのテキストの中から"初音","はちゅね","ミク","ネギ","ねぎ","、","。"のいずれかを見つけたら、それを変数mtとして作成しておいたHTMLエレメントと置換して、配列aに配置したHTMLエレメントを保存します。mtの中身はネギの振り全パターンをhidden状態で含んでいるspan要素です。関数fsはインターバルタイマーで300ミリ秒おきに呼び出される関数で、配列a内の各要素から、現在表示中のパターンをhiddenにして、次のパターンを表示するようにします。
ふるみっく版の方は、関数f1()内のテキストノードを見付けた時の処理が以下のようになっている以外は同じものです。
if(n.nodeName=="#text") { t=n.nodeValue.replace(/[ \t\r\n]+/g,"").length/10; while(t-->0) p.insertBefore(a[a.push(mt.cloneNode(true))-1],n); p.removeChild(n); }
こちらは、テキストノードの長さを数えて、その10分の1程度の数のmtに置き換えるものになります。実はこっちの方が単純なコードなんですよね。
できるだけシンプルで短かく仕上げたつもりなんですが、500文字をゆうに越えるコード量になってしまったので、IE6では動かないそうです(参考にしたサイト: http://www.teria.com/~koseki/memo/bookmarklets/tips.html)。 わたしの技術ではこのぐらいが限界っぽいので、これを見た誰かが完成させてくれることを期待して、私はギブアップしますw
コーディング等でハマった所
不慣れなJavaScriptコーディングで一通り罠を踏みまくったのでメモ。
SMILEVIDEO でハマった所
ただ1点。
動画の説明文には文字数制限があるので、2つのソースコードをまるごと貼ることができなかった orz
というか、もうちょっとコードが長かったら1つ貼るのも出来なかったかも……。
動画をうpした感想
めんどくせぇw
つか、もっとスマートに出来るようにならなきゃあかんな。
*1:最近はブラウザのポリシーで、ステータスバー書き換えは出来なくなってたりするんだよね