04 | 2017/05 |  06

  1. 無料サーバー

User forum-FC2BLOG-Info-Edit Template-Post-Edit-Upload-LogOut

CSSやJavascript自習の苦闘史を綴っていきたい。恐縮ですがJavascriptを有効にしてご覧ください。
2005年12月から社会問題も掲載!

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

 

jQuery の挙動を解読する(33):DOM Manipulate メソッド解読──jQuery解読(50)

Contents
  • domManip() メソッド解読
  • 各種 DOM Manipulate メソッドの性質と分類
  • 各種 DOM Manipulate メソッドの例を試す
  • 各種 DOM Manipulate メソッドを解読する───親ノード追加系
  • 各種 DOM Manipulate メソッドを解読する───子ノード追加系
  • 各種 DOM Manipulate メソッドを解読する───兄弟ノード追加系
  • 各種 DOM Manipulate メソッドを解読する───置換系

このエントリイでは DOM 要素操作 に係るインスタンスメソッドに焦点を当て、それらのメソッドを解読します。

対象とするメソッドは、domManip()、wrapAll()、wrapInner()、wrap()、append()、prepend()、before()、after() 、appendTo()、prependTo()、insertBefore()、insertAfter()、replaceWith()、replaceAll()、text()、html() です。

domManip()

まず、DOM 走査の基本的な役割を担う domManip() メソッドから解読します。

このメソッドは args 内の html 文字列によってインスタンスにノードを追加する際に、(1) clean メソッドを適用して html 文字列の記述ミスを正し、(2) またブラウザバグを補正すると共に、(3) DocumentFragment を使用することにより script タグをインスタンスに追加する、以上のことを行います。

■ domManip() インスタンスメソッド解読
  // 引数は順に、1:走査対象となるノードを要素とする配列、2:table 有無の指定、
  // 及び 3:適用するメソッドで、返値は jQuery インスタンスである。
