一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

對google個性主頁的拖拽效果的js的完整注釋[轉(zhuǎn)]

作者:Tin
出處:http://www.blogJava.NET/iamtin/archive/2006/04/27/43668.html
代碼:http://www.blogJava.NET/Files/iamtin/google_drag.rar
復(fù)制代碼 代碼如下:
// 工具類,使用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信息,其實(shí)就是相對于Body的padding以內(nèi)的絕對坐標(biāo) 
// 后面一個參數(shù)如果是true則獲取offsetLeft,false則是offsetTop 
// 關(guān)于offset、style、client等坐標(biāo)的定義參考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(參數(shù)中的funcName是這個fuction的名字)綁定到一個element上,并且以這個element的上下文運(yùn)行,其實(shí)是一種繼承,這個可以google些文章看看 
Util.bindFunction  =   function  (el, fucName) {
     return   function  () {
         return  el[fucName].apply(el, arguments);
    };
};
// 重新計算所有的可以拖拽的element的坐標(biāo),對同一個column下面的可拖拽圖層重新計算它們的高度而得出新的坐標(biāo),防止遮疊 
// 計算出來的坐標(biāo)記錄在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動態(tài)生成 
getGhostElement  =   function  () {
     if  ( ! ghostElement) {
        ghostElement  =  document.createElement( " DIV " );
        ghostElement.className  =   " modbox " ;
        ghostElement.backgroundColor  =   "" ;
        ghostElement.style.border  =   " 2px dashed #aaa " ;
        ghostElement.innerHTML  =   "   " ;
    }
     return  ghostElement;
};

// 初始化可以拖拽的Element的函數(shù),與拖拽無關(guān)的我去掉了 
function  draggable(el) {
     // 公用的開始拖拽的函數(shù) 
     this ._dragStart  =  start_Drag;
     // 公用的正在拖拽的函數(shù) 
     this ._drag  =  when_Drag;
     // 公用的拖拽結(jié)束的函數(shù) 
     this ._dragEnd  =  end_Drag;
     // 這個函數(shù)主要用來進(jìn)行拖拽結(jié)束后的dom處理 
     this ._afterDrag  =  after_Drag;
     // 是否正在被拖動,一開始當(dāng)然沒有被拖動 
     this .isDragging  =   false ;
     // 將這個Element的this指針注冊在elm這個變量里面,方便在自己的上下文以外調(diào)用自己的函數(shù)等,很常用的方法 
     this .elm  =  el;
     // 觸發(fā)拖拽的Element,在這里就是這個div上顯示標(biāo)題的那個div 
     this .header  =  document.getElementById(el.id  +   " _h " );
     // 對于有iframe的element拖拽不同,這里檢測一下并記錄 
     this .hasIFrame  =   this .elm.getElementsByTagName( " IFRAME " ).length  >   0 ;
     // 如果找到了header就綁定drag相關(guān)的event 
     if  ( this .header) {
         // 拖拽時的叉子鼠標(biāo)指針 
         this .header.style.cursor  =   " move " ;
         // 將函數(shù)綁定到header和element的this上,參照那個函數(shù)的說明 
        Drag.init( this .header,  this .elm);
         // 下面三個語句將寫好的三個函數(shù)綁定給這個elemnt的三個函數(shù)鉤子上,也就實(shí)現(xiàn)了element從draggable繼承可拖拽的函數(shù) 
         this .elm.onDragStart  =  Util.bindFunction( this ,  " _dragStart " );
         this .elm.onDrag  =  Util.bindFunction( this ,  " _drag " );
         this .elm.onDragEnd  =  Util.bindFunction( this ,  " _dragEnd " );
    }
};

