TOC
by
rikuba
2010-06-09 [2010/06/09 07:49:25]
ページ内の見出しから目次を生成(右上)。AutoPagerize対応。最近のブラウザでないと動きません。
@@ -1,61 +1,72 @@
/*
* @title TOC
- * @description ページの右上に目次を作る。IEでは動作しない。
+ * @description ページ内の見出しから目次を生成(右上)。最近のブラウザでないと動きません。
* @include http://*
* @license MIT License
* @require
*/
-(function (init) {
- var i = frames.length;
- while (i--) {
- try { init(frames[i].document); } catch (e) {}
+(function () {
+ function init(doc) {
+ var container, style;
+ if (container = doc.getElementById('bookmarklet_TOC')) {
+ container.parentNode.removeChild(container);
+ return;
+ }
+ container = doc.createElement('div');
+ container.id = 'bookmarklet_TOC';
+ container.appendChild(createTOC(doc));
+ doc.body.appendChild(container);
+ style = doc.createElement('style');
+ style.type = 'text/css';
+ style.textContent = [
+ '#bookmarklet_TOC { background: rgba(0,0,0,0.9); color: #fff;',
+ 'text-align: left; font: 90%/1.5 sans-serif;',
+ 'width: 30px; height: 30px; z-index: 256;',
+ 'max-width: 600px; max-height: 600px; overflow-y: auto;',
+ 'position: fixed; top: 0; right: 0; margin: 0; padding: 0;',
+ '-moz-border-radius: 0 0 0 8px; border-radius: 0 0 0 8px; }',
+ '#bookmarklet_TOC:hover { width: auto; height: auto;',
+ 'padding: 1ex 1em; }',
+ '#bookmarklet_TOC ol { list-style: none; display: none;',
+ 'margin: 0; padding: 0; }',
+ '#bookmarklet_TOC ol ol { margin-left: 1.5em; }',
+ '#bookmarklet_TOC:hover ol { display: block; }',
+ '#bookmarklet_TOC span:hover { cursor: pointer; ',
+ 'text-decoration: underline; }'].join('\n');
+ doc.querySelector('head').appendChild(style);
}
- init(document);
-})(
- (function (createTOC) {
- return function (doc) {
- var container, style;
- if (container = doc.getElementById('bookmarklet_TOC')) {
- container.parentNode.removeChild(container);
- return;
- }
- container = doc.createElement('div');
- container.id = 'bookmarklet_TOC';
- container.appendChild(createTOC(doc.body));
- doc.body.appendChild(container);
- style = doc.createElement('style');
- style.appendChild(doc.createTextNode('#bookmarklet_TOC{background:#000;color:#fff;font-size:90%;text-align:left;line-height:1.5;width:30px;height:30px;max-width:600px;max-height:600px;position:fixed;top:0;right:0;z-index:256;-moz-border-radius:0 0 0 8px;border-radius:0 0 0 8px;margin:0;padding:0}#bookmarklet_TOC:hover{width:auto;height:auto;padding:1ex 1em}#bookmarklet_TOC ol{list-style-position:inside;display:none;margin:0;padding:0}#bookmarklet_TOC ol ol{margin-left:1.5em}#bookmarklet_TOC:hover ol{display:block}#bookmarklet_TOC a{color:#fff;text-decoration:none}#bookmarklet_TOC a:hover{text-decoration:underline}'));
- doc.getElementsByTagName('head').item(0).appendChild(style);
- };
- })(
- function (root) {
- var doc, x, h, c, n, ln, diff, toc, list, i;
- doc = root.ownerDocument || root;
- x = doc.evaluate('descendant::*[self::h1 or self::h2 or self::h3 or self::h4 or self::h5 or self::h6]',
- root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
- toc = list = doc.createElement('ol');
- c = [, 0, 0, 0, 0, 0, 0];
- ln = 1;
- for (i = 0; i < x.snapshotLength; ++i) {
- h = x.snapshotItem(i);
- n = +h.nodeName.charAt(1);
- diff = ln - n;
- if (ln < n) {
- while (diff++) {
- list = (list.hasChildNodes() ? list.lastChild : list.appendChild(doc.createElement('li'))).appendChild(doc.createElement('ol'));
- }
- } else if (n < ln) {
- while (diff--) {
- list = list.parentNode.parentNode;
- }
- }
- a = list.appendChild(doc.createElement('li')).appendChild(doc.createElement('a'));
- a.appendChild(doc.createTextNode(h.textContent || ''));
- a.href = "javascript:document.getElementsByTagName('" + h.nodeName + "').item(" + c[n]++ + ").scrollIntoView()";
+ function createTOC(doc) {
+ var r = l = doc.createElement('ol');
+ var c = [,0,0,0,0,0,0];
+ var ln = 1;
+ [].forEach.call(
+ doc.querySelectorAll('h1,h2,h3,h4,h5,h6'),
+ function (h) {
+ var n = h.nodeName[1];
+ var d = ln - n;
+ if (ln < n)
+ while (d++)
+ l = (l.hasChildNodes()
+ ? l.lastChild
+ : l.appendChild(doc.createElement('li'))
+ ).appendChild(doc.createElement('ol'));
+ else if (n < ln)
+ while (d--)
+ l = l.parentNode.parentNode;
+ var s = l.appendChild(doc.createElement('li'))
+ .appendChild(doc.createElement('span'));
+ s.appendChild(doc.createTextNode(h.textContent || ''));
+ s.addEventListener('click', function () {
+ h.scrollIntoView();
+ }, false);
ln = n;
}
- return toc;
- }
- )
-);
+ );
+ return r;
+ }
+ init(document);
+ [].forEach(frames, function (frame) {
+ try { init(frame.document); } catch (e) {}
+ });
+})();
/*
* @title TOC
* @description ページ内の見出しから目次を生成(右上)。最近のブラウザでないと動きません。
* @include http://*
* @license MIT License
* @require
*/
(function () {
function init(doc) {
var container, style;
if (container = doc.getElementById('bookmarklet_TOC')) {
container.parentNode.removeChild(container);
return;
}
container = doc.createElement('div');
container.id = 'bookmarklet_TOC';
container.appendChild(createTOC(doc));
doc.body.appendChild(container);
style = doc.createElement('style');
style.type = 'text/css';
style.textContent = [
'#bookmarklet_TOC { background: rgba(0,0,0,0.9); color: #fff;',
'text-align: left; font: 90%/1.5 sans-serif;',
'width: 30px; height: 30px; z-index: 256;',
'max-width: 600px; max-height: 600px; overflow-y: auto;',
'position: fixed; top: 0; right: 0; margin: 0; padding: 0;',
'-moz-border-radius: 0 0 0 8px; border-radius: 0 0 0 8px; }',
'#bookmarklet_TOC:hover { width: auto; height: auto;',
'padding: 1ex 1em; }',
'#bookmarklet_TOC ol { list-style: none; display: none;',
'margin: 0; padding: 0; }',
'#bookmarklet_TOC ol ol { margin-left: 1.5em; }',
'#bookmarklet_TOC:hover ol { display: block; }',
'#bookmarklet_TOC span:hover { cursor: pointer; ',
'text-decoration: underline; }'].join('\n');
doc.querySelector('head').appendChild(style);
}
function createTOC(doc) {
var r = l = doc.createElement('ol');
var c = [,0,0,0,0,0,0];
var ln = 1;
[].forEach.call(
doc.querySelectorAll('h1,h2,h3,h4,h5,h6'),
function (h) {
var n = h.nodeName[1];
var d = ln - n;
if (ln < n)
while (d++)
l = (l.hasChildNodes()
? l.lastChild
: l.appendChild(doc.createElement('li'))
).appendChild(doc.createElement('ol'));
else if (n < ln)
while (d--)
l = l.parentNode.parentNode;
var s = l.appendChild(doc.createElement('li'))
.appendChild(doc.createElement('span'));
s.appendChild(doc.createTextNode(h.textContent || ''));
s.addEventListener('click', function () {
h.scrollIntoView();
}, false);
ln = n;
}
);
return r;
}
init(document);
[].forEach(frames, function (frame) {
try { init(frame.document); } catch (e) {}
});
})();
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。