514:domManip: function( args, table, callback ) {
515: if ( this[0] ) { // インスタンスに最初の要素があれば
    // 3 つの変数を定義する。まず文書断片( DocumentFragment )を作る。ここに、
    // this[0] が document ノードの時には owwnerDocument 値が null となる
    // ため < || this[0] > が必要となる。いずれにしても document ノードに
    // 文書断片を作成し、それへの参照を fragment 変数に代入する。
516:  var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
     // 引数 args を clean メソッドでチェックし return 値を変数 scripts に代入
     // する。ここに clean メソッド #961 から返される値は配列であり、その要素は
     // args 内に存在していた script タグである。
517:   scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
     // 上の clean メソッドにより args 配列要素の script タグ以外のタグ内にあった
     // script タグが削除された後に fragmentノードの chileNodes となっている。
     // ( #957 )。その中の第一子ノードを 変数 first に参照させる。
518:   first = fragment.firstChild;
519:  // このブロックは args 内に記述されていた script タグを、インスタンスの各要素
    // ノードから呼び出される実行される callback 関数の引数にするためのもの。
520:  if ( first ) // 第一子ノードが取得できれば
     // インスタンスに格納されている要素ノードの数だけ巡回処理する。
521:   for ( var i = 0, l = this.length; i < l; i++ )
      // root 関数で table ノードの場合の処理を行い、call の第 1 引数とし、
      // this に格納されている要素ノード数が 2 以上か イテレート変数が
      // 1 以上ならば fragment ノードの cloneNode をイベント付きで作成して
522:    callback.call( root(this[i], first), this.length > 1 || i > 0 ?
        // 第 2 引数とし、要素ノード数が 1 以下か i = 0 の時には
        // fragment ノード自体を第 2 引数とする。
523:      fragment.cloneNode(true) : fragment );
524: 
525:  if ( scripts ) // scripts が取得できたらば
     // その 1 つ 1 つを evalScript メソッドで評価する。
526:   jQuery.each( scripts, evalScript );
527: }
528: // 以上の処理を終えた this インスタンスを呼び出し元に返す。
529: return this; // また this[0] がない場合には this をそのまま返す。
530: 
531: function root( elem, cur ) {
    // 引数 table が true で、要素ノード=this[i] が table ノードで
    // cur が tr ノードならば
532:  return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
     // 取得できた最初の tbody ノードを返すか、取得できなければ tbody 要素ノードを
     // elem ノードに追加して return する。
533:   (elem.getElementsByTagName("tbody")[0] ||
534:   elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
     // その他の場合には elem 自身=this[0] を return する。
535:   elem;
536: }
537:}

▲ToTop

各種 DOM Manipulate メソッドの性質と分類

DOM 操作を行う jQuery インスタンスメソッドは次のように沢山あります。─── $(s,c).wrapAll(html)、$(s,c).wrapInner(html)、$(s,c).wrap(html)、$(s,c).append(elem)、$(s,c).prepend(elem)、$(s,c).before(elem)、$(s,c).after(elem)、$(s,c).appendTo(elem)、$(s,c).prependTo(elem)、$(s,c).insertBefore(elem)、$(s,c).insertAfter(elem)、$(s,c).replaceWith(elem)、$(s,c).replaceAll(elem)、$(s,c).text(str)、$(s,c).html(html) 等々。

これらの 15 個のメソッドの共通点は、jQuery インスタンス内に参照が取得されている要素ノードと、各のメソッドの引数である html や elem 等によって定まるノードとの、二者の組み合わせ方を定めることです。これらのインスタンスメソッドは、2 つの(あるいは 2 つの群の) DOM 要素間の前後関係(つまり兄弟関係)、包含/被包含関係(親子関係)、あるいは置換/被置換関係を定義づけます。

まず、組み合わせの対象となる 2 つ( 2 群 )の位置関係を整理しておくべきでしょう。分かりやすく表示するために、インスタンス内で参照付けられているノード群をA、引数によって参照付けられるノードをBとします。

親ノード追加系
  • $(s,c).wrapAll(html)……A[0]~A[last] までの全体を B で包含する。A[i] = B.childNodes[i]
  • $(s,c).wrapInner(html)……A の子ノード C を B で囲む。B.childNodes =A[i].childNodesとなる。
  • $(s,c).wrap(html)……B を個々の A の親ノードとする。A[i].parentNode = B
子ノード追加系
  • $(s,c).append(elem)……B を個々の Aの最後の子ノードとする。A[i].lastChild = B
  • $(s,c).prepend(elem)……B を個々の A の最初の子ノードとする。A[i].firstChild = B
  • $(s,c).appendTo(elem)……A を B の最後の子ノードとする。B.lastChild = A
  • $(s,c).prependTo(elem)……A を B の最初の子ノードとする。B.firstChild = A
兄弟ノード追加系
  • $(s,c).before(elem)……B を個々の A の直前の兄弟ノードとする。A[i].previousSibling = B
  • $(s,c).after(elem)……B を個々の A の直後の兄弟ノードとする。A[i].nextSibling = B
  • $(s,c).insertBefore(elem)……A を B の直前の兄弟ノードとする。A = B.previousSibling
  • $(s,c).insertAfter(elem)……A を B の直後の兄弟ノードとする。A = B.lastSibling
置換系
  • $(s,c).replaceWith(elem)……A を B で置換する。A[i] → B
  • $(s,c).replaceAll(elem)……B を A で置換する。A[i] ← B
  • $(s,c).text(str)……A の 子要素を B で置換する。A[i].childNodes = B
  • $(s,c).html(html)……A の 子要素を B で置換する。A[i].childNodes = B

▲ToTop

各種 DOM Manipulate メソッドの例を試す

解読の前に各種 DOM Manipulate メソッドの適用例をこのページ上で見てみます。それぞれのメソッドの働き方や差異を見るにはそれが手っ取り早いからです。

適用例の説明
  • 下のボタンは各種 DOM Manipulate メソッドを実行するためのもの。15 のいずれかをクリックすると、ボタンの下にある薄緑色のボックス内で各種メソッドの効果を表示します。
  • メソッドの適用効果を消去するにはもう一度同じボタンをクリックします。
  • メソッドの適用対象は、薄緑色のボックス内に配置した 3 つの p タグです。これをボタン上では $(this) と表示しました。3 つの pタグはピンクの枠で示していますが、それらを対象として各種 DOM Manipulate メソッドを適用します。
  • 他方、働き方を逆転させるメソッドの場合には、メソッド起動要素がサイト内に存在していなければ成りませんので、そのための要素として DIV タグ( class="targetDiv" )を用意しました。

メソッドの引数として次の html 文字列を準備しました。

  • "<div style='background-color:maroon;border:4px dotted gray;margin:2px;padding:2px;'></div>"
  • "<p style='background-color:maroon;border:4px dotted gray;margin:2px;padding:2px;'>これはボタンをクリックしたことにより追加されたノードです。</p>"
  
   
   
   

(第1 pタグ)これは各種 DOM Manipulate メソッドの働き方を視覚的に見やすくしたサンプルです。

(第2 pタグ)このブロックを包含する div タグがあり、その中に複数の 3 つの p タグと 2 つの div タグを配置し、3 つめのパラグラフには画像を配置しました。

(第1 divタグ)3 つの p タグを操作対象として各種のメソッドを適用します。

(第3 pタグ) これは画像を含むパラグラフです。

(第2 divタグ)
逆転メソッドで使用する div タグ

各種 DOM Manipulate メソッドを解読する───親ノード追加系

$(s,c).wrapAll(html) メソッド解読

このメソッドは、jQueryインスタンスが参照するノード全体を、 html 文字列によってサイトに追加されるノードの子ノードにします。

■ $(s,c).wrapAll(html) メソッド
219: wrapAll: function( html ) {
220:  if ( this[0] ) {
221:   // The elements to wrap the target around
     // html 文字列で指定されたノード群を document 内で検索し、マッチ
     // したノードの clone ノードを作り、変数 wrap に代入する。
222:   var wrap = jQuery( html, this[0].ownerDocument ).clone();
223:   // インスタンスの最初のノードに親ノードがあれば、
224:   if ( this[0].parentNode )
      // clone ノード ( wrap ) をインスタンスの、最初の配列もどきプロ
      // パティが参照するノード ( this[0] ) の前に配置する。
225:    wrap.insertBefore( this[0] );
226:
227:   wrap.map(function(){
      // この this は mapメソッド内にあり、map メソッドが wrap から
228:    var elem = this; // 呼び出されているので wrap を参照する。
229:
230:    while ( elem.firstChild ) // 最も深い階層にある最初の
231:     elem = elem.firstChild; // 子ノードを elem に代入し、
232:
233:    return elem; // その最後の子ノードを返す。
     // 返された最深層の最初の子ノードの中に、this を最後の子ノードとして追加する。
     // なおここの this はインスタンスから呼び出される wrapAll メソッド内にある
234:   }).append(this); // ので、インスタンスを参照する。
235:  }
236:
237:  return this; // インスタンスを返す。
238: },
$(s,c).wrapInner(html) 解読

このメソッドはインスタンスの各々の子ノードを html 文字列による追加ノードで包含します。

■ $(s,c).wrapInner(html) メソッド
240: wrapInner: function( html ) {
241:  return this.each(function(){ // インスタンスの各々のノードに対して
     // 当該ノードの子ノード jQuery( this ).contents() を html により
     // 挿入されるノードで包含する。なお、contents() は #1186 で定義
     // されているインスタンスメソッドである。
242:   jQuery( this ).contents().wrapAll( html );
243:  });
244: },
$(s,c).wrap(html) 解読

このメソッドはインスタンスが参照する各々のノードを html 文字列による追加ノードで包含します。

■ $(s,c).wrap(html) メソッド
246: wrap: function( html ) {
    // インスタンスの各々のノードを巡回処理し結果を返す。
247:  return this.each(function(){
     // 各々のノードを html 文字列による追加ノードの子ノードとする。
248:   jQuery( this ).wrapAll( html );
249:  });
250: },

▲ToTop

各種の DOM Manipulate メソッドを解読する───子ノード追加系

子ノードを追加する 最初の 2 つのメソッドでは共通して domManip メソッドが使われています。また、appendTo メソッドと prependTo メソッドはそれぞれ append と prepend メソッドを利用して対象を逆転させているだけですから、結局 4 つのメソッドで domManip メソッドが使われていることになります。

これは、誤記や table に係る IE のバグ対策を施さないと追加により、インスタンスが指し示すノードが文法的におかしくなってしまうことがあるためです。

■ 子ノード追加系 メソッド
▼ append() メソッド
252: append: function() {
253:  return this.domManip(arguments, true, function(elem){
254:   if (this.nodeType == 1)
      // この this は domManip メソッドの定義から、インスタンス内で指し
      // 示されている個々のノードを指す。( #522 )その個々のノードの
      // 最後の子ノードとして elem により定義されるノードを挿入する。
255:    this.appendChild( elem );
256:  });
257: },
258:

▼ prepend() メソッド
259: prepend: function() {
260:  return this.domManip(arguments, true, function(elem){
261:   if (this.nodeType == 1)
      // この this は domManip メソッドの定義から、インスタンス内で指し
      // 示されている個々のノードを指す。( #522 )その個々のノードの
      // 最初の子ノードの前に、elem により定義されるノードを挿入する。
262:    this.insertBefore( elem, this.firstChild );
263:  });
264: },

▼insertBefore() 及び insertAfter() メソッド
// 以下のブロックの解読は別途こちらのエントリイ ( jQuery の挙動を解読する(31):
jQuery.each({ nameN:fnN(){}},function(){}) によるメソッド登録──jQuery解読(48) )
で行いました。
1198:jQuery.each({
1199: appendTo: "append",
1200: prependTo: "prepend",
1201: insertBefore: "before",
1202: insertAfter: "after",
1203: replaceAll: "replaceWith"
1204:}, function(name, original){
1205: jQuery.fn[ name ] = function( selector ) {
1206:  var ret = [], insert = jQuery( selector );
1207:
1208:  for ( var i = 0, l = insert.length; i < l; i++ ) {
1209:   var elems = (i > 0 ? this.clone(true) : this).get();
1210:   jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
1211:   ret = ret.concat( elems );
1212:  }
1213:
1214:  return this.pushStack( ret, name, selector );
1215: };
1216:});

