不好意思,说反了:是当标签处于另一个标签中时,如果这个标签有滚动(auto),那它的坐标定位怎么改也是绝对定位,而无法使用相对定位处理我用的是prototype中的Postion的两个方法:relativize和absolutize。
先absolutize后,移动拖动对象,然后再relativize回去时,如果没有滚动条,则能正确显示在我放置的位置,当有滚动条时,则会是:放置的位置-滚动条的那个层与页面top和left的偏移量
先absolutize后,移动拖动对象,然后再relativize回去时,如果没有滚动条,则能正确显示在我放置的位置,当有滚动条时,则会是:放置的位置-滚动条的那个层与页面top和left的偏移量
absolute :Object is positioned relative to parent element's position—or to the body object if its parent element is not positioned—using the top and left properties.
经过测试,如果标签的所有祖先节点中,有任何一个是可滚动的(overflow,overflow-y,overflow-x其中一个属性的值为auto或scroll),那标签的绝对定位就是在此标签中的坐标位置,而不是对于BODY的。而prototype1.4在实现Position.absolutize方法时是这样写的:
Position.absolutize = function(element) {
element = $(element);
if (element.style.position == 'absolute') return;
Position.prepare();
var offsets = Position.positionedOffset(element); var top = offsets[1];
var left = offsets[0];
var width = element.clientWidth;
var height = element.clientHeight; element._originalLeft = left - parseFloat(element.style.left || 0);
element._originalTop = top - parseFloat(element.style.top || 0);
element._originalWidth = element.style.width;
element._originalHeight = element.style.height; element.style.position = 'absolute';
element.style.top = top + 'px';
element.style.left = left + 'px';
element.style.width = width + 'px';
element.style.height = height + 'px';
};
其中Position.positionedOffset就是取当前标签到body的偏移量,然后将信息存入_original*的相关属性中,等到调用Position.relativize时,再从这些_original*属性中从新计算出当前标签的相对位置。再看一下Position.positionedOffset的实现:
Position.positionedOffset = function (element) {
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
if (element) {
p = Element.getStyle(element, "position");
if (p == "relative" || p == "absolute") {
break;
}
}
} while (element);
return [valueL, valueT];
};
更改中间判断中断的部分为:
if (element) {
var scrollable = [element.style.overflow, element.style.overflowX, element.style.overflowY];
p = Element.getStyle(element, "position");
if (p == "relative" || p == "absolute" || scrollable.contains( "auto" ) || scrollable.contains( "scroll" )) {
break;
}
}
更改后位置处理的问题的解决了,下面的用于测试的HTML:
<div style="width:500px;overflow-y:auto;height:300px">
<div style="height:200px">
</div>
<div style="height:300px">
<div id="test" style="height:20px">test</div>
<input type="button" value="abs" onclick="Position.absolutize(${'test'});">
<input type="button" value="rel" onclick="Position.relativize(${'test'});">
</div>
</div>
<div style="width:500px;overflow-y:auto;height:300px">
<div id="test1" style="height:20px">test</div>
<input type="button" value="abs" onclick="Position.absolutize(${'test1'});">
<input type="button" value="rel" onclick="Position.relativize(${'test1'});">
</div>
此问题还有待进一步测试,如果没问题了就来结贴