一、前言
最開始實現滑鼠拖曳元素的目的就是在一個頁面上拖曳很多小圓點,用於固定定位,然後在複製HTML,貼上在頁面的開發程式碼中,就是這麼一個功能,實現了很多遍,都沒有做好,不得已採用了jQuery.fn.draggable插件,在接觸一些資料和別人的思路,今天終於把這個拖動功能給完善了,下面就來看看它的實現
二、設計想法
在拖曳元素上綁定滑鼠按下事件,在文件物件中綁定滑鼠移動,滑鼠彈起事件;
為什麼不把三個事件都綁定在拖曳元素上,這是因為當滑鼠移動太快時,滑鼠移動和彈起事件處理程序將不會執行
$(document)
.bind('mousemove', fn)
.bind('mouseup', fn);
三、源碼實作細節
在實作原始碼中有很多需要值得注意的地方:
1、先在滑鼠按下事件中,當點選拖曳元素中,可能會選擇區域文字,這並不是我們所需要的,解決方法如下:
}
進一步思考:為什麼會出現上面問題,原因在於變數x可能會小於limitObj._left或大於limitObj._right,變數y同理,
因此程式碼需要像下面這樣處理:
複製程式碼
function _initOptions() {
var noop = function(){}, defaultOptions;
defaultOptions = { // 默认配置项
boundaryElem: 'body' // 边界容器
};
options = $.extend( defaultOptions, options || {} );
$boundaryElem = $(options.boundaryElem);
dragStart = options.dragStart || noop,
dragMove = options.dragMove || noop,
dragEnd = options.dragEnd || noop;
}
function _drag(e) {
var clientX, clientY, offsetLeft, offsetTop,
$target = $(this), self = this;
limitObj = {
_left: 0,
_top: 0,
_right: ($boundaryElem.innerWidth() || $(window).width()) - $target.outerWidth(),
_bottom: ($boundaryElem.innerHeight() || $(window).height()) - $target.outerHeight()
};
// 记录鼠标按下时的位置及拖动元素的相对位置
clientX = e.clientX;
clientY = e.clientY;
offsetLeft = this.offsetLeft;
offsetTop = this.offsetTop;
dragStart.apply(this, arguments);
$(document).bind('mousemove', moveHandle)
.bind('mouseup', upHandle);
// 鼠标移动事件处理
function moveHandle(e) {
var x = e.clientX - clientX + offsetLeft;
var y = e.clientY - clientY + offsetTop;
$target.css({
left: Math.max( Math.min(x, limitObj._right), limitObj._left) + 'px',
top: Math.max( Math.min(y, limitObj._bottom), limitObj._top) + 'px'
});
dragMove.apply(self, arguments);
🎜 > e.preventDefault();
}
的usemove', moveHandle);
dragEnd.apply(self, arguments);
}
}
_initOptions(); // 初始化設定物件
$(this)
.css({ position: 'absolute' }) .bind('mousedown', function(e){
_drag.apply(this, [e]);
e.preventDefault();
// for firefox ie9 || less than ie9
window.getSelection ? window.getSelection().removeAllRanges() : });
return this;
}
});
實例呼叫:
複製程式碼