// 下面就是draggable里面用到的那4個function 
// 公用的開始拖拽的函數(shù) 
function  start_Drag() {
     // 重置坐標(biāo),實(shí)現(xiàn)拖拽以后自己的位置馬上會被填充的效果 
    Util.re_calcOff( this );
     // 記錄原先的鄰居節(jié)點(diǎn),用來對比是否被移動到新的位置 
     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的坐標(biāo) 
     var  offLeft  =  Util.getOffset( this .elm,  true );
     var  offTop  =  Util.getOffset( this .elm,  false );
     // 防止閃爍,現(xiàn)隱藏 
    Util.hide();
     // 將自己的寬度記錄在style屬性里面 
     this .elm.style.width  =  offW  +   " px " ;
     // 將那個灰框設(shè)定得與正在拖動的對象一樣高,比較形象 
    _ghostElement.style.height  =  offH  +   " px " ;
     // 把灰框放到這個對象原先的位置上 
     this .elm.parentNode.insertBefore(_ghostElement,  this .elm.nextSibling);
     // 由于要拖動必須將被拖動的對象從原先的盒子模型里面抽出來,所以設(shè)定position為absolute,這個可以參考一下css布局方面的知識 
     this .elm.style.position  =   " absolute " ;
     // 設(shè)置zIndex,讓它處在最前面一層,當(dāng)然其實(shí)zIndex=100是讓它很靠前,如果頁面里有zIndex>100的,那…… 
     this .elm.style.zIndex  =   100 ;
     // 由于position=absolute了,所以left和top實(shí)現(xiàn)絕對坐標(biāo)定位,這就是先前計算坐標(biāo)的作用,不讓這個模型亂跑,要從開始拖動的地方開始移動 
     this .elm.style.left  =  offLeft  +   " px " ;
     this .elm.style.top  =  offTop  +   " px " ;
     // 坐標(biāo)設(shè)定完畢,可以顯示了,這樣就不會閃爍了 
    Util.show();
     // 這里本來有個ig_d.G,沒搞明白干什么用的,不過沒有也可以用,誰知道麻煩告訴我一聲,不好意思 
     // 還沒有開始拖拽,這里做個記號 
     this .isDragging  =   false ;
     return   false ;
};
// 在拖拽時的相應(yīng)函數(shù),由于綁定到鼠標(biāo)的move這個event上,所以會傳入鼠標(biāo)的坐標(biāo)clientX, clientY 
function  when_Drag(clientX, clientY) {
     // 剛開始拖拽的時候?qū)D層變透明,并標(biāo)記為正在被拖拽 
     if  ( ! this .isDragging) {
         this .elm.style.filter  =   " alpha(opacity=70) " ;
         this .elm.style.opacity  =   0.7 ;
         this .isDragging  =   true ;
    }
     // 被拖拽到的新的column(當(dāng)然也可以是原來那個) 
     var  found  =   null ;
     // 最大的距離,可能是防止溢出或者什么bug 
     var  max_distance  =   100000000 ;
     // 遍歷所有的可拖拽的element,尋找離當(dāng)前鼠標(biāo)坐標(biāo)最近的那個可拖拽元素,以便后面插入 
     for  ( var  i  =   0 ; i  <  Util.dragArray.length; i ++ ) {
         var  ele  =  Util.dragArray[i];
         // 利用勾股定理計算鼠標(biāo)到遍歷到的這個元素的距離 
         var  distance  =  Math.sqrt(Math.pow(clientX  -  ele.elm.pagePosLeft,  2 )  +  Math.pow(clientY  -  ele.elm.pagePosTop,  2 ));
         // 自己已經(jīng)浮動了,所以不計算自己的 
         if  (ele  ==   this ) {
             continue ;
        }
         // 如果計算失敗繼續(xù)循環(huán) 
         if  (isNaN(distance)) {
             continue ;
        }
         // 如果更小,記錄下這個距離,并將它作為found 
         if  (distance  <  max_distance) {
            max_distance  =  distance;
            found  =  ele;
        }
    }
     // 準(zhǔn)備讓灰框落腳 
     var  _ghostElement  =  getGhostElement();
     // 如果找到了另外的落腳點(diǎn) 
     if  (found  !=   null   &&  _ghostElement.nextSibling  !=  found.elm) {
         // 找到落腳點(diǎn)就先把灰框插進(jìn)去,這就是我們看到的那個灰框停靠的特效,有點(diǎn)像吸附的感覺,哈哈 
        found.elm.parentNode.insertBefore(_ghostElement, found.elm);
         if  (Util.isOpera) {
             // Opera的現(xiàn)實(shí)問題,要隱藏/顯示后才能刷新出變化 
            document.body.style.display  =   " none " ;
            document.body.style.display  =   "" ;
        }
    }
};
// 拖拽完畢 
function  end_Drag() {
     // 拖拽完畢后執(zhí)行后面的鉤子,執(zhí)行after_Drag(),如果布局發(fā)生了變動了就記錄到遠(yuǎn)程服務(wù)器,保存你拖拽后新的布局順序 
     if  ( this ._afterDrag()) {
         // remote call to save the change 
    }
     return   true ;
};
// 拖拽后的執(zhí)行鉤子 
function  after_Drag() {
     var  returnValue  =   false ;
     // 防止閃爍 
    Util.hide();
     // 把拖拽時的position=absolute和相關(guān)的那些style都消除 
     this .elm.style.position  =   "" ;
     this .elm.style.width  =   "" ;
     this .elm.style.zIndex  =   "" ;
     this .elm.style.filter  =   "" ;
     this .elm.style.opacity  =   "" ;
     // 獲取灰框 
     var  ele  =  getGhostElement();
     // 如果現(xiàn)在的鄰居不是原來的鄰居了 
     if  (ele.nextSibling  !=   this .origNextSibling) {
         // 把被拖拽的這個節(jié)點(diǎn)插到灰框的前面 
        ele.parentNode.insertBefore( this .elm, ele.nextSibling);
         // 標(biāo)明被拖拽了新的地方 
        returnValue  =   true ;
    }
     // 移除灰框,這是這個灰框的生命周期應(yīng)該就結(jié)束了 
    ele.parentNode.removeChild(ele);
     // 修改完畢,顯示 
    Util.show();
     if  (Util.isOpera) {
         // Opera的現(xiàn)實(shí)問題,要隱藏/顯示后才能刷新出變化 
        document.body.style.display  =   " none " ;
        document.body.style.display  =   "" ;
    }
     return  returnValue;
};
// 可拖拽Element的原形,用來將event綁定到各個鉤子,這部分市比較通用的,NETvibes也是基本完全相同的實(shí)現(xiàn) 
// 這部分推薦看dindin的這個,也會幫助理解,http://www.jroller.com/page/dindin/?anchor=pro_Javascript_12 
var  Drag  =  {
     // 對這個element的引用,一次只能拖拽一個Element 
    obj: null , 
     // element是被拖拽的對象的引用,elementHeader就是鼠標(biāo)可以拖拽的區(qū)域 
    init: function  (elementHeader, element) {
         // 將start綁定到onmousedown事件,按下鼠標(biāo)觸發(fā)start 
        elementHeader.onmousedown  =  Drag.start;
         // 將element存到header的obj里面,方便header拖拽的時候引用 
        elementHeader.obj  =  element;
         // 初始化絕對的坐標(biāo),因為不是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被調(diào)用后才幫定到實(shí)際的函數(shù),可以參照draggable里面的內(nèi)容 
        element.onDragStart  =   new  Function();
        element.onDragEnd  =   new  Function();
        element.onDrag  =   new  Function();
    },
     // 開始拖拽的綁定,綁定到鼠標(biāo)的移動的event上 
    start: function  (event) {
         var  element  =  Drag.obj  =   this .obj;
         // 解決不同瀏覽器的event模型不同的問題 
        event  =  Drag.fixE(event);
         // 看看是不是左鍵點(diǎn)擊 
         if  (event.which  !=   1 ) {
             // 除了左鍵都不起作用 
             return   true ;
        }
         // 參照這個函數(shù)的解釋,掛上開始拖拽的鉤子 
        element.onDragStart();
         // 記錄鼠標(biāo)坐標(biāo) 
        element.lastMouseX  =  event.clientX;
        element.lastMouseY  =  event.clientY;
         // 將Global的event綁定到被拖動的element上面來 
        document.onmouseup  =  Drag.end;
        document.onmousemove  =  Drag.drag;
         return   false ;
    }, 
     // Element正在被拖動的函數(shù) 
    drag: function  (event) {
         // 解決不同瀏覽器的event模型不同的問題 
        event  =  Drag.fixE(event);
         // 看看是不是左鍵點(diǎn)擊 
         if  (event.which  ==   0 ) {
             // 除了左鍵都不起作用 
             return  Drag.end();
        }
         // 正在被拖動的Element 
         var  element  =  Drag.obj;
         // 鼠標(biāo)坐標(biāo) 
         var  _clientX  =  event.clientY;
         var  _clientY  =  event.clientX;
         // 如果鼠標(biāo)沒動就什么都不作 
         if  (element.lastMouseX  ==  _clientY  &&  element.lastMouseY  ==  _clientX) {
             return   false ;
        }
         // 剛才Element的坐標(biāo) 
         var  _lastX  =  parseInt(element.style.top);
         var  _lastY  =  parseInt(element.style.left);
         // 新的坐標(biāo) 
         var  newX, newY;
         // 計算新的坐標(biāo):原先的坐標(biāo)+鼠標(biāo)移動的值差 
        newX  =  _lastY  +  _clientY  -  element.lastMouseX;
        newY  =  _lastX  +  _clientX  -  element.lastMouseY;
         // 修改element的顯示坐標(biāo) 
        element.style.left  =  newX  +   " px " ;
        element.style.top  =  newY  +   " px " ;
         // 記錄element現(xiàn)在的坐標(biāo)供下一次移動使用 
        element.lastMouseX  =  _clientY;
        element.lastMouseY  =  _clientX;
         // 參照這個函數(shù)的解釋,掛接上Drag時的鉤子 
        element.onDrag(newX, newY);
         return   false ;
    },
     // Element正在被釋放的函數(shù),停止拖拽 
    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_;
    }
};