▲ToTop

各種の DOM Manipulate メソッドを解読する───兄弟ノード追加系

兄弟ノードを追加する最初の 2 つのメソッドでも共通して domManip メソッドが使われ、その中では clean メソッドが呼び出されます。また、insertBefore メソッドと insertAfter メソッドはそれぞれ before と after メソッドを利用して対象を逆転させているだけですから、結局 4 つのメソッドで domManip メソッドが使われていることになります。

このような回り道をするのは、clean メソッドを使って誤記や table に係る IE のバグ対策を施さないと、ノード追加によって、インスタンスが指し示すノードが文法的におかしくなってしまうことがあるためです。

■ 兄弟ノード追加系 メソッド
▼ before() メソッド
266: before: function() {
267:  return this.domManip(arguments, false, function(elem){
     // この this は domManip メソッドの定義から、インスタンス内で指し
     // 示されている個々のノードを指す。( #522 )その個々のノードの
     // 前に、elem により定義されるノードを兄弟要素として挿入する。
268:   this.parentNode.insertBefore( elem, this );
269:  });
270: },
271:

▼ after() メソッド
272: after: function() {
273:  return this.domManip(arguments, false, function(elem){
     // この this は domManip メソッドの定義から、インスタンス内で指し
     // 示されている個々のノードを指す。( #522 )その個々のノードの
     // 次の兄弟ノードの前に、elem により定義されるノードを挿入する。
     // つまり個々のノードの後ろに elem を兄弟ノードとして挿入する。
274:   this.parentNode.insertBefore( elem, this.nextSibling );
275:  });
276: },
// insertBefore と insertAfter の 2 つのメソッドに関しては、直上の
// 「子ノード追加系」でリストアップした #1198-1216 を参照のこと。

