jQuery UI – Droppable Widget簡介

by vivid 4. 六月 2014 04:13

.NET Magazine國際中文電子雜誌
者:許薰尹
稿:張智凱
文章編號:N140614901
出刊日期:2014/6/4
開發工具:Visual Studio 2013 Ultimate Update 2
版本:.NET Framework 4.5.5x

jQuery UI Droppable Widget可以讓你在網頁之中定義一個區塊,用來置放使用者利用滑鼠從Draggable Widget拖曳進來的物件。當物件拖曳到此Droppable區塊,便會觸發一些相關的drop、out、與over等等事件,讓您做因應的處理。Droppable Widget不能夠單獨使用,必需要搭配Draggable Widget一起使用。

我們先來看一個基本的Droppable Widget使用方式,參考以下範例程式碼:

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
  <title> </title>
  <link href = "Content/themes/base/jquery-ui.css" rel="stylesheet" />
  <style>
    #myDraggable {
      width: 150px;
      height: 150px;
      padding: 15px;
      cursor: move;
    }
    #myDroppable {
      width: 300px;
      height: 300px;
    }
  </style>
</head>
<body>

 

  <div id = "myDroppable" class = "ui-widget-content">
    <h1> 我是Droppable </h1>
  </div>

  <div id = "myDraggable" class = "ui-widget-content ">
    <h1> 我是Draggable </h1>

  </div>
  <script src="Scripts/jquery-2.0.3.min.js"></script>
  <script src="Scripts/jquery-ui-1.10.3.min.js"></script>

  <script>
    (function ($) {
      $("#myDraggable").draggable();
      $("#myDroppable").droppable();
    })(jQuery);
  </script>
</body>
</html>

網頁之中包含一個名為myDroppable的div,做為Droppable;另有一個名為myDraggable的Draggable。在jQuery的ready事件之中,分別叫用jQuery UI Widget的draggable()與.droppable()方法來初始化。當網頁一開始執行時,請參考執行畫面如下:

clip_image002

圖 1:使用jQuery UI Droppable。

你可以將Draggable拖曳到Droppable上方後方開,執行結果請參考下圖所示:

clip_image004

圖 2:Draggable可以拖放到 Droppable。

drop事件

我們可以利用Droppable的drop事件來判斷是否有物件被拖曳並置放到Droppable,例如修改一下上個範例,在叫用.droppable()方法初始化時,順帶傳入一個dropOptions物件來設定Droppable, dropOptions物件註冊drop事件,在Draggable物件拖曳到Droppable上放開滑鼠時,將會觸發drop事件,此例在事件發生時,在Droppable顯示「Dropped!」字串:

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
  <title> </title>
  <link href = "Content/themes/base/jquery-ui.css" rel = "stylesheet" />
  <style>
    .ui-widget-content {
      background: lightblue;
    }

    #myDraggable {
      width: 150px;
      height: 150px;
      padding: 15px;
      cursor: move;
    }

    #myDroppable {
      width: 300px;
      height: 300px;
    }
  </style>
</head>
<body>
  <div id = "myDroppable" class = "ui-widget-content">
    <h1> 我是Droppable </h1>
  </div>

  <div id = "myDraggable" class = "ui-widget-content ">
    <h1> 我是Draggable </h1>
  </div>


  <script src="Scripts/jquery-2.0.3.min.js"></script>
  <script src="Scripts/jquery-ui-1.10.3.min.js"></script>


  <script>
    (function ($) {
      $("#myDraggable").draggable();

      var dropOptions = {
        drop: function (event, ui) {
          $(this).html( "Dropped!" );
        }
      };

      $("#myDroppable").droppable( dropOptions );
    })(jQuery);
  </script>
</body>
</html>

 

此範例的執行結果請參考下圖所示:

clip_image006

圖 3:Draggable置放到Droppable上會觸發drop事件。

套用activeClass與hoverClass樣式

