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

Javascript
javascript innerText和innerHtml应用
图像替换新技术 状态域方法
JavaScript 判断判断某个对象是Object还是一个Array
Extjs 几个方法的讨论
JavaScript 学习笔记(十五)
javascript 匿名函数的理解(透彻版)
Jquery 常用方法经典总结
jquery 批量上传图片实现代码
javascript中的array数组使用技巧
详细讲解JS节点知识
javascript让setInteval里的函数参数中的this指向特定的对象
javaScript 关闭浏览器 (不弹出提示框)
对字符串进行HTML编码和解码的JavaScript函数
javascript 三种编解码方式
js左侧多级菜单动态的解决方案
JavaScript 学习笔记(十六) js事件
JavaScript面向对象之静态与非静态类
javascript两段代码,两个小技巧
js中鼠标滚轮事件详解(firefox多浏览器)
js实现的仿Photoshop鼠标滚轮控制输入框取值(修正兼容Chrome)

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-12   浏览: 71 ::
收藏到网摘: 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这个超级流行的效果库