▲ToTop

各種の DOM Manipulate メソッドを解読する───置換系

replaceWith(elem) メソッドは極めて簡単なコードで定義されています。インスタンスが指し示す個々の要素ノードの直後に兄弟要素 elem を追加してから、当該要素ノードをを削除します。

■ 置換系 メソッド
▼ replaceWith() メソッド
491: replaceWith: function( value ) {
492:  return this.after( value ).remove();
493: },

▼ replaceAll() メソッド
// replaceAll メソッドに関しては、こちらを参照のこと。

▼ text() メソッド
201: text: function( text ) {
    // 引数がオブジェクトでもなく空でもなければ
202:  if ( typeof text !== "object" && text != null )
     // インスタンスが指し示す個々の要素の子ノードを削除してから、
     // 0 プロパティが存在したら document ノードにテキストノードを作り、
     // それを個々の要素の子ノードとして追加する。
203:   return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
204:  // 引数がオブジェクトか、空文字のとき
205:  var ret = ""; // 空文字を変数 ret に代入
206:
207:  jQuery.each( text || this, function(){ // 
208:   jQuery.each( this.childNodes, function(){ // 子ノードを巡回処理
209:    if ( this.nodeType != 8 ) // 子ノードがコメントノードでない場合
210:     ret += this.nodeType != 1 ? // 子ノードが要素ノードでなければ
211:      this.nodeValue : // その値、つまりテキスト文字列を ret に代入
        // 子ノードが要素ノードの場合 this を配列の要素に入れて
212:      jQuery.fn.text( [ this ] ); //text メソッドを再帰呼び出しする。
213:   });
214:  });
215:
216:  return ret; // 文字列 ret を返す。
217: },

