妄想していたgetElementsByAttribute()って、XULのDOM拡張で存在したんだ……。属性でNodeListを取得できるんなら欲しい。DOMでもあったら便利だろうに(無関係)。
本題。ウェブサイトの構成をツリー状に整理して、サイトマップの生成に再利用するという方法は、どうもイマイチ。
link要素のrel属性にsite mapというのがあって、href属性にサイト構造を記したファイルのURIを記述しておけば、Mozillaのサイドバーのような手段でブラウザがサイトマップを提供してくれる、というのが理想。これを念頭に置きつつ。
DOMとJavaScriptでこういうことを実現するため、実験的にサイトマップを生成していたが、なにやら行き詰まってしまったので、シンプルなモデルを使って考え直してみることにした。余計な要素がからんでいると、頭がこんがらがってアイデアが具現化しない。
// 連想配列にサイト構造を収める
var WebSite = new function(){
this.title = 'site name';
this.uri = './';
this.contents1 = new function(){
this.title = 'contents1 title';
this.uri = 'contents1.html';
};
this.contents2 = new function(){
this.title = 'contents2 title';
this.uri = 'contents2.html';
};
this.contennts3 = new function(){
this.title = 'contents3 title';
this.uri = 'contents3.html';
this.contents1 = new function(){
this.title = 'contents1_3 title';
this.uri = 'contents1_3.html';
};
this.contents2 = new function(){
this.title = 'contents2_3 title';
this.uri = 'contents2_3.html';
this.contents1 = new function(){
this.title = 'contents1_2_3 title';
this.uri = 'contents1_2_3.html';
};
};
};
this.contents4 = new function(){
this.title = 'contents4 title';
this.uri = 'contents3.html';
};
};
// サイト構造をツリー状のリストにする関数
function createSiteMap(obj_argument){
var nUL = document.createElement('UL');
var parent = (!obj_argument) ? document.body : nLI;
parent.appendChild(nUL);
var object = (!obj_argument) ? WebSite : obj_argument;
for(var member in object){
if(member == 'title') continue;
if(member == 'uri') continue;
nLI = document.createElement('LI'); // var 無し。
nUL.appendChild(nLI);
var nA = document.createElement('A');
nA.href = object[member].uri;
nLI.appendChild(nA);
var nText = document.createTextNode(object[member].title);
nA.appendChild(nText);
createSiteMap(object[member]);
}
}
サンプル
ああ、とうとうできたか。そうだよなあ……。このシンプルなモデルで考えても1時間かかったというのに、例外やら、現在地表示やら、色々なことを考えなきゃならなかったわけで、私の頭で整理がつくわけが無かった。
今日の教訓。まずはシンプルなモデルで試すべし。
問題は、後で自分で作ったスクリプトを見て、すんなり理解できるかどうかだ……。なんにせよ、後々これを拡張していかなければいけないからこれは大問題。寝る前に細かく説明を書いておこう。
これと、CSS切り替え等をうまく組み合わせて何か……とか、拡張性がなければ、frameには勝てない。現在地表示だけじゃなぁ……。打倒frame!
各ブラウザのobject要素に関するバグが取れるまで待つというのも手。
闇黒日記(平成13年10月8日)のネタを拡張。
*[style]{ display:none !important; }
/* style属性は邪道 */
table{ display:none !important; }
table[summary]{ display:table; }
/* summary属性のないtableは不可 */
font{ visibility:hidden !important; }
a[href],a[name]{ visibility:visible !important; }
a{ visibility:hidden !important; }
/* href,name属性のないa要素に価値はない */
img{ visibility:hidden !important; }
img[alt]{ visibility:visible !important; }
/* alt属性のないimg要素は写す価値なし */
form{ display:none !important; }
form[action]{ display:block !important; }
/* Netscape Navigator対策は邪道 */
きちんと仕上げたら、何かに使えないだろうか。少なくともこれ、IEでは使えない。
日本のライブラリ ホームページでは、「ダイナミックHTML」と「ドキュメントオブジェクトモデル」がごっちゃになっていて解説も雑だ。情報も古い。4年前のまま(?)。本家の方は、整然と分けてあるし(standard information)情報も新しい。
で、MSDN Library (英語)を彷徨っていたらdocument.compatModeなるプロパティを発見。IE6以降の標準準拠モードのスイッチが入っている場合、[string]CSS1Compat、入っていなければ[string]BackCompat。Read Only。書けないでどうする……。XML宣言のあるXHTML文書も標準準拠モードで解釈して欲しい時、読めるだけじゃあ……。IE5/6の簡単な判別手段にはなる。しかし個人的には面倒でもdocument.implementation.hasFeature('HTML', '1.0')で判別したい。
ユーザーにCSSファイルの絶対URIを入力してもらい、それを適用させるというスクリプトを適当に作ってみた。ところが、Mozillaの場合、新たに生成したlink要素が、document.styleSheetsに含まれない。生成が済んでから参照しているのだけど。仕様書みても良く分からない。こういうときは、for(var i in document.styleSheets){..}。なんか見つかるだろう。見つからなかった。
これから(@深夜)少し試してみようと思っているもの。
どちらもIEで動くものはUser-Javascriptのソースに。これをウェブサイトで使うものにしようとすると、作業量が2倍(もしくはそれ以上)に増える。JSファイルも既存のものに加えると相当にでかくなるから、トップページでだけ切り替えられるようし、外部JSはクッキー関連の処理だけに特化してみると良いかも知れない。
テーブルに限らず、枠を破壊するのは快感。壊れた(壊した)やふーの画像(20kb)。W3C (英語)はさすが、テーブルを壊しても違和感がなかった。
歳が若いことを表す「弱冠」と数量が少ないことを表す「若干」の使い分けは大事ですネ。
Latest topics - outsider reflex より
そういえば幼い頃、駅のアルバイト募集の張り紙に「若干名募集」と書かれていて、へぇ、若い人千人も要るんだ凄いな、と二重にも三重にも間違っていたっけなあ、ははは、馬鹿だったよなあ、とか思って見ていた。
しばらくして、事実上これはウチへの突っ込みになってることに気づく……。すぐに直しました。
……とネタ風に書いてみましたが、ともかく助かりました。piroさんありがとうございます。
今回はフレームを使用して各項目のアクセスのしやすさを向上させてみました。前回の行ったり来たりの煩わしさと、イラストを見る場合ではそれぞれ新規ウィンドウを開くようにしてあったため、バグブラウザ等を使用しない場合デスクトップが大変なことになってしまうことを避けたかったからです。
ハイパーリンクが一つも無い、フレームの欠片。お陰でGoogleのキャシュからの引用となった(最新版は内容が異なる)。私にはなんのサイトだかもよく分からないのですが、アクセスのしやすさ
は向上したと言えますかね。
問題点としては、フレーム否定派閥の存在、某所でチクリと言われたのですが、そういう方には「見ない権利」をあげますので、イチイチ来て腹立てんといて下さいとしておきます。
その「フレーム否定派閥」の方が、私と同じように「検索エンジンに引っかかったのでお邪魔しただけ」だったとしたら、イチイチ来て腹立てんといてください
というのは筋違い。そういう方には、「WWWに公開しない権利」をあげますので、イチイチ正当な批判に腹立てんといて下さいとしておきます。他にも何か「権利」をあげましょうか。
フレームがますます嫌いになった日。いや、フレームを使っているにもかかわらずよく閲覧するサイトはある。しかしどれもフレームの利点と欠点を知り尽くしたプロが作っているサイト。フレームというのは、索引が作れるほどの莫大な情報量があるときに、代替手段を用意しつつ、レイアウトに気を使いつつ、ナビゲーションの構築に注意しつつ慎重に使わなければならない。個人、しかも素人にそのようなことができるわけがない。何れにしろ、アクセスしやすくなる
ことはありません。
自分の文書を改竄するというのも凄い表現だけれども、改変または修正といっても妥当なのでは。私だって確かに文書を削除する気はありませんが、修正は頻繁にやっております。
リンクするな、というのがWWWに失礼な行為だとするなら、意図的にデッドリンクを作ることも同様だと思う、ただそれだけのことなのです。
よたろーさんの雑感の更新をいつも楽しみにしております。
今月初めに、imagesという名前のアカウントを取得し、http://members.jcom.home.ne.jp/images/ に画像を置きまくっていたが、昨日、サポートセンターから電話がかかってきた。imagesという名前のアカウントが取れたのは何かの手違いだったそうだ。なるほど。403 Forbidden とはおかしな話だとは思っていたが、そういうことだったらしい。
で、今度はbinaryという名前のアカウントを取ってみた懲りない私。
ユーザージャバスクリプトをやっと更新。ま若干訂正箇所が残っています。
CSS関係の機能に特化した方が良いものができそうな気もする。事実、スタイルシートを操作する処理だけが異常に膨れ上がっている。綺麗に書き直してファイルサイズを3分の1にしたいなどぼやいていたが、結果的に2倍になってしまった。25kb。
User-Javascriptは作品ではなくて、スキルアップのための道具。これに鍛えられたお陰でdocuemnt.styleSheetsとは随分親しくなった……。完全に楽しんでいたし。今度は、このサイトにどういう形で還元できるかを考える番だ。代替スタイルシート、DOM Level2 Style を、どう使うか。「革命的CSS」は、今からスタートです。
theadだけでなく、空のtbodyも自動的に生成されてしまう。これは絶対に覚えておかないと……。
理不尽なバグに散々悩まされてしまった。知ってれば便利なんだろうけど、innerHTMLで調べてみなかったらずっと分からないままだった気がする。どこに書いてあるんだよこれ。
でも、もう少しでCSSルール追加関数の修正が終る。一区切りまで後少しだ。
本日23時、NHK「トップランナー」にラーメンズが出演する模様。ウチでは極たまにラーメンズのネタが出てきますので、ご存知ない方はどうぞ。
ありさかさとみさんにもご迷惑おかけしまた。
HTMLファイル名がagenda.htmlの場合に例外としていたのですが、agenda.htmlを含む場合にすべきでした。
確か、前回は、object要素にURIを渡すときにクエリーが必要だったように記憶してますが、今はもう必要でもなんでもなく、完全にこちらの責任です。
さとみかんからそふぃあさんの日記に行くと、本文を隱されてしまふんですが。
mettre du noir sur du blanc(平成13年10月4日) より
早速直しました。度々ご迷惑おかけします。野嵜さん、ご指摘有難うございました。
クッキーをJavaScriptでどうやって削除するのか、これは、簡単である。ただ単に有効期限を過去の時間に設定してやればよい。
なんてのは嘘。実はこの方法は、pathが一致していなければ意味が無い。
まずはじめに、document.URLを / (スラッシュ)で分割して配列に収める。次に、1から始めてその配列の数だけクッキーに「有効期限を過去の時間に設定した値」を書き込む。pathには各配列の値を入れる。1から始めるのは、丁度配列の2番目が空の文字列になるため、pathを明示していない場合のクッキーを削除できるからである。(配列[0]にはhttp:が入っている)この要領で確実に他所のサイトのクッキーを削除できる……と、思う。しかしこれは乱暴なので、実際には深い階層のpathから順に試していき、消せた時点でループから抜けると良いかも知れない。
できないことは無いけども冗長だしベターな方法が見つかったので取り消し。ユーザーの立場に立って、にわかにクッキーに関心が沸いてきた。
ユーザーの利便性のためにあるはずのクッキーを、何故ユーザーが能動的に扱えないのか。例えば文字サイズなど、サイトによってベストな大きさはそれぞれ異なる。サイトを移動するたびに変更するより、クッキーを使って覚えておいた方が良いに決まっている。サイト管理者を罵る前に、ユーザーはブラウザ製作会社を責めるべきだ。そんなこと言っても仕方ないから、自分で何とかするわけである。
Proxomitronへの依存度を最小に抑えた。link要素はDOMで、select要素はdocument.writeで書き出すようにし、イベントはdocument.onclick に代入したので、埋め込むのは本体のスクリプトタグだけに。これで、フィルターがうまく機能しないことはほとんど無くなった。
早寝早起きをしろということか。
HP Jornada 680のPocket IEは表示が本当に遅い。tableでレイアウトされた容量大きめのサイトなんかは、受信時間よりもレンダリング時間の方が時間が掛かる。その文書全体がtableで囲まれていようものなら、画面をスクロールさせるだけで10数秒掛かったりする。オンラインでそれをやると、金が掛かってしようがない。ハッキリ言って、通信費の半分以上は無駄に払っていると思う。助けてくれ。
つーか、tableでレイアウトするのやめてくれ〜。strictなHTMLを書こうよ。
テーブルレイアウトに死を。
この引用文がログに落ちたら、テーブル否定リンク集に追加しよう。実は否定の論拠となりそうなリソースのリンク集を、半年前から構築しています。フレーム、br改行、フラッシュ、その他。テーブルレイアウトについては、説得力のあるものがなかなか見つからないんです。
Mozillaのようにクッキーを表示する関数を作った。とりあえず表示するだけだが、削除するような仕掛けも追加したい。
(今回は、outside reflexのCSS切り替えスクリプトで使用されていた、JCookieというオブジェクトを眺めていて実現したくなりました。)
で、JCookie.deleteというメソッドを追加しようとしたら、識別子がありませんと言われた。予約語か何かに引っかかったらしい。調べてみると、deleteはすでにある演算子だった。varで宣言されていないオブジェクトや、メンバーを削除することができるらしい。newの逆じゃあないか。しかし、丁度こういう処理が無いかなと探していたものに出会ったわけで、怪我の功名というヤツである。これでやりたいことがまた一歩実現に近づいた(本買へ)。
そろそろ説明のページを修正したいので、画面のキャプチャをとり始めた。米msdn library(DOM) (英語)でCSS切り替えを使ったら、なかなか壮観だったので保存しておいた。CSS切り替え画像@msdn library(15kb)
それにしてもIE6、勝手に画像を縮小してくれるのは困る。初心者にとって設定変更は藪の中だし。
バジリコスバゲティを極めるべく、何か秘技を公開している人はいないものかと、「幻 バジリコ スパゲティ」で検索。タイトル的にピッタリの文書が見つかった。
本当に幻のバジリコだった。
タナァーカ・カクウェイ(byラーメンズ)を発見。fub不具合掲示板にて。
作者氏の違う。俺が田中角栄だ。
に胸打たれる。他人のマラカスは木っ端微塵
を再確認。
書き溜めた更新状況とメモ。
disableプロパティを切り替えるという形にしてみた。色々なCSSを組み合わせるのに必要。リストには、@importでインポートされたCSSも含めたいが、できるかどうか調査中。また、クッキーを発行して適用したCSSを覚えておくようにした。splitText()が可能になったということで、検索文字列をstrong要素に再生成するとか試してみたい。それにしてもDOMで遊んでいるサイトってないものかな。クロスブラウザとか無しで。アニメーションとか無しで。ブラウザ判別はダサいっていうポリシー持っている人いないかな。
IE6がDOM1をフルサポートしているとしたら、当然これらも使えるはず。とりあえずメモ。
やってみたかったのは、そのサイトのDOCTYPE宣言をステータスバーかどこかに自動で表示するというもの。でも仕様書を見ると、HTML文書は悉くnullが返るとか。つまらないことに使おうとしてはいけません(笑)。でも考えてみると、HTML要素の外にあるノードをどうやって取得するのか。
var imp = document.implementation;
if(imp){
if(imp.hasFeature('HTML', '2.0')){
var _dom2 = true;
// DOM2サポート
} else if(imp.hasFeature('HTML', '1.0')){
var _dom1 = true;
// DOM1サポート
}
} else {
var _dom0 = true;
// DOM未サポート
}
我に勇気をアタエタマエ