有人知道如何在没有JavaScript库的情况下获得jQuery的.offset()和.closest()的等价物吗?
对于.closest(),如果我知道在DOM树上爬多远,我就可以使用那么多的.parentNode,但是如果我不知道要爬多远,我就卡住了。
发布于 2011-01-14 17:48:29
jQuery的核心是javascript。您可以使用此jQuery source viewer来查找任何方法的实现。
例如,closest是如何实现的:
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 );
}下面是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 };
};发布于 2011-01-14 18:25:53
为什么不使用库呢?我想您编写自己的代码可能是有原因的,但它可能不会像jQuery那样好。
我的offset的5分钟实现看起来很糟糕:
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;
}发布于 2011-01-14 18:35:30
在不知道n的深度的树上遍历n的最简单方法是递归,而不是循环。同样,在不知道树的根的情况下爬到树上似乎是一种奇怪的情况,在遍历DOM时不太可能遇到这种情况。
在某些时候,你会点击body标签,然后你就无处可去了,除非你在一个iframe中,在这种情况下,你想要寻找顶部窗口,发现它是document.body
https://stackoverflow.com/questions/4689701
复制相似问题