2011-01-14 6 views
2

Weiß jemand, wie ich das Äquivalent von jQuery .offset() und ohne eine JavaScript-Bibliothek bekommen kann?Wie kann ich diese jQuery Ergebnisse mit Vanilla JavaScript erhalten?

Für .closest(), wenn ich weiß, wie weit der DOM-Baum zu klettern, kann ich einfach so viele .parentNode s, aber wenn ich nicht weiß, wie weit es geht, bin ich fest.

+2

Blick Der Quellcode einer JavaScript-Bibliothek untersucht dann, wie es gemacht wurde. – Reigel

Antwort

9

jQuery ist Javascript in seinem Kern. Sie können diese jQuery source viewer verwenden, um die Implementierung einer beliebigen Methode zu ermitteln.

Zum Beispiel, hier ist, wie closest implementiert:

closest: function(selectors, context) { 
    var ret = [], i, l, cur = this[0]; 

    if (jQuery.isArray(selectors)) { 
     var match, selector, 
      matches = {}, 
      level = 1; 

     if (cur && selectors.length) { 
      for (i = 0, l = selectors.length; i < l; i++) { 
       selector = selectors[i]; 

       if (!matches[selector]) { 
        matches[selector] = jQuery.expr.match.POS.test(selector) ? 
         jQuery(selector, context || this.context) : 
         selector; 
       } 
      } 

      while (cur && cur.ownerDocument && cur !== context) { 
       for (selector in matches) { 
        match = matches[selector]; 

        if (match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match)) { 
         ret.push({ selector: selector, elem: cur, level: level }); 
        } 
       } 

       cur = cur.parentNode; 
       level++; 
      } 
     } 

     return ret; 
    } 

    var pos = POS.test(selectors) ? 
     jQuery(selectors, context || this.context) : null; 

    for (i = 0, l = this.length; i < l; i++) { 
     cur = this[i]; 

     while (cur) { 
      if (pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors)) { 
       ret.push(cur); 
       break; 

      } else { 
       cur = cur.parentNode; 
       if (!cur || !cur.ownerDocument || cur === context) { 
        break; 
       } 
      } 
     } 
    } 

    ret = ret.length > 1 ? jQuery.unique(ret) : ret; 

    return this.pushStack(ret, "closest", selectors); 
} 

Und hier ist die Umsetzung des offset:

jQuery.fn.offset = function(options) { 
    var elem = this[0], box; 

    if (options) { 
     return this.each(function(i) { 
      jQuery.offset.setOffset(this, options, i); 
     }); 
    } 

    if (!elem || !elem.ownerDocument) { 
     return null; 
    } 

    if (elem === elem.ownerDocument.body) { 
     return jQuery.offset.bodyOffset(elem); 
    } 

    try { 
     box = elem.getBoundingClientRect(); 
    } catch(e) {} 

    var doc = elem.ownerDocument, 
     docElem = doc.documentElement; 

    // Make sure we're not dealing with a disconnected DOM node 
    if (!box || !jQuery.contains(docElem, elem)) { 
     return box || { top: 0, left: 0 }; 
    } 

    var body = doc.body, 
     win = getWindow(doc), 
     clientTop = docElem.clientTop || body.clientTop || 0, 
     clientLeft = docElem.clientLeft || body.clientLeft || 0, 
     scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop), 
     scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft), 
     top = box.top + scrollTop - clientTop, 
     left = box.left + scrollLeft - clientLeft; 

    return { top: top, left: left }; 
}; 
+0

Okay, also für '.offset()' kann ich 'myElement.getBoundingClientRect() verwenden. Top + document.body.scrollTop - document.body.clientTop;' (Zumindest in Chrome) dann? – Kerrick

+11

großartig, um auf jQuery-Quelle verweisen, jedoch verwendet diese Quelle eine andere jQuery-Funktionen, die diese Antwort meiner Meinung nach nicht optimal macht. Es wäre besser, nur die einfachste Logik zu setzen, um das zu erreichen. – alexserver

1

lesen Quelle von jQuery:

Für die .closest() Sie können eine Schleife über parentNode machen und anhalten, wo Ihr nächstes Elternteil gleich dem Fenster ist.

2

Warum nicht eine Bibliothek verwenden? Ich nehme an, es könnte einen Grund geben, das eigene zu schreiben, aber es wird wahrscheinlich nicht so gut sein wie das von jQuery.

Mein crappy wenig fünf Minuten Implementierung von Offset wie folgt aussieht:

function getOffset(elem) { 
    var offset = null; 
    if (elem) { 
     offset = {left: 0, top: 0}; 
     do { 
      offset.top += elem.offsetTop; 
      offset.left += elem.offsetLeft; 
      elem = elem.offsetParent; 
     } while (elem); 
    } 
    return offset; 
} 
2

Der einfachste Weg, um einen Baum zu Fuß bis die n tief ist, wo Sie nicht wissen, n Rekursion ist, und nicht Looping. Dann wieder auf einen Baum zu gehen, ohne zu wissen, dass seine Wurzel ist, scheint eine bizarre Situation zu sein, und nicht eine, der du wahrscheinlich begegnen wirst, wenn du das DOM begleitest.

Irgendwann Sie den Body-Tag getroffen werden und dann haben Sie nirgendwo gehen links, wenn Sie in einem Iframe sind, in dem Fall, dass Sie für das obere Fenster zu suchen wollen und document.body es findet

Verwandte Themen