Tin's Blog

You are coming a long way, baby~Thinking, feeling, memory...

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  128 随笔 :: 0 文章 :: 221 评论 :: 0 Trackbacks
这两天太忙了,没时间写Blog,业余时间又扒了一次google的拖拽,对比了netvibes的,差不多,让后就写了个注释,顺便学习。
google用了混淆,js里面的命名比较晕。我花了些时间把他们翻译成容易看懂的命名,并且作了注释,希望对大家有帮助。
可以这里下载我的例子:
http://www.blogjava.net/Files/iamtin/google_drag.rar

// 工具类,使用Util的命名空间,方便管理
var  Util  =   new  Object();
// 获取http header里面的UserAgent,浏览器信息
Util.getUserAgent  =  navigator.userAgent;
// 是否是Gecko核心的Browser,比如Mozila、Firefox
Util.isGecko  =  Util.getUserAgent.indexOf( " Gecko " !=   - 1 ;
// 是否是Opera
Util.isOpera  =  Util.getUserAgent.indexOf( " Opera " !=   - 1 ;
// 获取一个element的offset信息,其实就是相对于Body的padding以内的绝对坐标
//
后面一个参数如果是true则获取offsetLeft,false则是offsetTop
//
关于offset、style、client等坐标的定义参考dindin的这个帖子:http://www.jroller.com/page/dindin/?anchor=pro_javascript_12
Util.getOffset  =   function  (el, isLeft) {
    
var  retValue  =   0 ;
    
while  (el  !=   null ) {
        retValue 
+=  el[ " offset "   +  (isLeft  ?   " Left "  :  " Top " )];
        el 
=  el.offsetParent;
    }
    
return  retValue;
};
// 将一个function(参数中的funcName是这个fuction的名字)绑定到一个element上,并且以这个element的上下文运行,其实是一种继承,这个可以google些文章看看
Util.bindFunction  =   function  (el, fucName) {
    
return   function  () {
        
return  el[fucName].apply(el, arguments);
    };
};
// 重新计算所有的可以拖拽的element的坐标,对同一个column下面的可拖拽图层重新计算它们的高度而得出新的坐标,防止遮叠
//
计算出来的坐标记录在pagePosLeft和pagePosTop两个属性里面
Util.re_calcOff  =   function  (el) {
    
for  ( var  i  =   0 ; i  <  Util.dragArray.length; i ++ ) {
        
var  ele  =  Util.dragArray[i];
        ele.elm.pagePosLeft 
=  Util.getOffset(ele.elm,  true );
        ele.elm.pagePosTop 
=  Util.getOffset(ele.elm,  false );
    }
    
var  nextSib  =  el.elm.nextSibling;
    
while  (nextSib) {
        nextSib.pagePosTop 
-=  el.elm.offsetHeight;
        nextSib 
=  nextSib.nextSibling;
    }
};

// 隐藏Google Ig中间那个table,也就是拖拽的容器,配合show一般就是刷新用,解决一些浏览器的怪癖
Util.hide  =   function  () {
    Util.rootElement.style.display 
=   " none " ;
};
// 显示Google Ig中间那个table,解释同上
Util.show  =   function  () {
    Util.rootElement.style.display 
=   "" ;
};

// 移动时显示的占位虚线框
ghostElement  =   null ;
// 获取这个虚线框,通过dom动态生成
getGhostElement  =   function  () {
    
if  ( ! ghostElement) {
        ghostElement 
=  document.createElement( " DIV " );
        ghostElement.className 
=   " modbox " ;
        ghostElement.backgroundColor 
=   "" ;
        ghostElement.style.border 
=   " 2px dashed #aaa " ;
        ghostElement.innerHTML 
=   " &nbsp; " ;
    }
    
return  ghostElement;
};

// 初始化可以拖拽的Element的函数,与拖拽无关的我去掉了
function  draggable(el) {
    
// 公用的开始拖拽的函数
     this ._dragStart  =  start_Drag;
    
// 公用的正在拖拽的函数
     this ._drag  =  when_Drag;
    
// 公用的拖拽结束的函数
     this ._dragEnd  =  end_Drag;
    
// 这个函数主要用来进行拖拽结束后的dom处理
     this ._afterDrag  =  after_Drag;
    
// 是否正在被拖动,一开始当然没有被拖动
     this .isDragging  =   false ;
    
// 将这个Element的this指针注册在elm这个变量里面,方便在自己的上下文以外调用自己的函数等,很常用的方法
     this .elm  =  el;
    
// 触发拖拽的Element,在这里就是这个div上显示标题的那个div
     this .header  =  document.getElementById(el.id  +   " _h " );
    
// 对于有iframe的element拖拽不同,这里检测一下并记录
     this .hasIFrame  =   this .elm.getElementsByTagName( " IFRAME " ).length  >   0 ;
    
// 如果找到了header就绑定drag相关的event
     if  ( this .header) {
        
// 拖拽时的叉子鼠标指针
         this .header.style.cursor  =   " move " ;
        
// 将函数绑定到header和element的this上,参照那个函数的说明
        Drag.init( this .header,  this .elm);
        
// 下面三个语句将写好的三个函数绑定给这个elemnt的三个函数钩子上,也就实现了element从draggable继承可拖拽的函数
         this .elm.onDragStart  =  Util.bindFunction( this " _dragStart " );
        
this .elm.onDrag  =  Util.bindFunction( this " _drag " );
        
this .elm.onDragEnd  =  Util.bindFunction( this " _dragEnd " );
    }
};

// 下面就是draggable里面用到的那4个function
//
公用的开始拖拽的函数
function  start_Drag() {
    
// 重置坐标,实现拖拽以后自己的位置马上会被填充的效果
    Util.re_calcOff( this );
    
// 记录原先的邻居节点,用来对比是否被移动到新的位置
     this .origNextSibling  =   this .elm.nextSibling;
    
// 获取移动的时候那个灰色的虚线框
     var  _ghostElement  =  getGhostElement();
    
// 获取正在移动的这个对象的高度
     var  offH  =   this .elm.offsetHeight;
    
if  (Util.isGecko) {
        
// 修正gecko引擎的怪癖吧
        offH  -=  parseInt(_ghostElement.style.borderTopWidth)  *   2 ;
    }
    
// 获取正在移动的这个对象的宽度
     var  offW  =   this .elm.offsetWidth;
    
// 获取left和top的坐标
     var  offLeft  =  Util.getOffset( this .elm,  true );
    
var  offTop  =  Util.getOffset( this .elm,  false );
    
// 防止闪烁,现隐藏
    Util.hide();
    
// 将自己的宽度记录在style属性里面
     this .elm.style.width  =  offW  +   " px " ;
    
// 将那个灰框设定得与正在拖动的对象一样高,比较形象
    _ghostElement.style.height  =  offH  +   " px " ;
    
// 把灰框放到这个对象原先的位置上
     this .elm.parentNode.insertBefore(_ghostElement,  this .elm.nextSibling);
    
// 由于要拖动必须将被拖动的对象从原先的盒子模型里面抽出来,所以设定position为absolute,这个可以参考一下css布局方面的知识
     this .elm.style.position  =   " absolute " ;
    
// 设置zIndex,让它处在最前面一层,当然其实zIndex=100是让它很靠前,如果页面里有zIndex>100的,那……
     this .elm.style.zIndex  =   100 ;
    
// 由于position=absolute了,所以left和top实现绝对坐标定位,这就是先前计算坐标的作用,不让这个模型乱跑,要从开始拖动的地方开始移动
     this .elm.style.left  =  offLeft  +   " px " ;
    
this .elm.style.top  =  offTop  +   " px " ;
    
// 坐标设定完毕,可以显示了,这样就不会闪烁了
    Util.show();
    
// 这里本来有个ig_d.G,没搞明白干什么用的,不过没有也可以用,谁知道麻烦告诉我一声,不好意思
     // 还没有开始拖拽,这里做个记号
     this .isDragging  =   false ;
    
return   false ;
};
// 在拖拽时的相应函数,由于绑定到鼠标的move这个event上,所以会传入鼠标的坐标clientX, clientY
function  when_Drag(clientX, clientY) {
    
// 刚开始拖拽的时候将图层变透明,并标记为正在被拖拽
     if  ( ! this .isDragging) {
        
this .elm.style.filter  =   " alpha(opacity=70) " ;
        
this .elm.style.opacity  =   0.7 ;
        
this .isDragging  =   true ;
    }
    
// 被拖拽到的新的column(当然也可以是原来那个)
     var  found  =   null ;
    
// 最大的距离,可能是防止溢出或者什么bug
     var  max_distance  =   100000000 ;
    
// 遍历所有的可拖拽的element,寻找离当前鼠标坐标最近的那个可拖拽元素,以便后面插入
     for  ( var  i  =   0 ; i  <  Util.dragArray.length; i ++ ) {
        
var  ele  =  Util.dragArray[i];
        
// 利用勾股定理计算鼠标到遍历到的这个元素的距离
         var  distance  =  Math.sqrt(Math.pow(clientX  -  ele.elm.pagePosLeft,  2 +  Math.pow(clientY  -  ele.elm.pagePosTop,  2 ));
        
// 自己已经浮动了,所以不计算自己的
         if  (ele  ==   this ) {
            
continue ;
        }
        
// 如果计算失败继续循环
         if  (isNaN(distance)) {
            
continue ;
        }
        
// 如果更小,记录下这个距离,并将它作为found
         if  (distance  <  max_distance) {
            max_distance 
=  distance;
            found 
=  ele;
        }
    }
    
// 准备让灰框落脚
     var  _ghostElement  =  getGhostElement();
    
// 如果找到了另外的落脚点
     if  (found  !=   null   &&  _ghostElement.nextSibling  !=  found.elm) {
        
// 找到落脚点就先把灰框插进去,这就是我们看到的那个灰框停靠的特效,有点像吸附的感觉,哈哈
        found.elm.parentNode.insertBefore(_ghostElement, found.elm);
        
if  (Util.isOpera) {
            
// Opera的现实问题,要隐藏/显示后才能刷新出变化
            document.body.style.display  =   " none " ;
            document.body.style.display 
=   "" ;
        }
    }
};
// 拖拽完毕
function  end_Drag() {
    
// 拖拽完毕后执行后面的钩子,执行after_Drag(),如果布局发生了变动了就记录到远程服务器,保存你拖拽后新的布局顺序
     if  ( this ._afterDrag()) {
        
// remote call to save the change
    }
    
return   true ;
};
// 拖拽后的执行钩子
function  after_Drag() {
    
var  returnValue  =   false ;
    
// 防止闪烁
    Util.hide();
    
// 把拖拽时的position=absolute和相关的那些style都消除
     this .elm.style.position  =   "" ;
    
this .elm.style.width  =   "" ;
    
this .elm.style.zIndex  =   "" ;
    
this .elm.style.filter  =   "" ;
    
this .elm.style.opacity  =   "" ;
    
// 获取灰框
     var  ele  =  getGhostElement();
    
// 如果现在的邻居不是原来的邻居了
     if  (ele.nextSibling  !=   this .origNextSibling) {
        
// 把被拖拽的这个节点插到灰框的前面
        ele.parentNode.insertBefore( this .elm, ele.nextSibling);
        
// 标明被拖拽了新的地方
        returnValue  =   true ;
    }
    
// 移除灰框,这是这个灰框的生命周期应该就结束了
    ele.parentNode.removeChild(ele);
    
// 修改完毕,显示
    Util.show();
    
if  (Util.isOpera) {
        
// Opera的现实问题,要隐藏/显示后才能刷新出变化
        document.body.style.display  =   " none " ;
        document.body.style.display 
=   "" ;
    }
    
return  returnValue;
};
// 可拖拽Element的原形,用来将event绑定到各个钩子,这部分市比较通用的,netvibes也是基本完全相同的实现
//
这部分推荐看dindin的这个,也会帮助理解,http://www.jroller.com/page/dindin/?anchor=pro_javascript_12
var  Drag  =  {
    
// 对这个element的引用,一次只能拖拽一个Element
    obj: null
    
// element是被拖拽的对象的引用,elementHeader就是鼠标可以拖拽的区域
    init: function  (elementHeader, element) {
        
// 将start绑定到onmousedown事件,按下鼠标触发start
        elementHeader.onmousedown  =  Drag.start;
        
// 将element存到header的obj里面,方便header拖拽的时候引用
        elementHeader.obj  =  element;
        
// 初始化绝对的坐标,因为不是position=absolute所以不会起什么作用,但是防止后面onDrag的时候parse出错了
         if  (isNaN(parseInt(element.style.left))) {
            element.style.left 
=   " 0px " ;
        }
        
if  (isNaN(parseInt(element.style.top))) {
            element.style.top 
=   " 0px " ;
        }
        
// 挂上空Function,初始化这几个成员,在Drag.init被调用后才帮定到实际的函数,可以参照draggable里面的内容
        element.onDragStart  =   new  Function();
        element.onDragEnd 
=   new  Function();
        element.onDrag 
=   new  Function();
    },
    
// 开始拖拽的绑定,绑定到鼠标的移动的event上
    start: function  (event) {
        
var  element  =  Drag.obj  =   this .obj;
        
// 解决不同浏览器的event模型不同的问题
        event  =  Drag.fixE(event);
        
// 看看是不是左键点击
         if  (event.which  !=   1 ) {
            
// 除了左键都不起作用
             return   true ;
        }
        
// 参照这个函数的解释,挂上开始拖拽的钩子
        element.onDragStart();
        
// 记录鼠标坐标
        element.lastMouseX  =  event.clientX;
        element.lastMouseY 
=  event.clientY;
        
// 将Global的event绑定到被拖动的element上面来
        document.onmouseup  =  Drag.end;
        document.onmousemove 
=  Drag.drag;
        
return   false ;
    }, 
    
// Element正在被拖动的函数
    drag: function  (event) {
        
// 解决不同浏览器的event模型不同的问题
        event  =  Drag.fixE(event);
        
// 看看是不是左键点击
         if  (event.which  ==   0 ) {
            
// 除了左键都不起作用
             return  Drag.end();
        }
        
// 正在被拖动的Element
         var  element  =  Drag.obj;
        
// 鼠标坐标
         var  _clientX  =  event.clientY;
        
var  _clientY  =  event.clientX;
        
// 如果鼠标没动就什么都不作
         if  (element.lastMouseX  ==  _clientY  &&  element.lastMouseY  ==  _clientX) {
            
return   false ;
        }
        
// 刚才Element的坐标
         var  _lastX  =  parseInt(element.style.top);
        
var  _lastY  =  parseInt(element.style.left);
        
// 新的坐标
         var  newX, newY;
        
// 计算新的坐标:原先的坐标+鼠标移动的值差
        newX  =  _lastY  +  _clientY  -  element.lastMouseX;
        newY 
=  _lastX  +  _clientX  -  element.lastMouseY;
        
// 修改element的显示坐标
        element.style.left  =  newX  +   " px " ;
        element.style.top 
=  newY  +   " px " ;
        
// 记录element现在的坐标供下一次移动使用
        element.lastMouseX  =  _clientY;
        element.lastMouseY 
=  _clientX;
        
// 参照这个函数的解释,挂接上Drag时的钩子
        element.onDrag(newX, newY);
        
return   false ;
    },
    
// Element正在被释放的函数,停止拖拽
    end: function  (event) {
        
// 解决不同浏览器的event模型不同的问题
        event  =  Drag.fixE(event);
        
// 解除对Global的event的绑定
        document.onmousemove  =   null ;
        document.onmouseup 
=   null ;
        
// 先记录下onDragEnd的钩子,好移除obj
         var  _onDragEndFuc  =  Drag.obj.onDragEnd();
        
// 拖拽完毕,obj清空
        Drag.obj  =   null ;
        
return  _onDragEndFuc;
    }, 
    
// 解决不同浏览器的event模型不同的问题
    fixE: function  (ig_) {
        
if  ( typeof  ig_  ==   " undefined " ) {
            ig_ 
=  window.event;
        }
        
if  ( typeof  ig_.layerX  ==   " undefined " ) {
            ig_.layerX 
=  ig_.offsetX;
        }
        
if  ( typeof  ig_.layerY  ==   " undefined " ) {
            ig_.layerY 
=  ig_.offsetY;
        }
        
if  ( typeof  ig_.which  ==   " undefined " ) {
            ig_.which 
=  ig_.button;
        }
        
return  ig_;
    }
};



// 下面是初始化的函数了,看看上面这些东西怎么被调用
var  _IG_initDrag  =   function  (el) {
    
// column那个容器,在google里面就是那个table布局的tbody,netvibes用的<div>
    Util.rootElement  =  el;
    
// 这个tbody的行
    Util._rows  =  Util.rootElement.tBodies[ 0 ].rows[ 0 ];
    
// 列,google是3列,其实也可以更多
    Util.column  =  Util._rows.cells;
    
// 用来存取可拖拽的对象
    Util.dragArray  =   new  Array();
    
var  counter  =   0 ;
    
for  ( var  i  =   0 ; i  <  Util.column.length; i ++ ) {
        
// 搜索所有的column
         var  ele  =  Util.column[i];
        
for  ( var  j  =   0 ; j  <  ele.childNodes.length; j ++ ) {
            
// 搜索每一column里面的所有element
             var  ele1  =  ele.childNodes[j];
            
// 如果是div就把它初始化为一个draggable对象
             if  (ele1.tagName  ==   " DIV " ) {
                Util.dragArray[counter] 
=   new  draggable(ele1);
                counter
++ ;
            }
        }
    }
};

// google的页面里可以拖动的部分的id是"t_1"
//
挂载到onload,载入完毕执行。不过实际上google没有用onload。
//
而是写在页面最下面,异曲同工吧,也许直接写在页面是种怪癖,或者也有可能是兼容性考虑。

// 请将下面两条被注释掉的代码加,到你自己下载的一个google ig页面里面,把里面的所有其余script删除,挂上这个js也可以拖拽了,哈哈
//
_table=document.getElementById("t_1");
//
window.onload = _IG_initDrag(_table);

// 其实看懂这些代码对学习javascript很有益,希望对大家能有帮助
posted on 2006-04-27 22:40 Tin 阅读(15210) 评论(34)  编辑  收藏 所属分类: 非Java

评论

# re: 对google个性主页的拖拽效果的js的完整注释 2006-05-23 16:20 sillyman
能否说说怎样保存,并且和用户挂钩,使每个用户近来的时候看到的不一样。google这块是怎样实现的呢  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-05-23 16:24 sillyman
每个用户登陆进去看到的都是个性化的界面,这种界面的位置信息我想是应该保存在服务器上的,可是怎样保存的呢,保存在数据库里吗?数据库的表结构又应该是怎样的呢?  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-05-24 10:17 Tin
关于数据保存的问题,其实并不难,因为每次拖拽结束都回得出该div在哪个拖拽区域div里面,顺序也可以通过遍历所在div的childNodes来找到,然后调用一个XmlHttpRequest回去保存就可以了。在数据库里面保存应该只保存位置,然后给每个位置一个id,这个id在对应一个应用(即div里面显示的内容)就可以了。可以参考netvibes,它就是一个id对应一个rss,div里面显示rss的内容就可以了。XmlHttpRequest只需看看Ajax的相关书籍就可以了。推荐Ajax修炼之道和Ajax实战两本书。  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-05-24 14:52 sillyman
楼主能否百忙之余帮俺写出个例子,这方面的知识实在是匮乏,叩谢了!公司的头就想把主页变成这样的,真是难为死我了!  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-05-24 14:54 sillyman
在网上转了两天了,也没找大相应的代码,郁闷死了!  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-05-24 15:03 sillyman
我想可以保存在数据库里,表结构可以这样定义(用户ID,行号,列号,应用ID),如果数据能存成这样,我想就好做了,可是保存的时候怎样得到“行号、列号、和应用号”呢?楼主能否帮写点代码!  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-05-24 17:03 Tin
设计嘛,我想就是那样了。我的注释版把通讯部分删掉了。你可以自己研究一下google的js,很快就能明白了,原理非常简单的。“行号、列号、和应用号”这不是很简单么,你可以将div的id设为数据库中的应用ID。而行号则从div.parentNode里面获取,比如把parentNode的ID写为column1,column2这样的形式然后substring(6,7)不就获得了column的号,也就是列号。而行号也很简单div.parentNode进行getChildNodes然后遍历一遍,找到当前div所在的位置,然后行号不就找到了。这几个号都有了不就OK了。
其实要实现这样的应用还是要学习一下javascript,否则还是很难写出来。
还有Drag也可以通过dojo库里面的相应的东西实现,那个可以写钩子函数,实现起来比用google这个要规范一些。  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-05-25 14:52 sillyman
"我的注释版把通讯部分删掉了" 斑竹能否把完整的代码发给我,02118@126.com 非常感谢啊! div还不会用呢,可能很简单的问题,对于我来说都很难啊!:(  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-07-28 18:21 智商1000
感谢楼主!
希望再加深一步的研究并发表!谢谢!

附件中注释是乱码!  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-08-15 16:56 ahui4367
我用了楼主的翻译的东西,并且用asp.net+sqlserver保存了窗口布局.数据表的设计我用了2个表,具体的可以看.
http://blog.csdn.net/ahui4367/archive/2006/08/15/1066708.aspx  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-08-16 14:18 BlackSoul
看来有共同爱好了..我按照他的思路写了一个demo..有兴趣可以看一下在下的帖子
http://www.cnblogs.com/BlackSoul/archive/2006/08/14/javascript_drag_google.html

aspx写的仿google主页.用户信息用xml保存,客户端写cookie,cookie使用的是客户ip地址.
xml设置比较简单 1.id,2.所属框架位置,3.rss地址..  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-10-27 15:50 mmmtoo
怎么实现的本地cookie保存啊?  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-10-27 16:20 mmmtoo
@BlackSoul
没有看到你的cookie保存部分,能提供代码不?
mmmtoo@163.com  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-10-31 15:18 Tin
不好意思,我没有注释那部分。自己看看源代码吧。我觉得布局的存储策略可以灵活一点,客户段服务器端方案都是可以的。  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-11-02 15:08 dream
看源码??看google的源码和老大的不一样啊,我也想学习学习cookie保存部分,老大能提供源码不?
  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2006-11-07 15:58 11
cookie保存还是没有搞定啊,楼主是高手,帮忙解决一下啊!学习~  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2007-03-30 09:44 mxpx
google_drag这个脚本有个bug,即当鼠标点击可拖动区域时(不拖动),拖动区域底下会出现拖动时的阴影(框),而且会把界面撑开。
具体见:http://x.discuz.net/attachments/2007/03/350506_200703300944261.png
请问你知道是什么原因造成的吗?

谢谢。  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2007-08-29 16:51 black visitor
不知道是否能很好的支持IE7.0  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2007-12-07 12:48 hexuetao
楼主,真感谢你。
我想问一下,iGoogle实际上它是支持"刷新"的,就是说,用户拖拽后,刷新,用户拖拽后的布局不会变化,请问楼主这个该如何实现???
谢谢,等待答复!  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释[未登录] 2007-12-10 16:48 Tin
那个其实很简单,因为更新是分块的。分块更新就不会破坏布局。
比如你的布局后的小容器是div,如果你只更新div的innerHTML,那么布局就不会变。
我这个注释非常古老了,大家如果看DragDrop的代码可以去看Script.aculo.us或者JQuery或者moo.fx里面的实现,估计更有收获。  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释[未登录] 2007-12-10 16:50 Tin
@black visitor
javascript的东西,如果支持IE6和firefox那么一般就会支持IE7。IE7在JS上面并没有什么大的改进……所以一般还是考虑最低版本的浏览器。  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2008-02-15 10:26 zero8500
正在学习这方面的东西。学习了。。。  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释[未登录] 2008-03-17 15:29
我做了一个类似的个人首页可拖动的,有要的 email我,iamyangwenda@gmail.com
  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2008-03-18 20:53 小朱
@杨
???大哥,能发一份给我吗?
zhuyongke1@163.com  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释[未登录] 2008-04-18 15:08 tony
演示地址http://my.enet.com.cn/myinfo.php,有交流的加我qq:477894  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2008-05-24 12:58 杨文达
有交流加我qq:30296521,或发邮件iamyangwenda@gmail.com  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2008-05-24 12:59 杨文达
@tony
加这个qq:30296521  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2008-10-08 13:26 123123123
有没有ASP版的?????????  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2008-10-20 12:19 surffen
哎 , 看了很多 ,还没搞懂,  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2008-12-09 10:56 ytwang
请问搂主,我把它移植到asp.net中为什么会报脚本错误"尚未实现",好像是js里的错误  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释[未登录] 2009-06-09 16:05 zeus.xiao
@杨
兄弟,我想要一份,看到你的留言是在08年发的,不知道现在向你要是不是有点晚了.  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2009-09-16 14:55 末_雪er
@BlackSoul
看不到你的例子,麻烦给我邮箱发份。用cookie保存用户个性化的。
582444403@qq.com
谢谢了
  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2009-10-31 18:12 jacksnow
@BlackSoul
看不到你的例子能不能麻烦给我发一份,可以么?谢谢
jacksnow1026@163.com  回复  更多评论
  

# re: 对google个性主页的拖拽效果的js的完整注释 2013-09-14 19:53 yaoth
楼主很nb,谢谢!  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: