Prototype1.5 rc2版指南最后一篇之Position_Javascript教程-查字典教程网
Prototype1.5 rc2版指南最后一篇之Position
Prototype1.5 rc2版指南最后一篇之Position
发布时间:2017-01-14 来源:查字典编辑
摘要:Position是prototype中定义的一个对象,提供了操作DOM中与位置相关的方法,要很好的理解元素在页面中的位置,可以参考这篇文章:...

Position是prototype中定义的一个对象,提供了操作DOM中与位置相关的方法,要很好的理解元素在页面中的位置,可以参考这篇文章:Relatively Absolute

具体代码如下,按照代码说说,其中英文是作者的注释,中文红色的才是偶的说明或翻译英文的注释,采用顶式注释法(注释在要说明的代码的上面)说明

// set to true if needed, warning: firefox performance problems

// NOT neeeded for page scrolling, only if draggable contained in

// scrollable elements

//只有在使用拖动的时候元素包含在有滚动条的元素中才需要设置为true

includeScrollOffsets: false,

// must be called before calling withinIncludingScrolloffset, every time the

// page is scrolled

//当页面被scrolled后,使用withinIncludingScrolloffset的时候需要先调用这个方法

prepare: function() {

//横向滚动条滚动的距离

this.deltaX = window.pageXOffset

|| document.documentElement.scrollLeft

|| document.body.scrollLeft

|| 0;

//纵向滚动条滚动的距离

this.deltaY = window.pageYOffset

|| document.documentElement.scrollTop

|| document.body.scrollTop

|| 0;

},

//元素由于滚动条偏移的总距离

realOffset: function(element) {

var valueT = 0, valueL = 0;

do {

valueT += element.scrollTop || 0;

valueL += element.scrollLeft || 0;

element = element.parentNode;

} while (element);

return [valueL, valueT];

},

//元素在页面中由offsetParent累积的offset,当offsetParent都没有滚动条时,就是元素在页面中的位置

cumulativeOffset: function(element) {

var valueT = 0, valueL = 0;

do {

valueT += element.offsetTop || 0;

valueL += element.offsetLeft || 0;

element = element.offsetParent;

} while (element);

return [valueL, valueT];

},

//元素相对于containing block("nearest positioned ancestor")的位置,也就是相对于最近的一个position设置为relative或者absolute的祖先节点的位置,如果没有就是相对于body的位置,跟style.top,style.left一样?

positionedOffset: function(element) {

var valueT = 0, valueL = 0;

do {

valueT += element.offsetTop || 0;

valueL += element.offsetLeft || 0;

element = element.offsetParent;

if (element) {

if(element.tagName=='BODY') break;

var p = Element.getStyle(element, 'position');

if (p == 'relative' || p == 'absolute') break;

}

} while (element);

return [valueL, valueT];

},

//offsetParent

offsetParent: function(element) {

if (element.offsetParent) return element.offsetParent;

if (element == document.body) return element;

while ((element = element.parentNode) && element != document.body)

if (Element.getStyle(element, 'position') != 'static')

return element;

return document.body;

},

// caches x/y coordinate pair to use with overlap

//判断指定的位置是否在元素内

within: function(element, x, y) {

if (this.includeScrollOffsets)

return this.withinIncludingScrolloffsets(element, x, y);

this.xcomp = x;

this.ycomp = y;

this.offset = this.cumulativeOffset(element);

return (y >= this.offset[1] &&

y < this.offset[1] + element.offsetHeight &&

x >= this.offset[0] &&

x < this.offset[0] + element.offsetWidth);

},

//跟within差不多,不过考虑到滚动条,也许是在元素上面,但不是直接在上面,因为滚动条也许已经使元素不可见了

withinIncludingScrolloffsets: function(element, x, y) {

var offsetcache = this.realOffset(element);

this.xcomp = x + offsetcache[0] - this.deltaX;

this.ycomp = y + offsetcache[1] - this.deltaY;

this.offset = this.cumulativeOffset(element);

return (this.ycomp >= this.offset[1] &&

this.ycomp < this.offset[1] + element.offsetHeight &&

this.xcomp >= this.offset[0] &&

this.xcomp < this.offset[0] + element.offsetWidth);

},

// within must be called directly before

//在调用这个方法前,必须先调用within,返回在with指定的位置在水平或者垂直方向上占用的百分比

overlap: function(mode, element) {

if (!mode) return 0;

if (mode == 'vertical')

return ((this.offset[1] + element.offsetHeight) - this.ycomp) /

element.offsetHeight;

if (mode == 'horizontal')

return ((this.offset[0] + element.offsetWidth) - this.xcomp) /

element.offsetWidth;

},

//返回元素相对页面的真实位置

page: function(forElement) {

var valueT = 0, valueL = 0;

var element = forElement;

do {

valueT += element.offsetTop || 0;

valueL += element.offsetLeft || 0;

// Safari fix

if (element.offsetParent==document.body)

if (Element.getStyle(element,'position')=='absolute') break;

} while (element = element.offsetParent);

element = forElement;

do {

if (!window.opera || element.tagName=='BODY') {

valueT -= element.scrollTop || 0;

valueL -= element.scrollLeft || 0;

}

} while (element = element.parentNode);

return [valueL, valueT];

},

//设置target为source的位置,大小

clone: function(source, target) {

var options = Object.extend({

setLeft: true,

setTop: true,

setWidth: true,

setHeight: true,

offsetTop: 0,

offsetLeft: 0

}, arguments[2] || {})

// find page position of source

source = $(source);

var p = Position.page(source);

// find coordinate system to use

target = $(target);

var delta = [0, 0];

var parent = null;

// delta [0,0] will do fine with position: fixed elements,

// position:absolute needs offsetParent deltas

if (Element.getStyle(target,'position') == 'absolute') {

parent = Position.offsetParent(target);

delta = Position.page(parent);

}

// correct by body offsets (fixes Safari)

if (parent == document.body) {

delta[0] -= document.body.offsetLeft;

delta[1] -= document.body.offsetTop;

}

// set position

if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';

if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';

if(options.setWidth) target.style.width = source.offsetWidth + 'px';

if(options.setHeight) target.style.height = source.offsetHeight + 'px';

},

//将element的position设置为absolute的模式

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';;

},

//将element的position设置为absolute的模式

relativize: function(element) {

element = $(element);

if (element.style.position == 'relative') return;

Position.prepare();

element.style.position = 'relative';

var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);

var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

element.style.top = top + 'px';

element.style.left = left + 'px';

element.style.height = element._originalHeight;

element.style.width = element._originalWidth;

}

}

// Safari returns margins on body which is incorrect if the child is absolutely

// positioned. For performance reasons, redefine Position.cumulativeOffset for

// KHTML/WebKit only.

if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {

Position.cumulativeOffset = function(element) {

var valueT = 0, valueL = 0;

do {

valueT += element.offsetTop || 0;

valueL += element.offsetLeft || 0;

if (element.offsetParent == document.body)

if (Element.getStyle(element, 'position') == 'absolute') break;

element = element.offsetParent;

} while (element);

return [valueL, valueT];

}

}

终于把Prototype的所有部分都写完了,哈哈,越来越佩服自己的耐力了

下一步决定写写Scriptaculous这个超级流行的效果库

相关阅读
推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  • 最新Javascript教程学习
    热门Javascript教程学习
    编程开发子分类