( 十三 ).Prototype1.5 rc2 ( 1.5 rc2) 版指南最后一篇之 Position
Position 是 prototype 中定義的一個(gè)對(duì)象,提供了操作 DOM 中與位置相關(guān)的方法,要很好的理解元素在頁面中的位置,可以參考這篇文章: Relatively Absolute
具體代碼如下,按照代碼說說,其中英文是作者的注釋,中文紅色的才是偶的說明或翻譯英文的注釋,采用頂式注釋法 ( 注釋在要說明的代碼的上面 ) 說明
? // set to true if needed, warning: firefox performance problems
? // NOT neeeded for page scrolling, only if draggable contained in
? // scrollable elements
? //
只有在使用拖動(dòng)的時(shí)候元素包含在有滾動(dòng)條的元素中才需要設(shè)置為
true
? includeScrollOffsets: false,
? // must be called before calling withinIncludingScrolloffset, every time the
? // page is scrolled
? //
當(dāng)頁面被
scrolled
后,使用
withinIncludingScrolloffset
的時(shí)候需要先調(diào)用這個(gè)方法
? prepare: function() {
??? //
橫向滾動(dòng)條滾動(dòng)的距離
??? this.deltaX =? window.pageXOffset
??????????????? || document.documentElement.scrollLeft
??????????????? || document.body.scrollLeft
??????????????? || 0;
??? //
縱向滾動(dòng)條滾動(dòng)的距離
??? this.deltaY =? window.pageYOffset
??????????????? || document.documentElement.scrollTop
??????????????? || document.body.scrollTop
??????????????? || 0;
? },
//
元素由于滾動(dòng)條偏移的總距離
?
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
,當(dāng)
offsetParent
都沒有滾動(dòng)條時(shí),就是元素在頁面中的位置
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];
? },
//
元素相對(duì)于
containing block("nearest positioned ancestor")
的位置,也就是相對(duì)于最近的一個(gè)
position
設(shè)置為
relative
或者
absolute
的祖先節(jié)點(diǎn)的位置,如果沒有就是相對(duì)于
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
? //
判斷指定的位置是否在元素內(nèi)
? 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
差不多,不過考慮到滾動(dòng)條,也許是在元素上面,但不是直接在上面,因?yàn)闈L動(dòng)條也許已經(jīng)使元素不可見了
?
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
? //
在調(diào)用這個(gè)方法前,必須先調(diào)用
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;
? },
//
返回元素相對(duì)頁面的真實(shí)位置
?
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];
? },
//
設(shè)置
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
設(shè)置為
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
設(shè)置為
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
的所有部分都寫完了,哈哈,越來越佩服自己的耐力了
下一步?jīng)Q定寫寫 Scriptaculous 這個(gè)超級(jí)流行的效果庫
Prototype1.5 的下載為什么不簡(jiǎn)單點(diǎn)
這幾天在論壇和博客上看到很多人問
Prototype1.5
怎么下載,為什么下載這么困難呢?
Prototype
的官方網(wǎng)站是:
http://prototype.conio.net/
,如果你一下子找不到,到
google
上搜索
Prototype
就找到了
下載當(dāng)然要到官方網(wǎng)站下載了,但是問題是
Prototype
官方網(wǎng)站更新太慢,首頁上的下載連接還是
prototype1.4
的,而且只是一個(gè)單獨(dú)的
js
文件
那么怎么下載最新版本的呢?
1
,如果你只想得到一個(gè)單獨(dú)的
js
文件使用的話,其實(shí)官方網(wǎng)站提供了最新版
1.5
的下載
,
下面連接就是下載地址了
http://dev.rubyonrails.org/browser/trunk/railties/html/javascripts/prototype.js?format=raw
2
,如果你想得到詳細(xì)的源文件以及測(cè)試代碼,需要通過
svn
下載:使用下面的命令就可以了:
svn co http://dev.rubyonrails.org/svn/rails/spinoffs/prototype
如果你沒有
svn
的話,我已經(jīng)下載打包了傳到
51js
論壇中,查看下面連接的帖子中有下載的:
http://bbs.51js.com/viewthread.php?tid=65070&highlight=prototype
想必很多
prototype
愛好者都一直在等待著
prototype1.5
的發(fā)布,雖然等待的時(shí)間很長(zhǎng),但是這一令人激動(dòng)的一天終于到來了
因?yàn)榫W(wǎng)友提醒
,今天訪問
prototype
網(wǎng)站,發(fā)現(xiàn)原來的網(wǎng)址已經(jīng)自動(dòng)跳轉(zhuǎn)到新的網(wǎng)站去了,
作者使用了一個(gè)獨(dú)立的域名
http://www.prototypejs.org/
剛才在
google
里搜索
prototype
,發(fā)現(xiàn)搜索結(jié)果中出現(xiàn)的已經(jīng)是新網(wǎng)站了,
google
爬蟲也蠻勤快的嘛
更讓人高興的是,一向被人詬病的文檔問題這一版有了非常大的提高,可以說是有了質(zhì)的飛躍,以前的版本基本上沒有文檔,要使用只有自己理解了,
現(xiàn)在在它的官方網(wǎng)站上有專門的
API
參考以及一些使用的例子,看來作者真正的關(guān)于這個(gè)問題來了,
prototype
愛好者應(yīng)該高興一把了哈哈,趕快到
prototype
官方網(wǎng)站下載了
Engoy
吧
?
?
--聲明:該使用指南文章為轉(zhuǎn)載,由于是來源于多次轉(zhuǎn)載,未找到原出處。再次感謝作者與翻譯人員。