▼ html() メソッド
483: html: function( value ) {
484:  return value === undefined ? // value が未定義ならば
485:   (this[0] ? // 最初の配列もどきプロパティ 0 が存在すれば
      // プロパティ 0 の innerHTML 文字列内に変数 expando による
      // 「半角スペース + "jQuery" + 数字 = 数字」文字列があれば
      // それを削除してから、innerHTML 文字列を返値とする。
      // プロパティ 0 が存在しなければ null を返す。
486:    this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
487:    null) :
     // value が存在すれば個々の要素の子ノードを空にしてから、
     // value を子ノードとして追加する。
488:   this.empty().append( value );
489: },



・・・・・

 

■ コメントの投稿 ■

管理者にだけ表示を許可する

●トラックバック●

■トラックバックURLはこちら■
http://hkom.blog1.fc2.com/tb.php/703-8e4f1b3b

●参照元一覧●

<provided Fc2>
<provided i2i>

▲ToTop

 90%近いシェアを握っているインターネットエクスプローラの描画エンジンを利用したタブbrowser。沢山のタブbrowserがあるが、多機能、カスタマイズフリー、スクリプト利用等で一日の長がある。Gekkoエンジンへの対応も行われ、IEからの自立独立の方向に向かっている。2005年7月にはIE7が登場する見通しの中で、今後の発展が望まれる。

 多様なCSS作成支援機能を備えた、タグ入力式 HTML&CSS作成支援エディタ。スキンデザインもすっきりしている。テキストエディター上で作成するよりも確実で安全にタグ打ちが出来る。