在拖曳過程中,你可以利用draggable的activeClass與hoverClass選項來提供醒目的提示。當設定為accept的HTML項目開始拖曳時,會自動套用activeClass所指定的樣式;當draggable拖曳進draggable邊界約一半時,就會自動套用hoverClass所指定的樣式。參考以下範例:

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
  <title> </title>
  <link href = "Content/themes/sunny/jquery-ui.css" rel = "stylesheet" />
  <style>
    .ui-widget-content {
      background: lightblue;
    }

    #myDraggable1, #myDraggable2 {
      width: 150px;
      height: 150px;
      padding: 15px;
      cursor: move;
      float:left;
    }

    #myDroppable {
      width: 300px;
      height: 300px;
    }
 
    .ui-state-active {
      background-color:#ffd800;
    }
    .ui-state-hover {
      background-color:aquamarine!important;
    }
  </style>
</head>
<body>
  <div id = "myDroppable" class = "ui-widget-content">
    <h1>我是Droppable</h1>
  </div>
  <br />
  <div id = "myDraggable1" class = "ui-widget-content ">
    <h1> 我是Draggable1 </h1>
  </div>
 
  <div id = "myDraggable2" class = "ui-widget-content ">
    <h1> 我是Draggable2 </h1>
  </div>

 
  <script src="Scripts/jquery-2.0.3.min.js"></script>
  <script src="Scripts/jquery-ui-1.10.3.min.js"></script>


  <script>
    (function ($) {

      var dragOptions = {
        start: function (event, ui) {
          $("#myDroppable").html("");
        }
      };

      $("#myDraggable1").draggable( dragOptions );
      $("#myDraggable2").draggable( );

      var dropOptions = {
        accept: "#myDraggable1",
        activeClass: "ui-state-active",
        hoverClass: "ui-state-hover",
        drop: function (event, ui) {
          $(this).html( "Dropped!" );
        }
      };

      $("#myDroppable").droppable( dropOptions );
    })(jQuery);
  </script>
</body>
</html>

 

當一開始拖曳myDraggable1時,就套用activeClass樣式,讓Droppable底色變成淺橘色,執行結果請參考下圖所示:

clip_image008

圖 4:拖曳accept物件自動套用activeClass樣式。

拖曳myDraggable1超過約一半的大小時,就套用hoverClass,讓Droppable底色變成淺綠色,執行結果請參考下圖所示:

clip_image010

圖 5:拖曳accept物件到Droppable內自動套用hoverClass樣式。

因為Droppble的accept選項設定為「#myDraggable1」,因此myDraggable2並沒有類似的拖曳效果,執行結果請參考下圖所示:

clip_image012

圖 6:不是accept項目不會套用樣式與觸發事件。

accept選項

若要讓上例的myDraggable2也能有和myDraggable1般能置放在Droppable內,你可以修改上例程式碼,將accept設定如下,這樣myDraggable1與myDraggable2就會有相同效果:

var dropOptions = {
  accept: "#myDraggable1,#myDraggable2",
  activeClass: "ui-state-active",
  hoverClass: "ui-state-hover",
  drop: function (event, ui) {
    $(this).html( "Dropped!" );
  }
};

accept選項也可以設定為一個函式(function),網頁中的每一個Draggable都會傳入此函式做檢查,你可以從第一個參數取得被傳入來檢查的Draggable,若此Draggable可以置放在Droppble之中,此函式就回傳「true」。例如以下範例程式碼,叫用checkDraggable函式做檢查,設定myDraggable1可置放到Droppable,此範例的執行結果和上一個例子相同:

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
  <title> </title>
  <link href = "Content/themes/sunny/jquery-ui.css" rel = "stylesheet" />
  <style>
    .ui-widget-content {
      background: lightblue;
    }

    #myDraggable1, #myDraggable2 {
      width: 150px;
      height: 150px;
      padding: 15px;
      cursor: move;
      float: left;
    }

    #myDroppable {
      width: 300px;
      height: 300px;
    }

    .ui-state-active {
      background-color: #ffd800;
    }

    .ui-state-hover {
      background-color: #ff6a00;
    }
  </style>
