(
								十三
								).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
														
																使用指南
														
												
										
								
								系列文章
								
										.
								
						
				
				
						
						 
				
						
						 
				
						
								--声明:该使用指南文章为转载,由于是来源于多次转载,未找到原出处。再次感谢作者与翻译人员。