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