2

簡略化されたサンプル コード:

var $ = function(selector, node) { // Selector engine
    var selector = selector.trim(), node = node || document.body;
    if (selector != null) {
        return Array.prototype.slice.call(node.querySelectorAll(selector), 0); }
    }
}

私はこのようにそれを使用したい...:

$("div").innerHTML='It works!';

...このようではありません...:

$("div")[0].innerHTML='It works only on the specified index!';

...またはこれ:

for(i=0;i<$('div');i++) {
        $("div")[i].innerHTML='It works great but it's ugly!';
}

これは私が得たのと同じくらい近いです。チェーンを機能させ、ネイティブメソッドと互換性を持たせたい:

if(!Array.prototype.innerHTML) { 
    Array.prototype.innerHTML = function(html) {
        for (var i = 0; i < this.length; i++) {
            this[i].innerHTML = html;
        }
    }
}

$("div").innerHTML('It works, but it ruins method chaining!');

JavaScript をよりよく学習するために、このエンジンを作成することにしました。うまくいっていますが、スタック オーバーフローの親切なメンバーからもっと学べることを願っています。どんな助けでも大歓迎です!

4

2 に答える 2

4

このように使いたい…:

$("div").innerHTML='It works!';

...このようではありません...:

$("div")[0].innerHTML='It works only on the specified index!';

innerHTML結果のセットに割り当てて、すべての結果のにinnerHTML割り当てたいようです。

そのためには、直接または間接的に関数を使用する必要があります。

直接:

var $ = function(selector, node) { // Selector engine
    var selector = selector.trim(),
        node = node || document.body,
        rv;
    if (selector != null) {
        rv = Array.prototype.slice.call(node.querySelectorAll(selector), 0); }
        rv.setInnerHTML = setInnerHTML;
    }
    return rv;
}
function setInnerHTML(html) {
    var index;

    for (index = 0; index < this.length; ++index) {
        this[index].innerHTML = html;
    }
}

// Usage
$("div").setInnerHTML("The new HTML");

そこで、関数を定義し、それをプロパティとして返す配列に割り当てます。次に、配列でその関数を呼び出すことができます。(プロパティObject.definePropertyを設定できる場合は使用することをお勧めしsetInnerHTMLます。そうすれば、列挙できないようにすることができます。)

間接的に(ES5対応のJavaScriptエンジンが必要です):

var $ = function(selector, node) { // Selector engine
    var selector = selector.trim(),
        node = node || document.body,
        rv;
    if (selector != null) {
        rv = Array.prototype.slice.call(node.querySelectorAll(selector), 0); }
        Object.defineProperty(rv, "innerHTML", {
            set: setInnerHTML
        });
    }
    return rv;
}
function setInnerHTML(html) {
    var index;

    for (index = 0; index < this.length; ++index) {
        this[index].innerHTML = html;
    }
}

// Usage
$("div").innerHTML = "The new HTML";

そこで、Object.definePropertyプロパティのセッターを定義するために使用します。

以下のコメントであなたは言います

$関数に個別にアタッチすると機能するプロトタイプがいくつかあります。例:$('div').makeClass('this');チェーンされている場合は機能しません。例:$('div').makeClass('this').takeClass('that');

連鎖を機能させるにはreturn this;、各関数から実行します(したがって、の終わりmakeClassは実行しますreturn this;)。これは、のように連鎖しているときに、の戻り値をobj.foo().bar()呼び出しているためです。したがって、チェーンを機能させるには、必ずリターン(呼び出されたオブジェクト)を確認します。barfoofoothisfoo

于 2012-12-09T07:47:53.547 に答える
0

これが機能します。前の例で示した構文とは少し異なりますが、最終的な結果は同じです。他の Stack Exchange メンバーからも大きな助けを得ることができました。

var $ = function(selector, node) { // Selector engine
    var selector = selector.trim(), node = node || document.body;
    if (selector != null) {
        return Array.prototype.slice.call(node.querySelectorAll(selector), 0); }
    }
}

if(!Array.prototype.html) { 
    Array.prototype.html = function(html) {
        for (var i = 0; i < this.length; i++) {
            this[i].innerHTML = html;
        }
        return this; //<---- Silly me, my original code was missing this.
    }
}

実行すると、すべて (チェーンを含む) が希望どおりに機能します。

$("div").html('hello world');

出力:

<div>hello world</div>

乾杯!

于 2012-12-10T02:11:24.000 に答える