Opera用Hit-a-Hint作成記・経過報告 6
上のことを踏まえて、getAbsolutePosition 関数を次のように書き直してみた。
function getAbsolutePosition(elem) { var style = getComputedStyle(elem, null); var rect = rectFixForOpera(elem) || elem.getClientRects()[0]; if (rect && rect.right-rect.left && style.visibility != 'hidden' && style.opacity !=0 && rect.left >= 0 && rect.top >= -5 && rect.bottom <= window.innerHeight + 5 && rect.right <= window.innerWidth) { var html = document.documentElement; var body = document.body; return { top: (body.scrollTop || html.scrollTop) - html.clientTop + rect.top, left: (body.scrollLeft || html.scrollLeft) - html.clientLeft + rect.left } } return false; } function rectFixForOpera(elem) { if(!window.opera) return null; if(elem.tagName.toLowerCase()!='a')return null; if(getComputedStyle(elem,null).cssFloat!='none')return null; var c = elem.firstChild; var cIsAfterWhiteSpace = true; while (cIsAfterWhiteSpace) { if (!c) return { left: 0, right: 0, top: 0, bottom: 0 }; cIsAfterWhiteSpace = (c.nodeName.toLowerCase() == 'br' || c.nodeName == '#comment' || c.nodeName == '#text' && !/\S/.test(c.nodeValue)); if (c instanceof HTMLImageElement || c.tagName && c.tagName.toLowerCase()!='br' && getComputedStyle(c, null).display == 'block') return c.getBoundingClientRect(); c = c.nextSibling; } return null; }
中身が画像なのか< br >なのか、ブロック要素なのかインライン要素か、ということを調べる必要があるので、ちょっと複雑になってしまった。スピードも若干犠牲に。
タイプを判定するのに、instanceof でやるのがいいのか、nodeName がいいのか、tagName がいいのか、よくわかってないので僕の Hit-a-Hint のソース中にはそれらが混在してる。
とりあえず今日までの分を公開しておく。
かなり堅牢になってきたと思うので、そろそろコードフリーズになると思う。
バグがあったので修正。
cssFloat にも 対応。