拖拽功能恐怕也是AJAX最明顯的特徵之一了,之前自己實現過拖拽效果,效能並不好,尤其在IE下的反映,
在網上搜尋的時候發現大部分的實現效果都是類似這樣的:
(1) 建立mousedown, mousemove, mouseup的監聽事件
(2) 在mousemove的監聽事件中不斷的重設被拖拽元素的left, top值 (效能問題就出在這裡)
因為mousemove事件的執行是當滑鼠每移動一個像素,就會觸發綁定的事件相應函數,而JS操作DOM又是非常耗資源的;
後來看到scriptaculous這個架構(基於prototype.js)實現的拖拽效能非常好,主要是在IE下的反映,
開啟代碼從一堆源碼中找到了一句關鍵詞:setInterval,這個輪詢函數將滑鼠的移動和被拖拽元素的移動類比在兩個線程上執行,
而且不用在每移動一個像素就對元素的座標操作一次,這樣大大的節省了資源的利用
貼代碼
var Drag = {<br />init: function(boxname, handlename) {<br />this.BOX = boxname;<br />this.HANDLE = handlename;<br /> this.POINTER_X = 0;<br /> this.POINTER_Y = 0;<br />this.CURRENT_X = 0;<br />this.CURRENT_Y = 0;<br />this.moveTimer = null;<br /> var self = this;<br /> this.observe(handlename, 'mousedown', function(event) {<br /> self.mouseDown(event);<br /> });<br /> this.observe(document.body, 'mouseup', function(event) {<br /> self.mouseUp(event);<br /> });<br /> this.observe(document.body, 'mousemove', function(event) {<br /> self.mouseMove(event);<br /> });<br /> },<br /> $: function(obj) {<br /> if(typeof obj == "object") return obj;<br /> return document.getElementById(obj);<br /> },<br /> observe: function(e, n, h) {<br />e = this.$(e);<br />if(e == window || e == document.body) {<br />e = document.all ? document.body : window;<br />}<br />if (e.addEventListener) {<br /> e.addEventListener(n, h, false);<br /> } else {<br /> e.attachEvent("on" + n, h);<br />}<br />},<br />stopObserving: function(e, n, h) {<br />e = this.$(e);<br />if(e == window || e == document.body) {<br />e = document.all ? document.body : window;<br />}<br /> if (e.removeEventListener) {<br /> e.removeEventListener(n, h, false);<br /> } else {<br /> e.detachEvent("on" + n, h);<br /> }<br />},<br />mouseDown: function(event) {<br />event = event || window.event;<br />this.POINTER_X = event.clientX;<br />this.POINTER_Y = event.clientY;<br />this.mouseMoveListener(this.BOX);<br />},<br />mouseUp: function(event) {<br />event = event || window.event;<br />this.POINTER_X = event.clientX;<br />this.POINTER_Y = event.clientY;<br />this.clearMouseMoveListener();<br />},<br />mouseMove: function(event) {<br />event = event || window.event;<br />this.CURRENT_X = event.clientX;<br />this.CURRENT_Y = event.clientY;<br />},<br />mouseMoveListener: function(obj) {<br />obj = this.$(obj);<br />var self = this;<br />this.moveTimer = setInterval(function() {<br />self.rePositionBox(obj);<br />}, 10);<br />},<br />clearMouseMoveListener: function() {<br />if(this.moveTimer) {<br />clearInterval(this.moveTimer);<br />this.moveTimer = null;<br />}<br />},<br />rePositionBox: function(e, x, y) {<br />e = this.$(e);<br />var x = this.CURRENT_X == 0 ? 0 : this.CURRENT_X - this.POINTER_X;<br />var y = this.CURRENT_Y == 0 ? 0 : this.CURRENT_Y - this.POINTER_Y;<br />var currentX = parseInt(e.style.left);<br />var currentY = parseInt(e.style.top);<br />with(e.style) {<br />left = currentX+x+"px";<br />top = currentY+y+"px";<br />};<br />this.POINTER_X = this.CURRENT_X;<br />this.POINTER_Y = this.CURRENT_Y;<br />}<br />};<br />
HTML.
<?xml version="1.0" encoding="gb2312"?><!--<br /><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><br />--><br /><html xmlns="http://www.w3.org/1999/xhtml"><br /><head><br /> <mce:script src="./drag.js" mce_src="drag.js" type="text/javascript"></mce:script><br /> <mce:script type="text/javascript" language="javascript"><!--<br /> window.onload = function() {<br /> // setTimeout("Effect.toggle('revertbox1','appear')",200);<br /> // $('handle1').observe('dblclick',function() {Effect.Puff('revertbox1');});<br /> // $('viewbigphoto1').observe('click',function() {window.open("./images/fjc1.jpg","fjc","width=800px,height=600px,resizable=yes")});<br /> /*<br /> new Draggable('revertbox1',{<br /> scroll:document.body,<br /> handle:'handle1'<br /> });<br /> */<br /> Drag.init('revertbox1', 'handle1');<br /> };</p><p>// --></mce:script><br /> <mce:style><!--<br /> body {<br /> background:#F8F7F5;<br /> color:#666666;<br /> font-family:Arial,宋體,Helvetica,sans-serif;<br /> font-size:10pt;<br /> font-weight:bold;<br /> margin:0px;<br /> }</p><p>--></mce:style><style mce_bogus="1"> body {<br /> background:#F8F7F5;<br /> color:#666666;<br /> font-family:Arial,宋體,Helvetica,sans-serif;<br /> font-size:10pt;<br /> font-weight:bold;<br /> margin:0px;<br /> }<br /> </style><br /></head><br /><body><br /><div id="revertbox1" style="z-index:1;width:180px;height:200px;border:1px solid #999999;top:126;left:38;position:absolute;background:#d7be03;"><br /> <div id="handle1" style="width:100%;height:24px;padding:0px;margin:0px;border-bottom:1px solid #999999;background:#CCFFCC;cursor:move;"> Mountaineering</div><br /> <div id="viewbigphoto1" style="width:100%;height:100%;"><br /> </div><br /> </div><br /> </div><br /><div id="revertbox1" style="z-index:1;width:180px;height:200px;border:1px solid #999999;top:126;left:38;position:absolute;background:#d7be03;"><br /> <div id="handle1" style="width:100%;height:24px;padding:0px;margin:0px;border-bottom:1px solid #999999;background:#CCFFCC;cursor:move;"> Mountaineering</div><br /> <div id="viewbigphoto1" style="width:100%;height:100%;"><br /> </div><br /> </div><br /> </div><br /></body><br /></html>