《任務5 DOM操作-拖曳效果》任務產出匯總

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

首先把需要拖動的部分放到一個div里面,然后導入相關的.js文件
<code>
<div class="login_logo_webqq"></div>
</code>

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

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

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

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

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

現在我們得到了這塊元素之后,我們調用一個drag的函數,來完成拖拽.

<h2>拖動一共要經歷三步

1>在標題區域按下開始拖動

2>在頁面中拖動

3>釋放鼠標的時候停止拖動
</h2>

window.onload=drag;

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

    拖曳,獲取了這個div,

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

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

其中黃色的時光標,藍色時標題框,其中的白線就是我們要獲取的坐標.而白線的距離就是光標相對瀏覽器的距離減去彈框跟窗口之間的距離
![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現在是獲得的白線的距離
注意任何拖動的拖動的東西,都需要一個絕對定位,在css中.
    <p>
    <h5>錯誤發現:</h5>
    那現在又會發現,彈框可以任意拖動,也就是可以一直把滾動條撐起來,這樣的話用戶體驗也不好
    <h5>分析解決:</h5>
    我們現在就需要,當彈框接觸瀏覽器邊界的時候不能在想外拖動了.所以就用限制一個范圍,不能隨意拉動了.對于左邊也就時lt變成負數的時候讓他強制變成0.對于右邊就拖動的最大范圍就是頁面寬減去彈框寬度,當坐標大于這個范圍的時候就強制變成最大坐標
    </p>

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

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

推薦閱讀更多精彩內容

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