</head>
<body>
  <div id = "myDroppable" class = "ui-widget-content">
    <h1> 我是Droppable </h1>
  </div>
  <br />
  <div id = "myDraggable1" class = "ui-widget-content ">
    <h1> 我是Draggable1 </h1>
  </div>

  <div id = "myDraggable2" class = "ui-widget-content ">
    <h1> 我是Draggable2 </h1>
  </div>


  <script src="Scripts/jquery-2.0.3.min.js"></script>
  <script src="Scripts/jquery-ui-1.10.3.min.js"></script>


  <script>
    (function ($) {

      var dragOptions = {
        start: function (event, ui) {
          $("#myDroppable").html("");
        }
      };

      $("#myDraggable1").draggable( dragOptions );
      $("#myDraggable2").draggable();

      function checkDraggable(ele) {
        return ele.attr("id") == "myDraggable1" ? true : false;
      }

      var dropOptions = {
        accept: checkDraggable,
        activeClass: "ui-state-active",
        drop: function (event, ui) {
          $(this).html("Dropped!");
        }
      };

      $("#myDroppable").droppable( dropOptions );
    })(jQuery);
  </script>
</body>
</html>

容許度

容許度(tolerance)用來讓Droppable偵測Draggable是否拖曳到它的上方,預設的值是「intersect」。

可以設定為以下值:

  • · fit:被拖曳的物件要完整地放入Droppable的邊界之中。
  • · intersect:被拖曳的物件約百分之50放入Droppable之中。
  • · pointer:滑鼠的游標需要接觸到Droppable的邊界。
  • · touch:被拖曳的物件的邊界接觸到Droppable的邊界。

fit

我們看一個容許度(tolerance)設為fit的範例:

 

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
  <title> </title>
  <link href = "Content/themes/sunny/jquery-ui.css" rel = "stylesheet" />
  <style>
    .ui-widget-content {
      background: lightblue;
    }

    #myDraggable1, #myDraggable2 {
      width: 150px;
      height: 150px;
      padding: 15px;
      cursor: move;
      float: left;
    }

    #myDroppable {
      width: 300px;
      height: 300px;
    }

    .ui-state-active {
      background-color: #ffd800;
    }

    .ui-state-hover {
      background-color: #ff6a00;
    }
  </style>
</head>
<body>
  <div id = "myDroppable" class = "ui-widget-content">
    <h1> 我是Droppable </h1>
  </div>
  <br />
  <div id = "myDraggable1" class = "ui-widget-content ">
    <h1> 我是Draggable1 </h1>
  </div>
  <script src="Scripts/jquery-2.0.3.min.js"></script>
  <script src="Scripts/jquery-ui-1.10.3.min.js"></script>
  <script>
    (function ($) {

      var dragOptions = {
        start: function (event, ui) {
          $("#myDroppable").html("");
        }
      };

      $("#myDraggable1").draggable( dragOptions );

      function checkDraggable(ele) {
        return ele.attr("id") == "myDraggable1" ? true : false;
      }

      var dropOptions = {
        accept: checkDraggable,
        activeClass: "ui-state-active",
        tolerance: "fit",
        drop: function (event, ui) {
          $(this).html("Dropped!");
        }
      };

      $("#myDroppable").droppable( dropOptions );
    })(jQuery);
  </script>
</body>
</html>

執行時,若拖曳的myDraggable沒有完整放入myDraggable,則不會觸發drop事件,執行結果請參考下圖所示:

clip_image014

圖 7:myDraggable沒有完整放入myDraggable,則不會觸發drop事件。

執行時,若拖曳的myDraggable完整地放入myDraggable,才會觸發drop事件,請參考下圖所示:

clip_image016

圖 8:myDraggable完整地放入myDraggable,觸發drop事件。

intersect

接下來我們來看看設定為「intersect」的效果,修改上例,將tolerance設為「intersect」:

 

var dropOptions = {
        accept: checkDraggable,
        activeClass: "ui-state-active",
        tolerance: "intersect",
        drop: function (event, ui) {
          $(this).html("Dropped!");
        }
      };

      $("#myDroppable").droppable( dropOptions );


 

則執行時,當被拖曳的物件約百分之50放入Droppable之中便觸發drop事件,執行結果請參考下圖所示:

clip_image018

圖 9:拖曳不到百分之50不觸發事件。

clip_image020

圖 10:拖曳超過百分之50則觸發事件。

pointer

修改以上範例,將tolerance設為「pointer」:

var dropOptions = {
  accept: checkDraggable,
  activeClass: "ui-state-active",
  tolerance: "pointer",
  drop: function (event, ui) {
    $(this).html("Dropped!");
  }
};

$("#myDroppable").droppable( dropOptions );


