当前位置: 首页 > 图文教程 > 网络编程 > Javascript > Prototype1.5 rc2版指南最后一篇之Position

Javascript
jQuery中isFunction方法的BUG修复
将函数的实际参数转换成数组的方法
javascript 删除数组中重复项(uniq)
js 巧妙去除数组中的重复项
javascript下一种表单元素获取方法存在的问题
javascript 三种数组复制方法的性能对比
js 多层叠的TAB选项卡
javascript 自动标记来自搜索结果页的关键字
起点页面传值js,有空研究学习下
javascript 的Document属性和方法集合
JavaScript 使用简略语法创建对象的代码
使用JQuery进行跨域请求
jquery 经典动画菜单效果代码
jquery 常用操作方法
js提示信息jtip封装代码,可以是图片或文章
javascript面向对象的方式实现的弹出层效果代码
jquery中的sortable排序之后的保存状态的解决方法
js或css实现滚动广告的几种方案
使用JavaScript库还是自己写代码?
js 右键菜单,支持不同对象不同菜单(兼容IE、Firefox)

Javascript 中的 Prototype1.5 rc2版指南最后一篇之Position


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-12   浏览: 68 ::
收藏到网摘: n/a

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这个超级流行的效果库