Javascript 为什么jquery position()方法没有setter版本
我目前正在研究jquery,并注意到jquery中的大多数方法都有设置和getter版本。i、 该方法被用作setter或getter,具体取决于传递给该方法的参数的类型/数量 一个例子是 但我也注意到,只有getter版本,而setter版本缺失Javascript 为什么jquery position()方法没有setter版本,javascript,jquery,Javascript,Jquery,我目前正在研究jquery,并注意到jquery中的大多数方法都有设置和getter版本。i、 该方法被用作setter或getter,具体取决于传递给该方法的参数的类型/数量 一个例子是 但我也注意到,只有getter版本,而setter版本缺失 有人知道为什么position()方法没有setter版本吗?我不太确定,但我认为setter版本在某些情况下会很有用。这是因为offset()和position()在用途和引擎盖下都有很大的不同。作者试图用以下方式对此进行解释: .position
有人知道为什么
position()
方法没有setter版本吗?我不太确定,但我认为setter版本在某些情况下会很有用。这是因为offset()
和position()
在用途和引擎盖下都有很大的不同。作者试图用以下方式对此进行解释:
.position()
方法允许我们检索
相对于偏移父元素的元素(特别是其边距框)
(特别是它的填充框,不包括边距和边框)。
将其与检索当前位置的.offset()
进行对比
相对于文档
但最好的解释是,像往常一样,在来源中。非常简单:检查该元素在live DOM中的存在后,将其框与文档框进行比较,按滚动调整:
// If we don't have gBCR, just use 0,0 rather than error
// BlackBerry 5, iOS 3 (original iPhone)
if ( typeof elem.getBoundingClientRect !== "undefined" ) {
box = elem.getBoundingClientRect();
}
win = getWindow( doc );
return {
top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0),
left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
};
(顺便说一句,在2.x branch中更简单;不需要gBCR检查)
现在,仅当目标元素应用了
position:fixed
时,它才相对简单-只需将gBCR结果作为偏移量
否则,事情就会变得一团糟。首先,算法应该定位“真实”偏移父对象-位置不是静态的最接近的前置对象。如果未找到,则使用documentElement
:
// key part of `offsetParent()` method
while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) &&
jQuery.css( offsetParent, "position" ) === "static" ) ) {
offsetParent = offsetParent.offsetParent;
}
return offsetParent || documentElement;
然后代码计算offsetParent
offset-如果它是documentElement
,或者top:0,left:0
,则使用其坐标。别忘了边界
var parentOffset = { top: 0, left: 0 },
// ... later on
if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
parentOffset = offsetParent.offset();
}
// Add offsetParent borders
parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
最后,将比较偏移量-现在还将考虑元素的边距:
// Subtract parent offsets and element margins
// note: when an element has margin: auto the offsetLeft and marginLeft
// are the same in Safari causing offset.left to incorrectly be 0
return {
top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
};
还有谜题的第三部分。以下是关键部分:
// set position first, in-case top/left are set even on static elem
if ( position === "static" ) {
elem.style.position = "relative";
}
curOffset = curElem.offset();
curCSSTop = jQuery.css( elem, "top" );
curCSSLeft = jQuery.css( elem, "left" );
calculatePosition = ( position === "absolute" || position === "fixed" ) &&
jQuery.inArray( "auto", [ curCSSTop, curCSSLeft ] ) > -1;
// need to be able to calculate position if either top or left
// is auto and position is either absolute or fixed
if ( calculatePosition ) {
curPosition = curElem.position();
curTop = curPosition.top;
curLeft = curPosition.left;
} else {
curTop = parseFloat( curCSSTop ) || 0;
curLeft = parseFloat( curCSSLeft ) || 0;
}
// ...
if ( options.top != null ) {
props.top = ( options.top - curOffset.top ) + curTop;
}
if ( options.left != null ) {
props.left = ( options.left - curOffset.left ) + curLeft;
}
// ...
curElem.css( props );
从本质上讲,它还是非常简单的:计算元素的偏移量,并根据差异修改其顶部
和左侧
。复杂部分包括位置的情况:固定
与顶部
或左侧
的自动
值结合使用
当思考设置者的位置时,会出现两个问题。 首先,它应该如何处理静态元素?如上所述,
offset
setter只是将其位置
重写为相对
;我们是否应该采取同样的方法来处理offsetParent
突然的变化
其次,每次调用setter时,它都应该重新计算offsetParent
的填充框。当然,这在很大程度上取决于用例,但是-我们不应该只在元素挂载时进行计算,并在布局更改事件上重做吗?如果我们应该这样做,也许现有的css({top,left})旁边的offset()
setter已经满足了我们的所有需求
这些担忧也许可以解释为什么这个选项还没有在jQuery中实现——尽管它已经在jQuery中实现了。该插件不依赖于其他jQueryUI组件,但大约有500行
如果您确实认为它也应该是jQuery的一部分,只需在jQueryTracker上提出相应的问题;至少我还没有找到。可能是因为和是只读属性,所以如果我们不能设置offsetTop
和offsetLeft
属性,它会有什么影响?如中所示,是否存在设置offsetTop
和offsetLeft
可能有用的实例?因为元素的位置根据css position属性的不同而表现不同,加上jquery具有css位置设置器,因此它无论如何都是多余的,并且会毫无理由地增加库的大小。