چگونه یک عنصر HTML را قابل حرکت با موس کنیم؟

یکی از کارهای جالب و رایجی که سال‌هاست در وب رایج شده، این است که عناصر HTML را بتوان با موس جا‌به‌جا کرد. مثلا بتوان یک دیالوگ را جابه‌جا کرد. یا تصاویر یک گالری را و ....

استفاده از این تکنیک در سایت، اگر در جای مناسب استفاده شود، می‌تواند بسیار به جذابیت سایت کمک کند.

یک نمونه‌ی آشنا از این افکت، همان داشبورد (پیشخوان) وردپرس است.

برای ایجاد این تکنیک، راه حل‌های زیادی وجود دارد. راه حل مورد علاقه‌ی من (و احتمالا اکثر طراحان وب دیگر) همان کتابخانه jQueryUI است. کتابخانه jQueryUI یک library برای قابلیت drag & drop دارد که بسیار پیشرفته می‌باشد و در عین حال کار با آن بسیار ساده است.

اما در این مطلب، قصد ندارم jQueryUI را معرفی کنم. در این پست می‌خواهم یک روش دیگر را معرفی کنم که شاید کمتر مورد توجه قرار گرفته باشد (گرچه مطمئن نیستم که این روش پرطرفدار است یا کم طرفدار. برای خودم جدید بود).

کتابخانه مورد نظر من  Draggable.js است که بسیار ساده و کم حجم است. (در حالت عادی 5836 بایت و در حالت فشرده 2799 بایت است.)

در زیر سورس اصلی کتابخانه Draggable.js را می‌بینید:

/*
Copyright (c) 2007, NAKAMURA Satoru
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
* Neither the name of the NAKAMURA Satoru nor the names of its contributors
  may be used to endorse or promote products derived from this
  software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. / /

  • Draggable
  • @website http://clonedoppelganger.net/
  • @version 0.0.2 / / Example: [CSS]——————————————– #element_id { position: absolute; top: 10px; left: 35px; width: 150px; height: 100px; background-color: #00b; cursor: move; } [HTML]——————————————- <div id=“element_id”></div> [JavaScript]————————————- var draggable = new Draggable(“element_id”);

*/

/**

  • Constructor
  • @param {String|Element} element - element id or element object */ var Draggable = function(element) { this.initialize(element); }

/**

  • remove EventListeners */ Draggable.prototype.destroy = function() { this.detach(this.element, “mousedown”, this.observers[“mousedown”]); this.detach(this.html, “mouseup”, this.observers[“mouseup”]); this.detach(this.html, “mousemove”, this.observers[“mousemove”]); }

