セクション番号を自動で振ってくれる JavaScript
JavaScript の勉強のつもりで作ってみました.
表示例
<h1>ABC</h1> <h2>foo</h2> <h2>bar</h2> <h3>hoge</h3> <h3>fuga</h3> <h1>XYZ</h1> <h3>piyo</h3>
こんな感じのものが,
こんな風になります.
コード
var HeaderEnumerator = function() { this.enumeratingTags = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6']; this.sectionLevel = new SectionLevel(); }; HeaderEnumerator.prototype = { startElement: function(element) { var newSectionLevel = this.calcSectionLevel(element); if (newSectionLevel < 0) { return; } this.setSectionLevel(newSectionLevel); this.preppendSectionNumber(element); }, endElement: function(element) { }, calcSectionLevel: function(element) { return this.enumeratingTags.indexOf(element.nodeName); }, preppendSectionNumber: function(element) { var numElem = document.createElement('span'); numElem.className = 'section-number'; var numText = document.createTextNode(this.formatSectionNumber()); numElem.appendChild(numText); element.insertBefore(numElem, element.firstChild); }, setSectionLevel: function(newSectionLevel) { this.sectionLevel.setLevel(newSectionLevel); }, formatSectionNumber: function() { return this.sectionLevel.format(); } }; var SectionLevel = function() { this.numbers = [new SectionNumber()]; }; SectionLevel.prototype = { indent: function() { this.numbers.push(new SectionNumber()); }, unindent: function() { this.numbers.pop(); }, increment: function() { this.getCurrentNumber().increment(); }, setLevel: function(level) { if (level < 0) { return; } if (level < this.getLevel()) { var n = this.getLevel() - level; for (var i = 0; i < n; i++) { this.unindent(); } } else if (this.getLevel() < level) { var n = level - this.getLevel(); for (var i = 0; i < n; i++) { this.indent(); } } this.increment(); }, getLevel: function() { return this.numbers.length - 1; }, getCurrentNumber: function() { return this.numbers[this.getLevel()]; }, getNumber: function(i) { return this.numbers[i]; }, format: function() { var numstr = ''; for (var i = 0; i < this.numbers.length; i++) { numstr += this.getNumber(i).get() + '.'; } return numstr + ' '; } }; var SectionNumber = function() { this.sectionNumber = 0; }; SectionNumber.prototype = { increment: function() { this.sectionNumber++; }, get: function() { return this.sectionNumber; } }; function walk(element, obj) { obj.startElement(element); var len = element.childNodes.length; for (var i = 0; i < len; i++) { walk(element.childNodes[i], obj); } obj.endElement(element); } window.addEventListener("load", function () { walk(document.body, new HeaderEnumerator()); }, false);
全然 JavaScript っぽくないような気がしますが…
感想
基本的な文法はだいたいわかった気がします.
あと,見やすいライブラリ リファレンスも手に入れました.
JavaScript を面白いと感じるには,JavaScript っぽい書き方をしてこそだと思う (Python は内包表現が面白いよね) のだけど,JavaScript っぽく書けた気がしません...