最近由于业务需要,要有拖拽将页面上控件进行一个排序的调整,网上找的控件大多不能完美达到预期效果,就自己做了一个小插件,也记录一下,毕竟是第一次写js插件
插件代码:
/**
* Created by linxz on 2018/1/8.
*/
;(function($,window,document,undefined){
$.fn.drag = function(option){
var taglist=this;
$('body').append('<div id="insert" style="display:none;"></div>');
var currentTag=null;
var defaults={
insertbox:null,//'border:1px solid red;vertical-align: bottom;margin-left:10px;'//填充框模型的css
changeFilter:taglist
};
var settings = $.extend({}, defaults, option);
function showInsert(){
if(settings.insertbox!=null){
$('#insert').css(settings.insertbox);
}
$('#insert').css('display','inline-block');
}
function hideInsert(){
$('#insert').hide();
}
//获取dom的left位置
function getElementLeft(element){
var actualLeft = element.offsetLeft;
var current = element.offsetParent;
while (current !== null){
actualLeft+=current.offsetLeft;
current =current.offsetParent;
}
return actualLeft;
}
//获取dom的top位置
function getElementTop(element){
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current !== null){
actualTop+=current.offsetTop;
current =current.offsetParent;
}
return actualTop;
}
/**
* 判断是否有遮盖,如果有遮盖,则返回遮盖的dom
*/
function iscover(JQuery){
var covermostdom=[];//遮盖的dom元素
var lefttop={x:getElementLeft(JQuery[0]),y:getElementTop(JQuery[0])};//当前元素的左上角位置
var leftbottom={x:getElementLeft(JQuery[0]),y:getElementTop(JQuery[0])+JQuery.height()};//当前元素的左下角位置
var righttop={x:getElementLeft(JQuery[0])+JQuery.width(),y:getElementTop(JQuery[0])};//当前元素的右上角位置
var rightbottom={x:getElementLeft(JQuery[0])+JQuery.width(),y:getElementTop(JQuery[0])+JQuery.height()};//当前元素的右下角位置
$.each(settings.changeFilter,function(i,o){
if(o!=JQuery[0]){
//排除本身
var olefttop={x:getElementLeft(o),y:getElementTop(o)};//当前元素的左上角位置
var oleftbottom={x:getElementLeft(o),y:getElementTop(o)+$(o).height()};//当前元素的左下角位置
var orighttop={x:getElementLeft(o)+$(o).width(),y:getElementTop(o)};//当前元素的右上角位置
var orightbottom={x:getElementLeft(o)+$(o).width(),y:getElementTop(o)+$(o).height()};//当前元素的右下角位置
if((lefttop.y>=olefttop.y&&lefttop.y<=oleftbottom.y)||(leftbottom.y>=olefttop.y&&leftbottom.y<=oleftbottom.y)){
//Y轴相交
if((righttop.x>=olefttop.x&&righttop.x<=orighttop.x)||(lefttop.x>=olefttop.x&&lefttop.x<=orighttop.x)){
//X轴相交
covermostdom.push({item:o,position:{olefttop,oleftbottom,orighttop,orightbottom}});
}
}
}
});
var nearstdom=null;
var middlegap=null;
var jqueryxmiddle=(lefttop.x+righttop.x)/2;//当前元素的X轴中点
$.each(covermostdom,function(i,o){
//获取元素的中点,判断距离哪个元素最近
var currentxmiddle=(o.position.olefttop.x+o.position.orighttop.x)/2;
if(middlegap==null){
//第一次的时候先初始化中点距离
middlegap=Math.abs(jqueryxmiddle-currentxmiddle);
nearstdom=o.item;
}
if(Math.abs(jqueryxmiddle-currentxmiddle)<=middlegap){
middlegap=Math.abs(jqueryxmiddle-currentxmiddle);
nearstdom=o.item;
}
});
return nearstdom;
}
/**
* 判断元素1是在元素2的左边还是右边
* 根据元素1的left坐标和元素2的中点坐标进行判断,如果元素1的left在元素2中点的左边则返回left,否则返回right
* @param dom1 元素1,dom结点
* @param dom2 元素2,dom结点
*/
function isLeftOrRight(dom1,dom2){
x1=getElementLeft(dom1);
x2=getElementLeft(dom2)+($(dom2).width()/2);
if(x1<=x2){
return 'left';
}else{
return 'right';
}
}
function startDrag(target,event){
showInsert();
$('#insert').height(target.height());
// $('#insert').width(target.width());
target.css({position:'absolute'});
}
function dragging(target,event){
var covertarget=iscover(target);
if(covertarget!=null){
//如果有遮盖,则进行换位,提示换位
if(isLeftOrRight(target[0],covertarget)=='left'){
$(covertarget).before($('#insert'));
}else{
$(covertarget).after($('#insert'));
}
showInsert();
}else{
//没有遮盖,不需要进行换位,隐藏换位提示
hideInsert();
}
target.css({left:event.pageX-(target.width()/2),top:event.pageY-(target.height())});
}
function dragEnd(target,event){
/*var covertarget=iscover(target);
if(covertarget!=null){
//如果有遮盖,则进行换位
if(isLeftOrRight(target[0],covertarget)=='left'){
$(covertarget).before(target);
}else{
$(covertarget).after(target);
}
}*/
if($('#insert').is(':visible')){
//如果换位提示是显示的,则进行换位,换位完成之后隐藏换位提示
$('#insert').after(target);
hideInsert();
}
target.css({position:'static',left:0,top:0});
}
$(this).mousedown(function(event){
if(event.button==0){//是鼠标左键
currentTag=$(this);
startDrag(currentTag,event);
}else if(event.button==2){//是鼠标右键
//用于保留右键菜单设置控件
}
});
$(document).mousemove(function(event){
if(currentTag!=null){
dragging(currentTag,event);
}
});
$(document).mouseup(function(event){
if(currentTag!=null){
dragEnd(currentTag,event);
}
currentTag=null;
});
return this;
}
})(jQuery,window,document);
调用方式:
var tt=$('.textDiv').closest('.ed-figure').drag({//调用方式:$(JQuery).drag()或者$(JQuery).drag({});可以传入参数,有需要可以自己添加别的参数
insertbox:{'border':'1px solid green','vertical-align': 'bottom','margin-left':'10px'},
changeFilter:filterArr//$('.ed-figure')规定要拖动的控件可以放在哪些元素左右两边,可以是dom数组,也可以是JQuery选择器
});