DDSort icon indicating copy to clipboard operation
DDSort copied to clipboard

点击两个元素,会交换位置

Open 1148444066 opened this issue 6 years ago • 9 comments

当我创建一个元素的时候,聚焦,在创建另一个,有时候会直接换位置.应该是,移动了一点点,然后两个就换位置了,我想监听移动多少来判断换不换位置,但是不知道在哪里让换位停止,

1148444066 avatar Nov 01 '19 03:11 1148444066

你可以用在线编辑器 CodePen 写个例子吗,不太清楚你的问题 😶

Barrior avatar Nov 01 '19 08:11 Barrior

; (function ($) {     /**      * Author: https://github.com/Barrior              DDSort: drag and drop sorting.      * @param {Object} options              target[string]: 可选,jQuery事件委托选择器字符串,默认'li'              cloneStyle[object]: 可选,设置占位符元素的样式              floatStyle[object]: 可选,设置拖动元素的样式              down[function]: 可选,鼠标按下时执行的函数              move[function]: 可选,鼠标移动时执行的函数              up[function]: 可选,鼠标抬起时执行的函数      */     $.fn.DDSort = function (options) {         var $doc = $(document),                 fnEmpty = function () {},                 settings = $.extend(true, {                     down: fnEmpty,                     move: fnEmpty,                     up: fnEmpty,                     target: '.line',                     cloneStyle: { //                         拖动时,放置位置背景色                         'background-color': 'rgb(255,255,255)',                         'border': '6px dashed rgb(86,170,255)'                     },                     floatStyle: {                         //用固定定位可以防止定位父级不是Body的情况的兼容处理,表示不兼容IE6,无妨                         'position': 'fixed', //                        'position': 'absolute',                         'box-shadow': '10px 10px 20px 0 #eee',                         'webkitTransform': 'rotate(4deg)',                         'mozTransform': 'rotate(4deg)',                         'msTransform': 'rotate(4deg)',                         'transform': 'rotate(4deg)'                     }

                }, options);

        return this.each(function () {

            var that = $(this),                     height = 'height',                     width = 'width';

            if (that.css('box-sizing') == 'border-box') {                 height = 'outerHeight';                 width = 'outerWidth';             }

            that.on('mousedown.DDSort', settings.target, function (e) {                 //只允许鼠标左键拖动                 if (e.which != 1) {                     return;                 }                 //防止表单元素失效                 var tagName = e.target.tagName.toLowerCase();                 if (tagName == 'input' || tagName == 'textarea' || tagName == 'select') {                     return;                 }

                var THIS = this,                         $this = $(THIS),                         offset = $this.offset(),                         disX = e.pageX - offset.left,                         disY = e.pageY - offset.top,                         clone = $this.clone()                         .css(settings.cloneStyle)                         .css('height', $this height )                         .empty(),                         hasClone = 1,                         //缓存计算                         thisOuterHeight = $this.outerHeight(),                         thatOuterHeight = that.outerHeight(),                         //滚动速度                         upSpeed = thisOuterHeight,                         downSpeed = thisOuterHeight,                         maxSpeed = thisOuterHeight * 3;

                settings.down.call(THIS);

                $doc.on('mousemove.DDSort', function (e) {                     if (hasClone) {                         $this.before(clone)                                 .css('width', $this width )                                 .css(settings.floatStyle)                                 .appendTo($this.parent());                         hasClone = 0;                     }

                    var left = e.pageX - disX,                             top = e.pageY - disY,                             prev = clone.prev(),                             next = clone.next().not($this);

                    $this.css({                         left: left,                         top: top                     });

                    //向上排序                     if (prev.length && top < prev.offset().top + prev.outerHeight() / 2) {                         clone.after(prev);                         //向下排序                     } else if (next.length && top + thisOuterHeight > next.offset().top + next.outerHeight() / 2) {                         clone.before(next);                     }

                    /**                      * 处理滚动条                      * that是带着滚动条的元素,这里默认以为that元素是这样的元素(正常情况就是这样),如果使用者事件委托的元素不是这样的元素,那么需要提供接口出来                      */                     var thatScrollTop = that.scrollTop(),                             thatOffsetTop = that.offset().top,                             scrollVal;

                    //向上滚动                     if (top < thatOffsetTop) {

                        downSpeed = thisOuterHeight;                         upSpeed = ++upSpeed > maxSpeed ? maxSpeed : upSpeed;                         scrollVal = thatScrollTop - upSpeed;

                        //向下滚动                     } else if (top + thisOuterHeight - thatOffsetTop > thatOuterHeight) {                         upSpeed = thisOuterHeight;                         downSpeed = ++downSpeed > maxSpeed ? maxSpeed : downSpeed;                         scrollVal = thatScrollTop + downSpeed;                     }                     that.scrollTop(scrollVal);                     settings.move.call(THIS);                 })                         .on('mouseup.DDSort', function () {                             $doc.off('mousemove.DDSort mouseup.DDSort');                             //click的时候也会触发mouseup事件,加上判断阻止这种情况                             if (!hasClone) {                                 clone.before($this.removeAttr('style')).remove();                                 settings.up.call(THIS);                             }                         });                 return false;             });         });     };

})(jQuery);

使用时发现,点击一个元素,在点击另一个元素,点击第二个元素的时候,鼠标会出现拖拽的效果,导致两个元素交换位置,所以我想监听移动了多少,不够多就回到原位,不执行换位。后面代码有点没看懂,想知道怎么才能在执行回去,  that.scrollTop(scrollVal);  settings.move.call(THIS);  clone.before($this.removeAttr('style')).remove(); settings.up.call(THIS);

我猜测大概是这几个方法相关,没试出来

------------------ 原始邮件 ------------------ 发件人: "花祁"<[email protected]>; 发送时间: 2019年11月1日(星期五) 下午4:01 收件人: "Barrior/DDSort"<[email protected]>; 抄送: "郭林"<[email protected]>;"Author"<[email protected]>; 主题: Re: [Barrior/DDSort] 点击两个元素,会交换位置 (#19)

你可以用在线编辑器 CodePen 写个例子吗,不太清楚你的问题 😶

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

1148444066 avatar Nov 01 '19 08:11 1148444066

这样的话,你可以在 down 事件的时候看要不要记录移动的初始位置,最后在 up 事件里执行判断移动了多少,实现你说的逻辑了

Barrior avatar Nov 01 '19 08:11 Barrior

好的,谢谢! 你是用下面这个来记录位置的吗?前端人员走了,没搞过前端,看着有点头大 就是,不知道,怎么才能让交换事件取消,我先还以为把hasClone改为0就可以了,或者加个2标识不移动,哈哈 谢谢了,东西还是很有用的   var THIS = this,                         $this = $(THIS),                         offset = $this.offset(),                         disX = e.pageX - offset.left,                         disY = e.pageY - offset.top,                         clone = $this.clone()                         .css(settings.cloneStyle)                         .css('height', $this height )                         .empty(),                         hasClone = 1,                         //缓存计算                         thisOuterHeight = $this.outerHeight(),                         thatOuterHeight = that.outerHeight(),                         //滚动速度                         upSpeed = thisOuterHeight,                         downSpeed = thisOuterHeight,                         maxSpeed = thisOuterHeight * 3;

                settings.down.call(THIS);

------------------ 原始邮件 ------------------ 发件人: "花祁"<[email protected]>; 发送时间: 2019年11月1日(星期五) 下午4:21 收件人: "Barrior/DDSort"<[email protected]>; 抄送: "郭林"<[email protected]>;"Author"<[email protected]>; 主题: Re: [Barrior/DDSort] 点击两个元素,会交换位置 (#19)

这样的话,你可以在 down 事件的时候看要不要记录移动的初始位置,最后在 up 事件里执行判断移动了多少,实现你说的逻辑了

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

1148444066 avatar Nov 01 '19 08:11 1148444066

是的,好像源码里没有传 event 对象到 down 参数里,看你需要吗。另外好像还不没有API让交换事件取消,如果非要取消的话,需要改动源码或者在 down 函数里抛出错误,当然得在代码上层捕获一下错误,避免报错

Barrior avatar Nov 01 '19 08:11 Barrior

我瞧瞧吧,谢谢啦

------------------ 原始邮件 ------------------ 发件人: "花祁"<[email protected]>; 发送时间: 2019年11月1日(星期五) 下午4:44 收件人: "Barrior/DDSort"<[email protected]>; 抄送: "郭林"<[email protected]>;"Author"<[email protected]>; 主题: Re: [Barrior/DDSort] 点击两个元素,会交换位置 (#19)

是的,好像源码里没有传 event 对象到 down 参数里,看你需要吗。另外好像还不没有API让交换事件取消,如果非要取消的话,需要改动源码或者在 down 函数里抛出错误,当然得在代码上层捕获一下错误,避免报错

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

1148444066 avatar Nov 01 '19 08:11 1148444066

  //向上排序                     if (prev.length && top < prev.offset().top + prev.outerHeight() / 2) {                         clone.after(prev);                         //向下排序                     } else if (next.length && top + thisOuterHeight > next.offset().top + next.outerHeight() / 2) {                         clone.before(next);                     }

这个是不是判断移动了多少,超过一半就交换,是不是这里,写错了,才导致,移动一点就会交换

------------------ 原始邮件 ------------------ 发件人: "花祁"<[email protected]>; 发送时间: 2019年11月1日(星期五) 下午4:21 收件人: "Barrior/DDSort"<[email protected]>; 抄送: "郭林"<[email protected]>;"Author"<[email protected]>; 主题: Re: [Barrior/DDSort] 点击两个元素,会交换位置 (#19)

这样的话,你可以在 down 事件的时候看要不要记录移动的初始位置,最后在 up 事件里执行判断移动了多少,实现你说的逻辑了

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

1148444066 avatar Nov 06 '19 05:11 1148444066

这个还要看你页面的DOM结构和样式定义,很难说

Barrior avatar Nov 06 '19 06:11 Barrior

好滴,搞定了,谢谢

------------------ 原始邮件 ------------------ 发件人: "花祁"<[email protected]>; 发送时间: 2019年11月6日(星期三) 下午2:21 收件人: "Barrior/DDSort"<[email protected]>; 抄送: "郭林"<[email protected]>;"Author"<[email protected]>; 主题: Re: [Barrior/DDSort] 点击两个元素,会交换位置 (#19)

这个还要看你页面的DOM结构和样式定义,很难说

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

1148444066 avatar Nov 06 '19 06:11 1148444066