Draggable.prototype.initialize = function(element) { this.isIE = navigator.appVersion.lastIndexOf(“MSIE”) > 0; this.isFF = navigator.userAgent.toLowerCase().indexOf(“firefox”) > 0; this.html = document.getElementsByTagName(“html”).item(0); if (typeof element == “string”) { this.element = document.getElementById(element); } else { this.element = element; } this.style = this.element.style; this.thisBaseX; this.thisBaseY; this.pageBaseX; this.pageBaseY; this.scrollBaseY; this.isMoving = false; this.observers = {}; var self = this; // Mousedown this.observers[“mousedown”] = this.observe(this.element, “mousedown”, function(event) { if (self.isMoving) return; event = event || window.event; self.disableSelect(event); var position = self.getPosition(); self.thisBaseX = position[“x”]; self.thisBaseY = position[“y”]; self.pageBaseX = event.pageX || event.clientX; self.pageBaseY = event.pageY || event.clientY; if (self.isIE) self.scrollBaseY = document.body.scrollTop; self.isMoving = true; }); // Mousemove this.observers[“mousemove”] = this.observe(this.html, “mousemove”, function(event) { if (!self.isMoving) return; event = event || window.event; var x = (event.pageX || event.clientX) - self.pageBaseX + self.thisBaseX; var y = (event.pageY || event.clientY) - self.pageBaseY + self.thisBaseY; if (self.isIE) y += (parseInt(document.body.scrollTop) - self.scrollBaseY); self.setPosition(x, y); }); // Mouseup this.observers[“mouseup”] = this.observe(this.html, “mouseup”, function(event) { if (!self.isMoving) return; self.enableSelect(); self.isMoving = false; }); }

Draggable.prototype.observe = function(element, name, observer) { if (element.addEventListener) { element.addEventListener(name, observer, false); } else if (element.attachEvent) { element.attachEvent(“on” + name, observer); } return observer; }

Draggable.prototype.detach = function(element, name, observer) { if (element.removeEventListener) { element.removeEventListener(name, observer, false); } else if (element.detachEvent) { try { element.detachEvent(“on” + name, observer); } catch (e) {} } }

Draggable.prototype.setPosition = function(x, y) { this.style.left = x + “px”; this.style.top = y + “px”; }

Draggable.prototype.getPosition = function() { var x, y; // First you acquire from css style information. if (this.style.top == "" || this.style.left == “”) { if (this.element.currentStyle) { x = this.element.currentStyle[“left”]; y = this.element.currentStyle[“top”]; } else { var computedStyle = document.defaultView.getComputedStyle(this.element, null); x = computedStyle[“left”]; y = computedStyle[“top”]; } } else { x = this.style.left; y = this.style.top; } return {“x”: parseInt(x.replace(“px”, “”)) || 0, “y”: parseInt(y.replace(“px”, “”)) || 0}; }

Draggable.prototype.disableSelect = function(event) { if (this.isIE) { document.getElementsByTagName(“body”).item(0).onselectstart = function(e){ return false }; } else { try { event.preventDefault(); } catch(e) {} } }

Draggable.prototype.enableSelect = function() { if (this.isIE) document.getElementsByTagName(“body”).item(0).onselectstart = “”; }

(لطفا اگر از این کتابخانه استفاده می‌کنید، حقوق مولف آن را هم رعایت کنید! )

اکنون برای استفاده از این کتابخانه باید کار های زیر را انجام دهیم:

  1. وارد کردن کتابخانه به کد HTML توسط یک تگ <script>
  2. تگ HTML ای که قرار است قابل جابه‌جا کردن باشد را مشخص کنید و یک id به آن اختصاص دهید. همچنین خاصیت position: absolute را هم به خواص CSS آن اضافه کنید
  3. در برنامه JavaScript یک آبجکت جدید از Draggable ایجاد کنید و نام id ی عنصر HTML را به آن ارسال کنید
  4. تمام!
  5. برای از بین بردن (خنثی کردن) خاصیت جابه‌جایی پذیری، از متد destroy() استفاده کنید

نمونه کد:

<img src="./" width=“100” height=“100” style=“position:absolute”>
<img src="./" width=“100” height=“100” style=“position:absolute”>
<img src="./" width=“100” height=“100” style=“position:absolute”>
<script type=“text/javascript”>
var img = document.getElementsByTagName(“img”);
for (var i = 0; i < img.length; i++) {
new Draggable(img[i]);
}
</script>

یک مثال عملی:

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html lang=“en”>
<head>
<meta http-equiv=“Content-Style-Type” content=“text/css”>
<meta http-equiv=“Content-Script-Type” content=“text/javascript”>
<script type=“text/javascript” src="./Draggable.js"></script>
<style type=“text/css”>
.sample {
position: absolute;
width: 150px;
height: 100px;
cursor: move;
}
#sample1 {
top: 0px;
left: 500px;
background-color: #AEEE8E;
}
#sample2 {
top: 40px;
left: 540px;
background-color: #8ECAEE;
}
#sample3 {
top: 80px;
left: 580px;
background-color: #EE8E97;
}
</style>
</head>
<body>
<div id=“sample1” class=“sample”>Sample 1</div>
<div id=“sample2” class=“sample”>Sample 2</div>
<div id=“sample3” class=“sample”>Sample 3</div>
<script type=“text/javascript”>
var sample1 = new Draggable(“sample1”);
var sample2 = new Draggable(“sample2”);
var sample3 = new Draggable(“sample3”);
</script>
</body>
</html>

کد های کامل را برای دانلود ضمیمه کردم

نظرات شما

قسمت نظرات با استفاده از سرویس دیسکاس پیاده سازی شده است. متاسفانه این سرویس از داخل ایران قابل دسترس نیست. لطفا از آی پی خارجی استفاده کنید.