《任務(wù)5 DOM操作-拖曳效果》任務(wù)產(chǎn)出匯總

ps:代碼是其他提供,其中所有文字都是個(gè)人理解,如果有什么錯(cuò)誤和想法歡迎溝通~希望對(duì)你有幫助,biu
<h1>拖動(dòng) /拖曳效果</h1>

首先把需要拖動(dòng)的部分放到一個(gè)div里面,然后導(dǎo)入相關(guān)的.js文件
<code>
<div class="login_logo_webqq"></div>
</code>

由于IE10以上不支持document.getElementsClassName(),所以為了解決所有瀏覽器兼容的問題,需要把獲取ClassName封裝起來.

通過Class獲取元素需要兩個(gè)參數(shù),一個(gè)時(shí)ClassName類名,一個(gè)是父元素,第二個(gè)參數(shù)也不是必須的,如果不寫就打上document,就會(huì)尋找所有class的元素,寫了就尋找這個(gè)父元素下的ClassName.

    function getByClass(clsName,parent){
      var oParent=parent?document.getElementById(parent):document,
      eles=[],

解釋:如果傳入parent就獲取他的id然后付給變量,沒有傳的話就放入document
由于類名可能不唯一,所以得到的是一個(gè)數(shù)組,就把他放到這個(gè)eles數(shù)組里面.

          elements=oParent.getElementsByTagName('*');
    ```      
現(xiàn)在獲取到父元素下面所有的元素,然后進(jìn)行遍歷
    
      for(var i=0,l=elements.length;i<l;i++){
        if(elements[i].className==clsName){
          eles.push(elements[i]);
        }
      }
      return eles;
    }

現(xiàn)在我們得到了這塊元素之后,我們調(diào)用一個(gè)drag的函數(shù),來完成拖拽.

<h2>拖動(dòng)一共要經(jīng)歷三步

1>在標(biāo)題區(qū)域按下開始拖動(dòng)

2>在頁面中拖動(dòng)

3>釋放鼠標(biāo)的時(shí)候停止拖動(dòng)
</h2>

window.onload=drag;

function drag(){
var oTitle=getByClass('login_logo_webqq','loginPanel')[0];

    拖曳,獲取了這個(gè)div,

oTitle.onmousedown=fnDown;
```
onmousedown:在用戶按下任意鼠標(biāo)按鈕時(shí)出發(fā)事件fndown,為了方便閱讀我將fnDown函數(shù)放到下面.<h3>拖動(dòng)的原理其實(shí)就是拖動(dòng)的部分和你的光標(biāo)的坐標(biāo)是一樣的.</h3>
光標(biāo)的位置可以通過clientX 和 clientY來得到.
鼠標(biāo)事件都是在瀏覽器的特定位置上發(fā)生的,這個(gè)位置的信息保存在事件的clientX和clientY屬性中.所有瀏覽器都支持這兩個(gè)屬性,他們的值表示事件發(fā)生時(shí)鼠標(biāo)指針在視口中的水平和垂直坐標(biāo),不包括頁面滾動(dòng)的距離,也就是說可以通過這兩個(gè)屬性獲得光標(biāo)的xy坐標(biāo),然后讓彈框也是這個(gè)坐標(biāo)不就實(shí)現(xiàn)了拖動(dòng)

   function fnDown(event){
   event = event || window.event;
   
   var oDrag=document.getElementById('loginPanel'),
       // 光標(biāo)按下時(shí)光標(biāo)和面板之間的距離
       disX=event.clientX-oDrag.offsetLeft,
       disY=event.clientY-oDrag.offsetTop;
     //用來獲取彈框左上角相對(duì)瀏覽器距離,下面會(huì)解釋  
   
   document.onmousemove=function(event){
     event = event || window.event;
     //IE得用window.event,得到事件對(duì)象
     fnMove(event,disX,disY);
     
     
     function fnMove(e,posX,posY){
   var oDrag=document.getElementById('loginPanel'),//改變他得先把他取出來
   ```
<p>
   <h5>錯(cuò)誤演示:</h5>
   按理來說只要改變他的位置定位就可以了
  oDrag.style.left = event.clientX+'px';
  oDrang.style.top = event.clientY+'px';
<p>
      這樣操作會(huì)明顯發(fā)現(xiàn),當(dāng)你光標(biāo)在拖動(dòng)區(qū)域按下鼠標(biāo)時(shí),光標(biāo)會(huì)跑到彈框的左上角,這樣的話用戶體驗(yàn)就不太好了.
      bug分析:
      由于你告訴瀏覽器光標(biāo)在哪,彈框在那,得有個(gè)標(biāo)準(zhǔn)吧,所以就是時(shí)你的彈框左上角和光標(biāo)位置一樣.而且你本身定義的top和left就是左上角的位置.
      <h5>解決方案:</h5>
      所以就是說我們不能直接告訴他讓和光標(biāo)一個(gè)位置,而是在你光標(biāo)按下的位置上的基礎(chǔ)來改變位置.所以就是要獲取到按下鼠標(biāo)的位置和左上角的位置有什么關(guān)系,在這個(gè)基礎(chǔ)上改變位置.
![guangbaio.png](http://upload-images.jianshu.io/upload_images/3189429-199a5ec9533f500c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

其中黃色的時(shí)光標(biāo),藍(lán)色時(shí)標(biāo)題框,其中的白線就是我們要獲取的坐標(biāo).而白線的距離就是光標(biāo)相對(duì)瀏覽器的距離減去彈框跟窗口之間的距離
![weizhi.png](http://upload-images.jianshu.io/upload_images/3189429-c6bb703bdb99f946.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

</p>
</p>
      
          l=e.clientX-posX,
          t=e.clientY-posY,
l,t現(xiàn)在是獲得的白線的距離
注意任何拖動(dòng)的拖動(dòng)的東西,都需要一個(gè)絕對(duì)定位,在css中.
    <p>
    <h5>錯(cuò)誤發(fā)現(xiàn):</h5>
    那現(xiàn)在又會(huì)發(fā)現(xiàn),彈框可以任意拖動(dòng),也就是可以一直把滾動(dòng)條撐起來,這樣的話用戶體驗(yàn)也不好
    <h5>分析解決:</h5>
    我們現(xiàn)在就需要,當(dāng)彈框接觸瀏覽器邊界的時(shí)候不能在想外拖動(dòng)了.所以就用限制一個(gè)范圍,不能隨意拉動(dòng)了.對(duì)于左邊也就時(shí)lt變成負(fù)數(shù)的時(shí)候讓他強(qiáng)制變成0.對(duì)于右邊就拖動(dòng)的最大范圍就是頁面寬減去彈框?qū)挾?當(dāng)坐標(biāo)大于這個(gè)范圍的時(shí)候就強(qiáng)制變成最大坐標(biāo)
    </p>

    winW=document.documentElement.clientWidth || document.body.clientWidth,
          winH=document.documentElement.clientHeight || document.body.clientHeight,
          
          maxW=winW-oDrag.offsetWidth-10,
          //這里減10是因?yàn)殛P(guān)閉按鈕允許溢出十個(gè)像素
          maxH=winH-oDrag.offsetHeight;
      if(l<0){
        l=0;
      }else if(l>maxW){
        l=maxW;
      }
      if(t<0){
        t=10;
        //這樣才能底對(duì)齊
      }else if(t>maxH){
        t=maxH;
      }
      
      oDrag.style.left=l+'px';
      oDrag.style.top=t+'px';
    }
 }
      
onmousemove當(dāng)鼠標(biāo)指針在元素內(nèi)部移動(dòng)時(shí)重復(fù)地觸發(fā),也就是每移動(dòng)一下都會(huì)觸發(fā)這個(gè)事件.
      
      
      // mouseup當(dāng)用戶釋放鼠標(biāo)觸發(fā)事件
      document.onmouseup=function(){
        document.onmousemove=null;
        //就是移動(dòng)的時(shí)候什么也不做,釋放事件
        document.onmouseup=null;
      }
    }

<h4>總結(jié)</h4>
總的來說就是獲取到可以點(diǎn)擊鼠標(biāo)拖動(dòng)的區(qū)域,然后再處理好彈框和鼠標(biāo)坐標(biāo)的關(guān)系.放開鼠標(biāo)的時(shí)候釋放事件.最后再處理一下邊界的問題就好了.我個(gè)人認(rèn)為這個(gè)這個(gè)坐標(biāo)的問題還是很值得分析的.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • HTML標(biāo)簽解釋大全 一、HTML標(biāo)記 標(biāo)簽:!DOCTYPE 說明:指定了 HTML 文檔遵循的文檔類型定義(D...
    米塔塔閱讀 3,331評(píng)論 1 41
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 6,554評(píng)論 0 17
  • 事件源對(duì)象 event.srcElement.tagName event.srcElement.type 捕獲釋放...
    孤魂草閱讀 910評(píng)論 0 0
  • 一、JS前言 (1)認(rèn)識(shí)JS 也許你已經(jīng)了解HTML標(biāo)記(也稱為結(jié)構(gòu)),知道了CSS樣式(也稱為表示),會(huì)使用HT...
    凜0_0閱讀 2,807評(píng)論 0 8
  • 我是北方人,從小喜歡吃饅頭。尤其是媽媽和面、老爸親手揉、上鍋蒸出來的大饅頭,咬下去滿口生香,就著咸菜就能吃上一整個(gè)...
    4d67e06828ce閱讀 986評(píng)論 1 2