只要滑鼠的游標接觸到Droppable的邊界,就會觸發drop事件,執行結果請參考下圖所示:

clip_image022

圖 12:滑鼠的游標接觸到Droppable的邊界觸發drop事件。

touch

修改以上範例,將tolerance設為「touch」:

var dropOptions = {
  accept: checkDraggable,
  activeClass: "ui-state-active",
  tolerance: "touch",
  drop: function (event, ui) {
    $(this).html( "Dropped!" );
  }
};

$("#myDroppable").droppable( dropOptions );


 

執行時,當被拖曳的物件的邊界接觸到Droppable的邊界就會觸發drop事件,執行結果請參考下圖所示:

clip_image024

圖 13:拖曳的物件的邊界接觸到Droppable的邊界觸發drop事件。

Droppable事件

Droppable提供許多事件,在拖放的過程中,會觸發相關的事件,你可以利用事件的回呼函式(Event callback)來攔截這些事件,回應和使用者之間的互動。這些事件包含:

  • · activate:當設定為accept 的Draggable開始拖曳時觸發。
  • · deactivate:當設定為accept 的Draggable拖曳結束之後觸發。
  • · drop:當設定為accept 的Draggable拖曳到Droppable後放開滑鼠時觸發。
  • · out:設定為accept 的Draggable拖曳到Droppable邊界之外(根據tolerance設定而有不同)。
  • · over:當設定為accept 的Draggable拖曳到Droppable上方時觸發(根據tolerance設定而有不同)。

以下範例程式碼註冊了drop、activate、deactivate、out、over、create等事件,在事件發生時,印出事件的名稱到瀏覽器除錯工具的主控台:

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
  <title> </title>
  <link href = "Content/themes/sunny/jquery-ui.css" rel = "stylesheet" />
  <style>
    .ui-widget-content {
      background: lightblue;
    }

    #myDraggable1, #myDraggable2 {
      width: 150px;
      height: 150px;
      padding: 15px;
      cursor: move;
      float: left;
    }

    #myDroppable {
      width: 300px;
      height: 300px;
    }

    .ui-state-active {
      background-color: #ffd800;
    }

    .ui-state-hover {
      background-color: #ff6a00;
    }
  </style>
</head>
<body>

  <div id = "myDroppable" class = "ui-widget-content">
    <h1>我是Droppable</h1>
  </div>


  <br />
  <div id = "myDraggable1" class = "ui-widget-content ">
    <h1> 我是Draggable1 </h1>
  </div>

  <div id = "myDraggable2" class = "ui-widget-content ">
    <h1> 我是Draggable2 </h1>
  </div>

  <script src="Scripts/jquery-2.0.3.min.js"></script>
  <script src="Scripts/jquery-ui-1.10.3.min.js"></script>
  <script>
    (function ($) {

      var dragOptions = {
        start: function (event, ui) {
          $("#myDroppable").html("");
        }
      };

      $("#myDraggable1").draggable( dragOptions );
      $("#myDraggable2").draggable( dragOptions );

      function checkDraggable(ele) {
        return ele.attr("id") == "myDraggable1" ? true : false;
      }


      var dropOptions = {
        accept: checkDraggable,
        activeClass: "ui-state-active",
        tolerance: "intersect",
        drop: function (event, ui) {
          $(this).html("Dropped!");
          console.log("drop");
        },
        activate: function (event, ui) {
          console.log("activate");
        },
        deactivate: function (event, ui) {
          console.log("deactivate");
        },
        out: function (event, ui) {
          console.log("out");
        },
        over: function (event, ui) {
          console.log("over");
        },
        create: function (event, ui) {
          console.log("create");
        }
      };

      $("#myDroppable").droppable( dropOptions );
    })(jQuery);
  </script>
</body>
</html>

 

因為myDraggable1設定為accept,因此拖曳myDraggable1時,便會觸發activate事件,並印出字串到瀏覽器除錯工具的主控台。下圖是Chrome瀏覽器的執行結果,若要開啟除錯工具,只要在瀏覽器上按下「F12」鍵就可以看到除錯工具,執行結果請參考下圖所示:

clip_image026

圖 14:使用除錯工具檢視事件的順序。

