posts - 495,comments - 227,trackbacks - 0

          一直以來,都對JS獲取元素的位置感到非常的困惑:一會client、一會offset、一會scroll。

          再加上各大瀏覽器之間的不兼容,唉,搞得哥暈暈乎乎的。

          而很多頁面效果都要用到這些位置。不得已,得練練,得記記。

          下面就來說說這個基于 JQuery的簡易拖拽插件吧。   

          按慣例,先說說拖拽的原理,以及搞這么一個東東的步驟:

          那什么是拖拽呢? 看名字就知道了:就是把一個東東拖來拽去的。 放到我們的DOM上,就是改變它的位置。

          它只有兩個難點:1、如何知道是在拖? 2、如何知道從哪拖,拖到哪?

          其實,這也算不上難點,畢竟兩者都是基礎的東西,關鍵在于熟練。

          換到js 中,我們搞一個拖拽效果,大致有如下步驟:

          1、讓元素捕獲事件(一般情況下,無非就是mousedown、mousemove、mouseup)

          2、在mousedown時,標記開始拖拽,并獲取元素及鼠標的位置。

          3、在mousemove時,不斷的獲取鼠標的新位置,并通過相應的位置算法,來重新定位元素位置。

          4、在mouseup時,結束拖拽。。。然后周而復始。

          這中間,個需要注意的地方:被拖拽的元素,至少需要相對或絕對定位,否則拖拽不會有效果。

          OK,不多說,無代碼,無真相。相應的解釋都在其中了:

          猛擊下載


          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
          <html xmlns="http://www.w3.org/1999/xhtml">
          <head>
          <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
          <title></title>
          <meta name="keywords" content="Javascript自由拖拽類" />
          <script type="text/javascript" src="jquery-1.4.2.min.js"></script>

          <script type="text/javascript">
             (
          function($)
              {
                  $.extend({
                      
          //獲取鼠標當前坐標
                      mouseCoords:function(ev){
                          
          if(ev.pageX || ev.pageY){
                              
          return {x:ev.pageX, y:ev.pageY};
                          }
                          
          return {
                              x:ev.clientX 
          + document.body.scrollLeft - document.body.clientLeft,
                              y:ev.clientY 
          + document.body.scrollTop  - document.body.clientTop
                          };
                      },
                      
          //獲取樣式值
                      getStyle:function(obj,styleName)
                      {
                          
          return obj.currentStyle ? obj.currentStyle[styleName] : document.defaultView.getComputedStyle(obj,null)[styleName];
          //                return obj.currentStyle ? obj.currentStyle[styleName] : document.defaultView.getComputedStyle(obj,null).getPropertyValue(styleName);
                      }
                  });        

                  
          // 元素拖拽插件
                  $.fn.dragDrop = function(options)
                  {
                      
          var opts = $.extend({},$.fn.dragDrop.defaults,options);

                      
          return this.each(function(){

                          
          //是否正在拖動
                          var bDraging = false;   
                          
          //移動的元素
                          var moveEle = $(this);
                          
          //點擊哪個元素,以觸發移動。
                          //該元素需要是被移動元素的子元素(比如標題等)
                          var focuEle = opts.focuEle ? $(opts.focuEle,moveEle) : moveEle ;
                          
          if(!focuEle || focuEle.length<=0)
                          {
                              alert('focuEle is not found
          ! the element must be a child of '+this.id);
                              
          return false;
                          }                
                          
          // initDiffX|Y : 初始時,鼠標與被移動元素原點的距離
                          // moveX|Y : 移動時,被移動元素定位位置 (新鼠標位置與initDiffX|Y的差值)
                          // 如果定義了移動中的回調函數,該對象將以參數傳入回調函數。
                          var dragParams = {initDiffX:'',initDiffY:'',moveX:'',moveY:''};  

                          
          //被移動元素,需要設置定位樣式,否則拖拽效果將無效。
                          moveEle.css({'position':'absolute','left':'0','top':'0'});
                          
                          
          //點擊時,記錄鼠標位置
                          //DOM寫法: getElementById('***').onmousedown= function(event);
                          focuEle.bind('mousedown',function(e){                
                              
          //標記開始移動
                              bDraging = true;
                              
          //改變鼠標形狀
                              moveEle.css({'cursor':'move'});
                              
          //捕獲事件。(該用法,還有個好處,就是防止移動太快導致鼠標跑出被移動元素之外)
                              if(moveEle.get(0).setCapture)
                              {  
                                  moveEle.get(
          0).setCapture();  
                              } 
                              
          //(實際上是鼠標當前位置相對于被移動元素原點的距離)
                              // DOM寫法:(ev.clientX + document.body.scrollLeft - document.body.clientLeft) - document.getElementById('***').style.left;
                              dragParams.initDiffX = $.mouseCoords(e).x - moveEle.position().left;
                              dragParams.initDiffY 
          = $.mouseCoords(e).y - moveEle.position().top;
                          });

                          
          //移動過程
                          focuEle.bind('mousemove',function(e){
                              
          if(bDraging)
                              {    
                                  
          //被移動元素的新位置,實際上鼠標當前位置與原位置之差
                                  //實際上,被移動元素的新位置,也可以直接是鼠標位置,這也能體現拖拽,但是元素的位置就不會精確。
                                  dragParams.moveX = $.mouseCoords(e).x - dragParams.initDiffX;
                                  dragParams.moveY 
          = $.mouseCoords(e).y - dragParams.initDiffY;

                                  
          //是否限定在某個區域中移動.
                                  //fixarea格式: [x軸最小值,x軸最大值,y軸最小值,y軸最大值]
                                  if(opts.fixarea)
                                  {
                                      
          if(dragParams.moveX<opts.fixarea[0])
                                      {
                                          dragParams.moveX
          =opts.fixarea[0]
                                      }
                                      
          if(dragParams.moveX>opts.fixarea[1])
                                      {
                                          dragParams.moveX
          =opts.fixarea[1]
                                      }

                                      
          if(dragParams.moveY<opts.fixarea[2])
                                      {
                                          dragParams.moveY
          =opts.fixarea[2]
                                      }
                                      
          if(dragParams.moveY>opts.fixarea[3])
                                      {
                                          dragParams.moveY
          =opts.fixarea[3]
                                      }
                                  }
                                  
                                  
          //移動方向:可以是不限定、垂直、水平。
                                  if(opts.dragDirection=='all')
                                  {
                                      
          //DOM寫法: document.getElementById('***').style.left = '***px'; 
                                      moveEle.css({'left':dragParams.moveX,'top':dragParams.moveY});
                                  }
                                  
          else if (opts.dragDirection=='vertical')
                                  {
                                      moveEle.css({'top':dragParams.moveY});
                                  }
                                  
          else if(opts.dragDirection=='horizontal')
                                  {
                                      moveEle.css({'left':dragParams.moveX});
                                  }

                                  
          //如果有回調
                                  if(opts.callback)
                                  {
                                      
          //將dragParams作為參數傳遞
                                      opts.callback.call(opts.callback,dragParams);
                                  }
                              }
                          });

                          
          //鼠標彈起時,標記為取消移動
                          focuEle.bind('mouseup',function(e){
                              bDraging
          =false;
                              moveEle.css({'cursor':'
          default'});
                              
          if(moveEle.get(0).releaseCapture)
                              {
                                  moveEle.get(
          0).releaseCapture();
                              }
                          });
                      });
                  };

                  
          //默認配置
                  $.fn.dragDrop.defaults = 
                  {
                      focuEle:
          null,            //點擊哪個元素開始拖動,可為空。不為空時,需要為被拖動元素的子元素。
                      callback:null,            //拖動時觸發的回調。
                      dragDirection:'all',    //拖動方向:['all','vertical','horizontal']
                      fixarea:null            //限制在哪個區域拖動,以數組形式提供[minX,maxX,minY,maxY]
                  };

              })(jQuery);   


              
          // test 
             $(function(){
                  
          //限定區域,有回調函數。
                  $('#dragDiv').dragDrop({fixarea:[0,$('#dragContainer').width()-50,0,$('#dragContainer').height()-50],callback:function(params){
                          $('#span1').text('X:'
          +params.moveX+' Y:'+params.moveY);
                  }});
                  
          //默認設置
                  $('#dragDiv1').dragDrop();
             });
          </script>

          </head>
          <body>
              
          <div id="dragContainer" style="position:relative;left:10px;top:10px;border:1px dashed blue;width:500px;height:500px;">

                
          <div id="dragDiv" style="background-color:blue;height:50px;width:50px;">
                
          </div>
                
          <div id="dragDiv1" style="border:1px solid red;height:50px;width:50px;">
                
          </div>

              
          </div>

                
          <span id="span1"></span>
          </body>
          </html>
          posted on 2011-09-28 17:47 SIMONE 閱讀(974) 評論(0)  編輯  收藏 所屬分類: JavaScript
          主站蜘蛛池模板: 称多县| 喀喇| 丹巴县| 隆尧县| 平谷区| 德兴市| 板桥市| 秭归县| 综艺| 宁德市| 琼海市| 达州市| 麟游县| 清涧县| 镇沅| 台安县| 呼图壁县| 集贤县| 衡水市| 鸡东县| 临夏市| 江永县| 江西省| 桦川县| 会宁县| 大荔县| 汤阴县| 崇礼县| 彝良县| 抚远县| 隆安县| 丹东市| 长葛市| 乡城县| 托里县| 左云县| 大兴区| 高清| 疏勒县| 读书| 桃园市|