文字コードを選べないのが欠点。

 StyleNote同様のタグ入力式 HTML&CSS 作成支援エディタ。長年使用してきたが現在StyleNoteに乗り換えつつある。

 クリップボード履歴情報を活用する為のソフト。画像まで履歴を取ってくれるのが嬉しい。このソフトを使わない日は絶対ない程に重宝し、愛用している。

 起動中のウィンドウの「コピーできない」説明文などの文字列を取得し、コピー可能な文字データにするツール。何かと便利。

 ストリーミングデータを保存することが出来るソフト。動画利用には不可欠なソフトだ。

 無料ながらレイヤー機能を有し、スクリプトによる拡張も可能な、sleipnir作者が提供している優れもの画像編集ソフト。

 画面キャプチャソフトと言えばこれに勝るものなし、ではないだろうか? 様々な取得方法を有しており、ブログ作成にもHomepage作成に不可欠だ。Jtrimと並んでWoodyBellsの作品。

 複数ファイルの同時編集は出来ないが、透過pngも作れる画像編集ソフト。
(以下当該サイトから抜粋)初心者にも簡単に操作が出来るフォトレタッチソフトです。多くの加工機能で画像に様々な効果を与えることができます。非常に軽快に動作するため、ストレスなく操作できます。

 Animation Gifファイルを作れる無料ソフト。

 キャプチャソフト。画面内にサイト全体が表示しきれない場合でも、これを使えば全体をキャプチャすることが出来る。

 画像処理。画像のフォーマット変換のみならず、色数やサイズ、圧縮率の変更まで一括処理できてしまう『BatchGOO!』は、大量の画像をまとめて処理したいときに大変便利なソフト。BMP, TIFF, JPEG, PCX, PNG の相互変換をはじめ、色数・サイズ・解像度の統一、JPEG圧縮率の調節など、ホームページ用の画像や携帯電話用の壁紙を揃えるのに抜群の相性を見せる。(Vectorの当該ソフト紹介頁より抜粋引用)

 名前から直ぐに想像が付くように画像のサイズを測るためのソフトだ。Homepage作成には欠かせない。2カラム、3カラムのレイアウトを行う場合に大変重宝する。

 ランチャーソフトは沢山あるが、中でもこれが一押しだ。2年以上使ってきたがその操作性には毎日満足している。これを使い始めてからデスクトップには一切のアイコンを表示することをやめてしまった。

 AdobeReader7によって、起動時間が長すぎるという長年のユーザーの不満はある程度解消した。そのためこの高速化ソフトは存在価値が低下してしまったかもしれない。AdobeReader6迄はこのソフトによる起動高速化で恩恵を受けてきた。

 IE専用が難点だが、様々なサイト内でIDやパスワードを入力するのに重宝するソフト。コンテキストメニューから簡単に起動できるのがGood! sleipnir等のIEの描画エンジンを利用しているブラウザでも使える。

 利用しているパソコンの諸元値を取得するには、このソフトがベストだ。インストール済みソフトの一覧が取得できるのも嬉しい。

 WMPは機能が豊富なだけ重い。RealPlayerも同様だ。そこでMedia Player Classicを使いたい。動作が軽快なだけではなく、対応しているファイル形式もすこぶる多く、これひとつで、wmvもrmも表示できてしまうのだから凄い! 数多あるMedia Playerの王様と言えるだろう。

 自宅でPCを起動しているときには必ず起動しているメディアプレーヤー。何かと過剰なWinampよりも、起動も速くスキンはシンプルだ。

 DivX, Xvid, Mov, Vob, Mpeg, Mpeg4, avi, wmv, dv, などの動画をDVD-Video形式に変換できるフリーソフト。クリックするとDVD関連ソフト紹介サイト=「DVDなToolたち」なるHomepageが開きます。

----------
200903300116
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。