2015-04-15 6 views
5

1) Ich habe eine Aufgabe, jQuery in Javascript zu implementieren. Aber aus irgendeinem Grund funktioniert meine Methode nicht. Zum Beispiel, wenn ich schreibewinzige Implementierung von jquery

$('.a').each(function (index) {$(this).append('<b>' + index + '</b>')}) 

es gibt

DOMException: Fehler beim Ausführen 'querySelectorAll' auf 'Document': '[object Object]' ist kein gültiger Selektor.

auch ich kann this.each innerhalb anderer Funktionen nicht verwenden. Zum Beispiel, wenn ich jedes anstelle von forEach innerhalb des Anhangs verwendet hätte, hätte es nicht funktioniert.


<script type="text/javascript"> 
(function() { 
    function $(selector) { 
    if (this instanceof $) return this.search(selector) 
     return new $(selector); 
    } 
    $.prototype = { 
    constructor: $, 
    length: 0, 

    search: function(selector) { 
     var that=this; 
     var elems=Array.prototype.slice 
      .call(document.querySelectorAll(selector)); 
     elems.forEach(function(x,i){that[i]=x;}); 
     this.length = elems.length; 
     return this; 
    }, 

    append: function(text) { 
     if (text instanceof $) { 
     this[0].appendChild(text[0]); 
     for(var i = 1; i < this.length-1; i++) { 
      var p = text[0].cloneNode(true); 
      this[i].appendChild(p); 
     } 
     } else Array.prototype.slice 
      .call(this).forEach(function(x){ 
       x.innerHTML = x.innerHTML + text; 
      }); 

     return this; 
    }, 

    each: function(callback){ 
     for (var i=0;i<this.length;i++){ 
     this[i]=callback.call(this,this[i]) 
     }; 
     return this; 
    }, 

    } 
    window.$ = $; 
}()); 

+3

* „ich eine Aufgabe habe jQuery Javascript zu implementieren“ * Er .... jQuery * ** ist *** "on" (in) JavaScript implementiert. –

+0

es arbeitet an Geige ist hier [demo] (http://jsfiddle.net/n4aspu8p/) – ozil

+7

By the way FYI mit der '.each()' Methode auf einen Selektor, der eine '# id' (was ein einzelnes Element ist) macht überhaupt keinen Sinn. –

Antwort

5

Zum Beispiel, wenn ich schreibe

$('#id').each(function (index) {$(this).html('<b>' + index + '</b>')}) 

es gibt

DOMException: Fehler beim Ausführen 'querySelectorAll' auf 'Document': ‚[object Objekt] 'ist kein gültiger Selektor.

Sie tun $(this) in Ihrem each Rückruf. So ruft $ mit this auf das DOM-Element, das nicht instanceof $ ist, und so rufen Sie new $(selector) übergeben das DOM-Element. Das ruft this.search(selector) auf, wo wiederum selector das DOM-Element ist. Dann rufen Sie querySelectorAll(selector) an. QSA akzeptiert Zeichenketten, nicht DOM-Elemente, und so wird das Element in die Zeichenkette "[object Object]" konvertiert (oder bei einigen Engines ist es "[object HTMLElement]") und schlägt fehl.

Sie können diese Fehler diagnostizieren, indem Sie mit dem in Ihrem Browser integrierten Debugger den Code-Anweisung-für-Anweisung-Code durchlaufen. Wenn Sie jQuery aus irgendeinem Grund neu implementieren möchten, müssen Sie sich angewöhnen, genau das zu tun: Debugger stark zu verwenden, Fehler zu identifizieren und zu beheben.

In diesem Fall möchten Sie zum Beispiel erkennen, dass selector keine Zeichenfolge ist und behandeln, dass z. etwas vage wie folgt aus:

search: function(selector) { 
    var that=this, elems; 
    if (typeof selector === "string") { 
    elems = Array.prototype.slice.call(document.querySelectorAll(selector)); 
    elems.forEach(function(x,i){that[i]=x;}); 
    this.length = elems.length; 
    } else { 
    this[0] = selector; 
    this.length = 1; 
    } 
    return this; 
}, 

Aber es wird viele, viele andere Dinge, die Sie in darüber hinaus laufen werde, mit dem Sie Ihren Debugger benötigen für.

+0

Ich kann nicht verstehen, warum, wenn ich außerhalb einer Append-Funktion gehe das sieht ok aus, aber nächsten Schritt kommt es zu jeder Funktion und jetzt ist diese [0] undefiniert. – Aleks

+0

Ich habe verstanden! Meine Funktion wurde nicht richtig geschrieben! – Aleks

+0

Ich habe noch 1 Frage! Wenn ich .children() Funktion schreibe, will ich, dass 'dieses geändert wird, und es zurückzugeben. Bin ich richtig, wenn ich alle Eigenschaften lösche: 0,1,2 ... bis Länge in 'diesem' und dann ersetze sie durch neue, die Kinder davon sind? Oder gibt es elegantere Methode, dies zu tun? – Aleks

0

Dies wird für Ihre usecase arbeiten, aber alle Grenzfälle zu implementieren wäre ein bisschen komplizierter:

(function() { 
    function $(selector) { 
    if (!(this instanceof $)){//forgot new 
     return new $(selector); 
    } 
    if(typeof selector === 'string'){ 
     return this.search(selector); 
    } 
    //assuming selector is a dom object 
    this[0]=selector; 
    this.length=1; 
    } 
    $.prototype = { 
    constructor: $, 
    length: 0, 

    search: function(selector) { 
     var that=this; 
     var elems=Array.prototype.slice 
      .call(document.querySelectorAll(selector)); 
     elems.forEach(function(x,i){that[i]=x;}); 
     this.length = elems.length; 
     return this; 
    }, 
    append: function(text) { 
     if (text instanceof $) { 
     this[0].appendChild(text[0]); 
     for(var i = 1; i < this.length-1; i++) { 
      var p = text[0].cloneNode(true); 
      this[i].appendChild(p); 
     } 
     } else { 
      this.each(function(x){ 
       this.innerHTML = this.innerHTML + text; 
      }); 
     } 
     return this; 
    }, 
    // callback is called with the invoking object to be the dom element 
    each: function(callback){ 
     for (var i=0;i<this.length;i++){ 
     this[i]=callback.call(this[i],i); 
     }; 
     return this; 
    }, 

    } 
    window.$ = $; 
}()); 
$('.a').each(function (index) {return $(this).append('<b>' + index + '</b>')}) 
+0

Ihre Antwort ist sehr hilfreich, aber auch jede Funktion sollte so geändert werden, dass Sie nur Callback aufrufen, aber nicht diesem zuweisen [i] – Aleks