(
十三
).Prototype1.5 rc2
(
1.5 rc2)
版指南最后一篇之
Position
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
这个超级流行的效果库
Prototype1.5
的下载为什么不简单点
这几天在论坛和博客上看到很多人问
Prototype1.5
怎么下载,为什么下载这么困难呢?
Prototype
的官方网站是:
http://prototype.conio.net/
,如果你一下子找不到,到
google
上搜索
Prototype
就找到了
下载当然要到官方网站下载了,但是问题是
Prototype
官方网站更新太慢,首页上的下载连接还是
prototype1.4
的,而且只是一个单独的
js
文件
那么怎么下载最新版本的呢?
1
,如果你只想得到一个单独的
js
文件使用的话,其实官方网站提供了最新版
1.5
的下载
,
下面连接就是下载地址了
http://dev.rubyonrails.org/browser/trunk/railties/html/javascripts/prototype.js?format=raw
2
,如果你想得到详细的源文件以及测试代码,需要通过
svn
下载:使用下面的命令就可以了:
svn co http://dev.rubyonrails.org/svn/rails/spinoffs/prototype
如果你没有
svn
的话,我已经下载打包了传到
51js
论坛中,查看下面连接的帖子中有下载的:
http://bbs.51js.com/viewthread.php?tid=65070&highlight=prototype
想必很多
prototype
爱好者都一直在等待着
prototype1.5
的发布,虽然等待的时间很长,但是这一令人激动的一天终于到来了
因为网友提醒
,今天访问
prototype
网站,发现原来的网址已经自动跳转到新的网站去了,
作者使用了一个独立的域名
http://www.prototypejs.org/
刚才在
google
里搜索
prototype
,发现搜索结果中出现的已经是新网站了,
google
爬虫也蛮勤快的嘛
更让人高兴的是,一向被人诟病的文档问题这一版有了非常大的提高,可以说是有了质的飞跃,以前的版本基本上没有文档,要使用只有自己理解了,
现在在它的官方网站上有专门的
API
参考以及一些使用的例子,看来作者真正的关于这个问题来了,
prototype
爱好者应该高兴一把了哈哈,赶快到
prototype
官方网站下载了
Engoy
吧
如果感觉阅读英文是一种折磨的话,可以参考我以前写的
prototype 1.5
使用指南
系列文章
.
--声明:该使用指南文章为转载,由于是来源于多次转载,未找到原出处。再次感谢作者与翻译人员。