因為myDraggable2不是設定為accept的項目,因此拖曳myDraggable2時,便不會觸發Droppable的activate事件,執行結果請參考下圖所示:

clip_image028

圖 15:非accept項目不觸發事件。

若拖曳Draggable到Droppable上方之後放開,則按順序觸發以下事件:activate、over、drop、deactivate,執行結果請參考下圖所示:

clip_image030

圖 16:置放物件時事件順序。

若是從Droppable上方,將Draggable拖曳到Droppable邊界之外,則按順序觸發以下事件:activate、over、out、deactivate,執行結果請參考下圖所示:

clip_image032

圖 17:Draggable拖出Droppable時事件順序。

scope選項

Droppable有一個scope選項,可以將Draggble與Droppable進行分組,分在同一組才能夠做置放的動作。例如以下範例程式碼:

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
  <title> </title>
  <link href = "Content/themes/sunny/jquery-ui.css" rel = "stylesheet" />
  <style>
    .ui-widget-content {
      background: lightblue;
    }

    #myDraggable1, #myDraggable2, #myDraggable3 {
      width: 150px;
      height: 150px;
      padding: 15px;
      cursor: move;
      float: left;
      margin-top: 15px;
    }

    #myDraggable1 {
      clear: both;
    }

    #myDroppable1, #myDroppable2 {
      width: 300px;
      height: 300px;
      float: left;
    }

    .ui-state-active {
      background-color: #ffd800;
    }

    .ui-state-hover {
      background-color: #ff6a00;
    }
  </style>
</head>
<body>

  <div id = "myDroppable1" class = "ui-widget-content">
    <h1> 我是Droppable1 </h1>
  </div>


  <div id = "myDroppable2" class = "ui-widget-content">
    <h1> 我是Droppable2 </h1>
  </div>

  <div style = "clear:both;" />
  <div id = "myDraggable1" class = "ui-widget-content ">
    <h1> 我是Draggable1 </h1>
  </div>

  <div id = "myDraggable2" class = "ui-widget-content ">
    <h1> 我是Draggable2 </h1>
  </div>

  <div id = "myDraggable3" class = "ui-widget-content ">
    <h1> 我是Draggable3 </h1>
  </div>
  <script src="Scripts/jquery-2.0.3.min.js"></script>
  <script src="Scripts/jquery-ui-1.10.3.min.js"></script>
  <script>
    (function ($) {

      var dragOptions1 = {
        scope: "scope1"
      };
      $("#myDraggable1").draggable(dragOptions1);

      var dragOptions2 = {
        scope: "scope2"
      };
      $("#myDraggable2,#myDraggable3").draggable(dragOptions2);

      var dropOptions1 = {
        scope: "scope1",
        activeClass: "ui-state-active",
        tolerance: "intersect",
        drop: function (event, ui) {
          $(this).html("Dropped!");
          console.log("drop");
        },
      };

      $("#myDroppable1").droppable(dropOptions1);

      var dropOptions2 = {
        scope: "scope2",
        activeClass: "ui-state-active",
        tolerance: "intersect",
        drop: function (event, ui) {
          $(this).html("Dropped!");
          console.log("drop");
        },
      };
      $("#myDroppable2").droppable(dropOptions2);
    })(jQuery);
  </script>
</body>
</html>

 

在這個範例之中myDraggable1與myDroppable1設定相同的scope:「scope1」;而myDraggable2、myDraggable3與myDroppable2設定相同的scope:「scope2」,當程式一執行,myDraggable1只有放在myDroppable1才會套用activeClass樣式,並觸發myDroppable1的事件,執行結果請參考下圖所示:

clip_image034

圖 18:myDraggable1和myDroppable1設相同scope。

myDraggable2只有放在myDroppable2才會套用activeClass樣式,並觸發myDroppable2的drop事件,執行結果請參考下圖所示:

clip_image036

圖 19:myDraggable2和myDroppable2設相同scope。

同樣地myDraggable3只有放在myDroppable2才會套用activeClass樣式,並觸發myDroppable2的drop事件,執行結果請參考下圖所示:

clip_image038

圖 20:myDraggable3和myDroppable2設相同scope。

Tags:

.NET Magazine國際中文電子雜誌 | jQuery UI | 許薰尹Vivid Hsu

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List