以前よりCamino べんりセットのbookmarkletを使っていたのですが、その中の「ID/NAME を表示」が、最近ページによって動いたり動かなかったりという状況があったので、同様の機能のものを自分なりに作ってみることにしました。
(function(){
var elements = $A(document.body.getElementsByTagName('*'));
var i = elements.length;
while (i--) {
var element = elements[i];
var tagName = element.tagName.toLowerCase();
if (tagName == 'a') {
var id = element.id || element.name;
if (!id) continue;
var anch = makeIdAnch(id);
element.parentNode.insertBefore(anch, element);
}
else if (element.id) {
var anch = makeIdAnch(element.id);
if ( tagName.match(/^(br|hr|area|img|object|embed|iframe|col|input|button|textarea|select)$/) )
element.parentNode.insertBefore(anch, element);
else
element.insertBefore(anch, element.firstChild);
}
}
function $A(list) {
var i = list.length, array = new Array(i);
while (i--) array[i] = list[i];
return array;
}
function makeIdAnch(id) {
var ins = document.createElement('ins');
setStyle(ins, {
margin: 0,
padding: 0,
backgroundImage: 'none',
textDecoration: 'none'
});
var anch = document.createElement('a');
setStyle(anch, {
backgroundColor: '#ffc',
border: 'outset 1px #ffc',
padding: '0 2px',
textDecoration: 'none',
color: '#00f',
fontSize: '12px',
fontWeight: 'normal'
});
anch.appendChild( document.createTextNode(id) );
anch.href = '#' + id;
ins.appendChild(anch);
return ins;
}
function setStyle(element, style) {
var es = element.style;
for (var prop in style) {
es[prop] = style[prop];
}
}
})();
prototype.jsより$A()
関数を拝借したのですが、リストの各要素に何か処理をする際に「最初にリストのlengthを取得し、while (length--)
で逆順に回す」というやり方をしていたのを初めて見たので、自分でも使ってみました。
// 例: whileで回す場合
var i = list.length;
while (i--) {
var item = list[i];
// item に対して何かする
}
// 例: forで回す場合
for (var i = 0, len = list.length; i < len; i++) {
var item = list[i];
// item に対して何かする
}
後置の--
を使っているので、例えばlength
が5だったとすると、while
の括弧内では 5, 4, 3, 2, 1 と続くのに対し、while
ループ内では 4, 3, 2, 1, 0 となるのでインデックスの値として丁度よくなっています。見た目にも3項のfor
で書くよりすっきりしているのもよいと思いました。