Extの12を読みます(各位置に要素を挿入します)


IEはinnerHTMLというショートカット作成DOM要素(およびその属性など)を発明するほか、insertAdjacentHTML/insertAdjacentText方法を発明した.それらは初めてIE 4に導入され、その後、Opera、Safari、Chromeなどの他のブラウザが相次いで実現された.Firefoxだけは実現しなかった.多くのブラウザでinsertAdjacentHTMLが実装されていることから、html 5はその列に組み込まれており、insertAdjacentTextはそれほどラッキーではありません.Firefoxでは、他の方法で同じ機能を実現しています.この編でHTML Elementを拡張する.prototypeはFirefoxのためにIEと同じインタフェース方法を実現した.Ext.DomHelperではHTML Elementを拡張していません.prototype(一部の人は原生を汚染したHTML Elementと思っているので、しばらく置いておきます).次の4つの方法が提供されています
 
insertBeforeエレメントの前に新しいエレメントを挿入insertAfterエレメントの後ろに新しいエレメントを挿入insertFirstエレメント内部の最初の位置に新しいエレメントappendを挿入エレメント内部の最後の位置に新しいエレメントを挿入
 
前編で述べたように,この4つのメソッドはいずれもプライベートなdoInsert関数を呼び出し,doInsert関数の内部ではExt.DomHelperのinsertHtmlメソッドを呼び出している.下一篇に戻ってそのスクリーンショットを見ると一目瞭然です.したがってinsertHtmlメソッドは,クライアントプログラマに提供される4つのインタフェースメソッドのうち,様々な方法で要素を挿入することを実現するコアメソッドである.
insertHtml : function(where, el, html){
    var hash = {},
        hashVal,
        setStart,
        range,
        frag,
        rangeEl,
        rs;

    where = where.toLowerCase();
    // add these here because they are used in both branches of the condition.
    hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
    hash[afterend] = ['AfterEnd', 'nextSibling'];

    if (el.insertAdjacentHTML) {
        if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
            return rs;
        }
        // add these two to the hash.
        hash[afterbegin] = ['AfterBegin', 'firstChild'];
        hash[beforeend] = ['BeforeEnd', 'lastChild'];
        if ((hashVal = hash[where])) {
            el.insertAdjacentHTML(hashVal[0], html);
            return el[hashVal[1]];
        }
    } else {
        range = el.ownerDocument.createRange();
        setStart = 'setStart' + (/end/i.test(where) ? 'After' : 'Before');
        if (hash[where]) {
            range[setStart](el);
            frag = range.createContextualFragment(html);
            el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
            return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling'];
        } else {
            rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child';
            if (el.firstChild) {
                range[setStart](el[rangeEl]);
                frag = range.createContextualFragment(html);
                if(where == afterbegin){
                    el.insertBefore(frag, el.firstChild);
                }else{
                    el.appendChild(frag);
                }
            } else {
                el.innerHTML = html;
            }
            return el[rangeEl];
        }
    }
    throw 'Illegal insertion point -> "' + where + '"';
},

 
InsertHtmlの実現も理解しやすく、2つの分岐1はelをサポートする.InsertAdjacentHTMLのブラウザ(IE/Chrome/Safari/Opera)はelを使用する.InsertAdjacentHTMLブランチ2、elはサポートされていません.InsertAdjacentHTMLのブラウザ(Firefox)はrangeを使用する.createContextualFragment+el.insertBefore/el.appendChildブランチ1ではtable/tr/td要素を個別に処理し,対応するプライベート関数はieTable,insertIntoTableである.insertIntoTableでdivを作成してtableを追加したのは、IE 6/7/8のTable要素のinnerHTML Bugのためです.Ext.DomHelperには最後の方法applyStylesが残っています
applyStyles : function(el, styles){
    if(styles){
        var i = 0,
            len,
            style;

        el = Ext.fly(el);
        if(Ext.isFunction(styles)){
            styles = styles.call();
        }
        if(Ext.isString(styles)){
            styles = styles.trim().split(/\s*(?::|;)\s*/);
            for(len = styles.length; i < len;){
                el.setStyle(styles[i++], styles[i++]);
            }
        }else if (Ext.isObject(styles)){
            el.setStyle(styles);
        }
    }
},

 
HTML要素のスタイルを設定するには、パラメータstylesは文字列'color:red'であってもよく、オブジェクト{color:red}であっても関数function(){return'color:red'}であってもよい.el = Ext.fly(el); この文のExt.flyは、Ext.Elementオブジェクトを取得し、Ext.Elementに定義します.後編は、Ext.flyとExt.getの違いについて言及した.styles = styles.call(); stylesが関数タイプである場合、この関数を直接呼び出します.ここではcallで関数を実行しますが、パラメータは伝達されません.したがって、callを完全に削除してかっこ()呼び出しを直接使用することができます:styles=styles();関数の様々な呼び出し方法は、具名関数の4つの呼び出し方法 stylesが文字列タイプである場合、以下の文styles=stylesがある.trim().split(/\s*(?::|;)\s*/); trimメソッドを直接使用しているが、ExtはStringに拡張していない.第3編プロトタイプ拡張を覚えていて、Stringにformatメソッドを1つ追加しただけだ.
Ext.applyIf(String, {
    format : function(format){
        var args = Ext.toArray(arguments, 1);
        return format.replace(/\{(\d+)\}/g, function(m, i){
            return args[i];
        });
    }
});

 
これはbugで、trimの様々な実装を参照してください.