Insertion.Afterクラス
【抜粋】 Insertion.After = Class.create(); Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { initializeRange: function() { this.range.setStartAfter(this.element); }, insertContent: function(fragments) { fragments.each((function(fragment) { this.element.parentNode.insertBefore(fragment, this.element.nextSibling); }).bind(this)); } });
基準要素の直後に要素を挿入するクラスです。インスタンス作成時に処理が行われ、各メソッドは外部から使用されることはありません。
Abstract.Insertionクラスの引数に'afterEnd'を設定してインスタンスを生成、継承しています
initializeRangeメソッド
this.rangeはRangeオブジェクトです。setStartAfterメソッドにより、基準要素の直後を指定します。Mozilla系ブラウザでcreateContextualFragmentメソッドを使うための準備です。
insertContentメソッド
引数fragmentsが、挿入する要素オブジェクトを格納しているArrayオブジェクトなのは前述Insertion.Beforeクラスと同じです。基準要素の親要素からinsertBeforeメソッドを使用して、基準要素の次の要素の前に挿入しています*1。
【例】 <html> <head> <title></title> <style> <!-- div, table, td{ border:solid blue 2px; margin:5px; padding:5px; } --> </style> <script language="javascript" src="prototype.js" charset="utf-8"></script> <script> <!-- var counter = 0; function test(){ var blue = (255 - counter * 20); blue = (blue < 0) ? 0 : blue; var color = "rgb(255, 255, " + blue + ")"; var str = "<div>BBBB<div>" + counter + "</div></div>" + "<script>" + "$('test').style.backgroundColor = '" + color + "';" + "counter++;" + "</script>"; new Insertion.After('test', str); } //--> </script> </head> <body> <div id="test">AAAA</div> <button onclick="test();">TEST</button> </body> </html>
前述Insertion.Beforeの例をInsertion.Afterに変えただけです。*2
テーブル途中への行追加は、tr要素を対象とすることで可能です。v1.4.0では、IEでtr要素を対象とすることができません。v1.5.0以降で対象となります。>>こちら<<を参照してください。
テーブル末尾への行追加は前述Insertion.Bottomクラスを使用します。
【参考】v1.5.0について
v1.5.0ではAbstract.Insertionのinitializeメソッドが以下のようになるようです。
Abstract.Insertion.prototype = { initialize: function(element, content) { this.element = $(element); this.content = content.stripScripts(); if (this.adjacency && this.element.insertAdjacentHTML) { try { this.element.insertAdjacentHTML(this.adjacency, this.content); } catch (e) { var tagName = this.element.tagName.toLowerCase(); if (tagName == 'tbody' || tagName == 'tr') { this.insertContent(this.contentFromAnonymousTable()); } else { throw e; } } } else { this.range = this.element.ownerDocument.createRange(); if (this.initializeRange) this.initializeRange(); this.insertContent([this.range.createContextualFragment(this.content)]); } setTimeout(function() {content.evalScripts()}, 10); },
11行目でタグ名の条件にtrが追加されています。これにより、IEでもtr要素を対象とすることができます。Insertion.BeforeやInsertion.Afterで、テーブル途中への行追加も可能となります。
【参考】テーブル途中への行追加 (Abstract.Insertionのinitializeメソッドを上書き) <html> <head> <title></title> <style> <!-- table, td{ border:solid blue 2px; margin:5px; padding:5px; } --> </style> <script language="javascript" src="prototype.js" charset="utf-8"></script> <script> <!-- //メソッド上書き(v1.5.0以降では不要) Abstract.Insertion.prototype.initialize = function(element, content) { this.element = $(element); this.content = content.stripScripts(); if (this.adjacency && this.element.insertAdjacentHTML) { try { this.element.insertAdjacentHTML(this.adjacency, this.content); } catch (e) { var tagName = this.element.tagName.toLowerCase(); if (tagName == 'tbody' || tagName == 'tr') { this.insertContent(this.contentFromAnonymousTable()); } else { throw e; } } } else { this.range = this.element.ownerDocument.createRange(); if (this.initializeRange) this.initializeRange(); this.insertContent([this.range.createContextualFragment(this.content)]); } setTimeout(function() {content.evalScripts()}, 10); }; var counter = 0; function test(location){ var str = "<tr><td>ADD</td><td>" + counter + "</td></tr>"; new Insertion[location]('tr', str); counter++; } //--> </script> </head> <body> <table> <tbody id="tbody"> <tr id="tr"><td>CELL</td><td>CELL</td></tr> </tbody> </table> <button onclick="test('Before');">BEFORE</button> <button onclick="test('After');">AFTER</button> </body> </html>
*1:要素のnextSiblingプロパティは次の要素が格納されている
*2:Operaではカウンタが上がらない不具合があります。Insertion.Beforeクラス - Backstage of theater.js参照