// 下面是初始化的函數(shù)了,看看上面這些東西怎么被調(diào)用 
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列,其實(shí)也可以更多 
    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,載入完畢執(zhí)行。不過實(shí)際上google沒有用onload。 
// 而是寫在頁面最下面,異曲同工吧,也許直接寫在頁面是種怪癖,或者也有可能是兼容性考慮。 

// 請將下面兩條被注釋掉的代碼加,到你自己下載的一個google ig頁面里面,把里面的所有其余script刪除,掛上這個js也可以拖拽了,哈哈 
// _table=document.getElementById("t_1"); 
// window.onload = _IG_initDrag(_table); 

// 其實(shí)看懂這些代碼對學(xué)習(xí)Javascript很有益,希望對大家能有幫助 

JavaScript技術(shù)對google個性主頁的拖拽效果的js的完整注釋[轉(zhuǎn)],轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 成年美女黄网站色大 | 亚洲综人网 | 婷婷激情四月 | 免费的黄色片视频 | 国产午夜精品福利久久 | 黄网站免费在线观看 | 日本久久精品免视看国产成人 | 久久丝袜精品综合网站 | 久久国产精品-国产精品 | 天天干天天干天天干天天 | 国产zzzwww在线观看视频 | 国产福利免费视频 | 久久噜国产精品拍拍拍拍 | 伊人手机在线视频 | 最新精品视频在线观看 | 麻豆a| 成人精品视频在线观看播放 | 丁香综合缴情六月婷婷 | 国产精品女 | 午夜毛片福利 | 精品国产自在现线看 | 视频在线观看一区 | 黄网在线免费看 | 伊人任线任你躁 | 大伊人青草狠狠久久 | 亚洲夜色 | 婷婷影院在线观看 | 六月婷婷在线 | 开心激情五月网 | 国产小视频在线免费 | 国产乱子伦视频大全 | 国产精品视频第二区第二页 | 夜夜未满 18勿进的爽影院 | 国产大片免费观看中文字幕 | 狠狠综合久久综合鬼色 | www.色综合.com| 婷婷99精品国产97久久综合 | 亚洲国产系列一区二区三区 | 亚洲一区二区三区在线视频 | 国产日韩一区二区三区在线播放 | 91麻豆文化传媒有限公司 |