NHK番組「プロジェクトX 挑戦者たち」の、2ちゃんねる内ガンダムパロディ記事スレッド「プロジェクトX 〜技術士官達」まとめサイト
普段自分はMac OS X用の2ちゃんねるブラウザ「Cocomonar」を使っていますが、他の2ちゃんねるブラウザをお使いの方もそうでしょうが、アンカー(>>1など)にマウスカーソルを置くと該当の記事がポップアップするのに慣れると、HTMLでの記事の閲覧が苦痛でしょうがない時があるのです。そんなわけでこの「displayResponse.js」を作りました。
ただ先に言っておきますが、スクリプトの半分がたはパクリです。「+ JavaScript の質問用スレッド + 過去ログ」というサイトで使っている、同様の機能のスクリプトをかっぱらってきました。心当たりのある方、正直スマン。
ただ、作りっぱなしでは、これから時間が経っていざもう一度このスクリプトを使おうと思った時に、たぶん設定すべき部分というものが俺の記憶力だと訳分かんなくなっていると思うんです。そこでここにこのスクリプトの詳細をメモしておきます。
開発はmi(ミミカキエディット)で行い、Camino 1.0 for Macintoshで動作確認を行いました。スクリプトが組み上がった後にInternetExplorer 6 for Windows、Safari for Macintosh、Opera 6 for Macintoshで確認して、微調整をしています。試してないけどWin版OperaやWin版Firefox、Unix版Konquerorなんかでも動くでしょう。たぶん。残念ながらInternetExplorer 6 for Macintoshでは動かなかったのですが、どうせMicrosoftのサポートも終了しているブラウザだし、javascriptが動かない環境の人のために<a href="#A1">などのようにアンカーを入れてあるので、実用上問題ないとして放置しました。それとjavascriptにDocument Object Model (DOM)の技術を用いているので、当然ながらDOMに対応していないブラウザでは動きません。具体的には"document.getElementById"が使えるブラウザのみでスクリプトが動くようにし、それ以外はハネています。Netscape Communicator 4.7とか、そういう古いブラウザはサポートしません。当然ながらテキストブラウザもサポートしませんし、携帯電話、モバイルなどのブラウザもサポートしません。つーかどうせ読む人いないだろうし。
(あの音楽)
宇宙世紀0058年 サイド3の男達はスペースノイドの自治権をもとめて立ち上がります
その中心的人物だったジオン・ズム・ダイクンはコントリズムを提唱。各サイドの国家主義。ここに
エレズム+サイドズムの思想(サイド国家主義)がドッキングします。
そしてサイド3で「ジオン共和国」を建国させます。
しかし連邦の経済的・軍事的圧力により経済も苦しくなっていきます。
ですがスペースノイドの自治のために男達はある賭けをします。
プロジェクトX ーガンヲタ達ー この後すぐです
switchA=false;
switchDIV=false;
function hideResponse(obj){
if(document.getElementById){ // Browser limitation
if(obj.nodeName=="A"){switchA=false;}
if(obj.nodeName=="DIV"){switchDIV=false;}
if((switchA==false)&&(switchDIV==false)){
var p = document.getElementById('pop');
p.style.display = "none";
p.style.visibility = "hidden";
}
}
}
function displayResponse(){
if(document.getElementById){ // Browser limitation
if(displayResponse.arguments[0].nodeName=="DIV"){
var p = document.getElementById('pop');
p.style.display = "block";
p.style.visibility = "visible";
switchDIV = true;
}
if(displayResponse.arguments[0].nodeName=="A"){
var arg = new Array();
arg = displayResponse.arguments;
var str = "";
for(var i=2;i300){p.style.height="300px";}
if (db.scrollTop+arg[1].clientY-30+p.offsetHeight > db.clientHeight+db.scrollTop){
p.style.top = db.clientHeight+db.scrollTop-p.offsetHeight-20+"px";
}else{
p.style.top = db.scrollTop+arg[1].clientY-30+"px";
}
p.style.visibility = "visible";
switchA=true;
}
}
}
まずこのスクリプトでは、if構文内で"document.getElementById"というメソッドが使えるかどうかを判定する事で、対応していないブラウザを排除しています。
次に参照ボックスを表示するか表示しないかの判定のために"switchA"と"switchDIV"というグローバル変数を用意し、その中にtrueまたはfalseの値を入れてスイッチにすることにより、マウスカーソルがどのオブジェクトの上にあるかを間接的に把握して表示を変えています。
その変数スイッチの切り替えは、HTML内のA要素に書いたonmouseover、onmouseoutイベントによって行っています。アンカー一つひとつに似たような記述を繰り返しているので、スマートなやり方であるとはとても思えませんが、2ちゃんねるでの書き込みにあるアンカー文字が必ずしも>>1のような様式に則っていない以上(ひどい場合「》603」のような例がある)、手作業での調整もやむなしということでA要素に直接記述する形にしました。このほうがどのような書き方にも対応できるので、まとめサイト制作者にとっては手間がかかりますが、閲覧者にとってはありがたいものだと思います。もちろんjavascript側での正規表現の検索置換を使えば、自動的なonmouseoverを書く事はできますが、まずは判りやすさを優先しました。
onmouseoverイベントに記述するdisplayResponse関数の引数は、カンマで区切ればいくつでも書けるようにしました。これは>>1-10のように範囲指定しているときに役立つはずです。なお引数の1番目のthisは固定で、イベントが発生したHTML要素の種類によってswitchA変数かswitchDIV変数のどちらを設定するかの判定などに使っています。2番目のeventも固定で、参照ボックスの表示座標の決定に使っています。3番目からの数字が参照レス番号で、該当の参照レスを囲んでいるDIV要素のIDの決定に使っています。
onmouseoutイベントに記述するhideResponse関数の引数はthis固定で、displayResponse関数と同じく、switchA変数とswitchDIV変数のどちらを設定するかの判定に使っています。
hideResponse関数の仕事は、switchA変数とswitchDIV変数を設定した上で、条件分岐により参照ボックスを隠す事です。switchA変数とswitchDIV変数の両方がfalse(つまり両方からマウスカーソルが離れている)のときに、CSSのvisibleとdisplay両方で隠しています。両方を使っている理由は、displayResponse関数の説明で行います。
displayResponse関数の仕事は、switchA変数とswitchDIV変数を設定した上で、条件分岐により参照ボックスを表示し、または参照ボックスを表示しつつ内容を書き換える事です。動作を分けた理由は、A要素からDIV要素にマウスを移動した場合に参照ボックスの中身を再描画する手間を省くためです。このためチラツキを押さえることができました。
displayResponse関数内での描画部分は、A要素からイベントが呼ばれた場合のみ行うようにしていますが、この際にCSSのdisplayプロパティを先に"block"にして、描画を行った後にvisibilityプロパティをvisibleにしています。これは描画中や参照ボックスの移動中の画面のチラツキを押さえるためで、このためそれほどストレスを感じない表示になっています。
onmouseoverイベントの説明でも書きましたが、>>1-10のように範囲指定する場合には"displayResponse(this,event,1,2,3,4,5,6,7,8,9,10);"のように該当する記事を全部書けば済むようになっています。これはdisplayResponse関数のプロパティであるargumentsによって取得可能です。
なお、記事を囲むDIVや参照ボックスのDIVのIDを変更する場合、このスクリプト内の"var p = document.getElementById('pop');"や"str += document.getElementById('res'+arg[i]).innerHTML;"の該当する部分も変更してください。
参照ボックスはクリックしたアンカー付近(正確にはマウスカーソル)を基準に移動されます。これにより参照をスムーズに行えるのですが、この部分は前述のサイトに使用されているスクリプトから借用している部分です。
いじってみてわかると思うのですが、レスの参照記事内でさらにアンカーがあってそれにマウスカーソルを重ねると、元の参照ボックスが消えてその先の参照ボックスに置き換わるだけになっています。これをできれば複数のボックスが入れ子になるようにしたいところです。しかもマウスカーソルの位置判定がシビアで、参照記事内のアンカーがとても使いづらくなっています。
それとこのスクリプトを使うには、2ちゃんねるでの生ログのままでは使う事ができず、エディタでの正規表現などを駆使してソースを整形しなければいけません。このサイトはHTML4.01でのWeb標準に準拠しているため、どうせ整形しなければいけなかったので問題ないですが、生ログをそのまま保存しているサイトなどでの汎用性に欠けるという問題があります。このスクリプトの元を持ってきたサイトではそのへんの問題をクリアしているので、そちらを使えばいいとも思いますが、できれば自分の手で汎用性も高いものを作り上げてみたいという欲求があります。
上の2点の問題点を解決するには、javascriptでのソースのリアルタイム置き換え、DOMによる参照記事ボックスの描画をやるべきだと思うんです。ただわかっていてもスキルが追いつかないと言うか、根気が続かないと言うか、とりあえず現状で動いているのでとりあえずは満足しています。ぶっちゃけ自分が見るのに欲しいから作っただけだしぃ〜。
このスクリプトを使うためには、2ちゃんねるで配信されているHTMLソースを改変しなければ使うことができません。改変するには「正規表現」での検索・置換を行うと便利です。というより、事実上正規表現を使わなければできません。以下の表で正規表現を使ってHTMLソースを改変する方法を述べます。
| No. | 検索文字列 | 置換文字列 |
|---|---|---|
| 1 | <dt>{[0-9]+} 名前:<a href="mailto:{.*?}"><[bB]> {.*?} </[bB]></a> 投稿日: {.*?} ID:{.*?}<br><dd> | </p><dl><dt>番号: </dt><dd class="h_num">¥1</dd><dt>名前: </dt><dd class="h_name">¥3</dd><dt>Mail: </dt><dd class="h_mail">¥2</dd><dt>投稿日: </dt><dd class="h_date">¥4</dd><dt>ID: </dt><dd class="h_id">¥5</dd></dl><p> |
| 2 | <dt>{[0-9]+} 名前:<font color=".*?"><[bB]> {.*?} </[bB]></font> 投稿日: {.*?} ID:{.*?}<br><dd> | </p><dl><dt>番号: </dt><dd class="h_num">¥1</dd><dt>名前: </dt><dd class="h_name">¥2</dd><dt>Mail: </dt><dd class="h_mail"></dd><dt>投稿日: </dt><dd class="h_date">¥3</dd><dt>ID: </dt><dd class="h_id">¥4</dd></dl><p> |
| 3 | <dt>Mail: </dt><dd class="h_mail">{.*?sage.*?}</dd> | <dt><img src="../common/sage.png" width="20" height="20" alt="sage">Mail: </dt><dd class="h_mail">¥1</dd> |
| 4 | <dt>Mail: </dt><dd class="h_mail">{.*?}</dd> | <dt><img src="../common/age.png" width="20" height="20" alt="sage">Mail: </dt><dd class="h_mail">¥1</dd> |
| 5 | <a href="¥.¥./test/read¥.cgi.*?" target="_blank">>>{[0-9]+}</a> | >>¥1 |
| 6 | <dd class="h_name">{[>]*}{[0-9]+}</dd> | <dd class="h_name">¥1<a href="#A¥2" onmouseover="displayResponse(this,¥2);">¥2</a></dd> |
| 7 | {>[>]*}{[0-9]+} | <a href="#A¥2" onmouseover="displayResponse(this,¥2);">¥1¥2</a> |
| 8 | <dl><dt>番号: </dt><dd class="h_num">{[0-9]+}</dd> | </div>¥r<div id="res¥1"><a name="A¥1"></a><dl class="f12"><dt class="h_num">番号: </dt><dd class="h_num">¥1</dd> |
| 9 | <{[pdl]+}> | <¥1 class="f12"> |
| 10 | <dd class="h_name">{[0-9]+}</dd> | <a href="#A1" onmouseover="displayResponse(this,1);">¥1</a> |
| 11 | <a href="http://ime¥.nu/{.*?}" target="_blank"> | <a href="http://¥1"> |
| 12 | </*[bB]> |
| No. | 検索文字列 | 置換文字列 |
|---|---|---|
| 1 | <dt>{[0-9]+} :<a href="mailto:{.*?}"><[bB]>{.*?}</[bB]></a>:{.*?} ID:{.*?}<dd> | </p><dl><dt>番号: </dt><dd class="h_num">¥1</dd><dt>名前: </dt><dd class="h_name">¥3</dd><dt>Mail: </dt><dd class="h_mail">¥2</dd><dt>投稿日: </dt><dd class="h_date">¥4</dd><dt>ID: </dt><dd class="h_id">¥5</dd></dl><p> |
| 2 | <dt>{[0-9]+} :<font color=.*?><[bB]>{.*?}</[bB]></font>:{.*?} ID:{.*?}<dd> | </p><dl><dt>番号: </dt><dd class="h_num">¥1</dd><dt>名前: </dt><dd class="h_name">¥2</dd><dt>Mail: </dt><dd class="h_mail"></dd><dt>投稿日: </dt><dd class="h_date">¥3</dd><dt>ID: </dt><dd class="h_id">¥4</dd></dl><p> |
| 3 | <dt>Mail: </dt><dd class="h_mail">{.*?sage.*?}</dd> | <dt><img src="../common/sage.png" width="20" height="20" alt="sage">Mail: </dt><dd class="h_mail">¥1</dd> |
| 4 | <dt>Mail: </dt><dd class="h_mail">{.*?}</dd> | <dt><img src="../common/age.png" width="20" height="20" alt="sage">Mail: </dt><dd class="h_mail">¥1</dd> |
| 5 | <a href="¥.¥./test/read¥.cgi.*?" target="_blank">>>{[0-9]+}</a> | >>¥1 |
| 6 | <dd class="h_name">{[>]*}{[0-9]+}</dd> | <dd class="h_name">¥1<a href="#A¥2" onmouseover="displayResponse(this,¥2);">¥2</a></dd> |
| 7 | {>[>]*}{[0-9]+} | <a href="#A¥2" onmouseover="displayResponse(this,¥2);">¥1¥2</a> |
| 8 | <dl><dt>番号: </dt><dd class="h_num">{[0-9]+}</dd> | </div>¥r<div id="res¥1"><a name="A¥1"></a><dl class="f12"><dt class="h_num">番号: </dt><dd class="h_num">¥1</dd> |
| 9 | <{[pdl]+}> | <¥1 class="f12"> |
| 10 | <dd class="h_name">{[0-9]+}</dd> | <a href="#A1" onmouseover="displayResponse(this,1);">¥1</a> |
| 11 | <a href="http://ime¥.nu/{.*?}" target="_blank"> | <a href="http://¥1"> |
| 12 | </*[bB]> |
なお、上記の正規表現による検索・置換表は、Jedit向けに作られています。Jeditでは文字列の参照を{ }(中括弧)で行い、参照文字列の代入を¥(円マークまたはバックスラッシュ)で行います。しかし普通のエディタでは参照を( )(括弧)で行い、参照文字列の代入を$(ドル記号)で行っているはずです。Jedit以外のエディタで検索・置換を行ったりする場合は、適宜修正して使用してください。
このように正規表現での検索・置換を行っても、アーティクルへのアンカーを全角文字で行っている場合や、その他自分勝手な方法で書かれているアーティクルもあるかもしれません。正規表現での検索・置換を行ったからそれでよいとは考えず、必ずHTMLソースファイルを全て見直しながら手で修正を行うようにしてください。
annie gary p@yahoo co jp メールアドレスの間違いには充分お気を付けの上、ご送信ください。