Netscape Navigator 4.x での、(A 要素の name 参照でなく) ID 参照によるハイパーリンクの実現を試みる。 XHTML1.1 とかで使える、かも。
ここでは、 position 指定をした要素であれば、 N4 でも id によって要素を Layer オブジェクトとして認識可能である点を利用して、この実現を試みる。
こんな感じで動作させるような関数を作ればよいだろう。
if(location.hash){ // 現在の URI が部分識別子を持っていたら scrollToLayer( location.hash.substring(1) ); // ロケーションから取得した部分識別子を元に // その名前を ID に持つ Layer までスクロール }
このような scrollToLayer() を作れば解決できる。
同一ページ内でのリンクについては上のコードの呼出しが難しい。上で想定した scrollToLayer が作れるとしたら、それをリンクのクリックで呼出したい。
var links = document.links; for ( var i=0; i<links.length; i++ ){ if(links[i].hash && links[i].pathname==location.pathname){ links[i].onclick = scrollToLayer; } }
では、部分識別子のオブジェクトを取得してその位置までページをスクロールさせる Function を作成する。引数は部分識別子を表す文字列、またはイベントオブジェクト。
function scrollToLayer (o){ var id = (typeof o == 'object')? o.target.hash.substring(1) : String(o); if (document.layers[id]){ location.hash=id; window.scrollTo(0, document.layers[id].pageY); return false; } }
上で参照している document.layers は、実際には、 Layer オブジェクトが階層化されているため文書中の全 Layer オブジェクトを認識することが出来ない。なので、別途オブジェクトを作成し Layer を単階層にまとめなおし、上の関数ではそのオブジェクトを参照するようにする。
var lays = function layerEnum (layers, lays) { for(var i=0; i<layers.length; i++){ lays[layers[i].id] = layers[i]; layerEnum(layers[i].document.layers, lays); } return lays; } (document.layers, new Object);
勿論、 position 指定するのを忘れてはいけない。ここでは、折角なので(笑) JSS を使ってみた。 JSS にしたのは Netscape 4 以外にこのスタイルを読ませる必要が無いこと、同時に上記の JavaScript も書けてしまうことからである。
with(document.tags){ h1.position = h2.position = h3.position = h4.position = h5.position = h6.position = 'relative'; }
これで全ての見出し要素 (h1-h6) が、 Layer として認識可能になる。
では、実行してみよう。というか、このページ自体にすでに上記のコードが埋め込んであったりする。後は実際に NN4 でこのページにアクセスして、リンクを追ってみるだけだ。勿論このページのソースも見て A 要素の name 属性を使ってないことも確認して欲しい。 目次へ。
with(document.tags){ h1.position = h2.position = h3.position = h4.position = h5.position = h6.position = 'relative'; } window.onload = function () { function scrollToLayer (o){ var id = (typeof o == 'object')? o.target.hash.substring(1) : String(o); if (lays[id]){ location.hash=id; window.scrollTo(0, lays[id].pageY); return false; } } var lays = function layerEnum (layers, lays) { for(var i=0; i<layers.length; i++){ lays[layers[i].id] = layers[i]; layerEnum(layers[i].document.layers, lays); } return lays; } (document.layers, new Object); var links = document.links; if(location.hash){ scrollToLayer(location.hash.substring(1)); } for ( var i=0; i<links.length; i++ ){ if(links[i].hash && links[i].pathname==location.pathname){ links[i].onclick = scrollToLayer; } } }
かなりうまくいっているように見えるが、やはり問題は山積み。この他にもいっぱい問題を抱えていることだろうと思う。
Issued: / Revised: / All rights reserved. © 2002-2017 TAKI