Sortable.js拖拽排序使用方法解析

时间:2021-05-26

最近公司项目经常用到一个拖拽 Sortable.js插件,所以有空的时候看了 Sortable.js 源码,总共1300多行这样,写的挺完美的。

官网: http://rubaxa.github.io/Sortable/

拖拽的时候主要由这几个事件完成,

ondragstart 事件:当拖拽元素开始被拖拽的时候触发的事件,此事件作用在被拖曳元素上
ondragenter 事件:当拖曳元素进入目标元素的时候触发的事件,此事件作用在目标元素上
ondragover事件:拖拽元素在目标元素上移动的时候触发的事件,此事件作用在目标元素上
ondrop 事件:被拖拽的元素在目标元素上同时鼠标放开触发的事件,此事件作用在目标元素上
ondragend 事件:当拖拽完成后触发的事件,此事件作用在被拖曳元素上

主要是拖拽的时候发生ondragstart事件和ondragover事件的时候节点交换位置,其实就是把他们的节点互相调换,当然这只是最简单的拖拽排序方式,里面用到了许多技术比用判断拖拽滚动条的时候是滚动拖拽元素上面的根节点的父节点滚动,还是滚动window上面的滚动条, 还有拖拽的时候利用getBoundingClientRect() 属性判断鼠标是在dom节点的左边,右边,上面,还是下面。还有利用回调和函数式编程声明函数,利用布尔值相加相减去,做0和1判断,利用了事件绑定来判定两个列表中的不同元素,这些都是很有趣的技术。

注意:这个插件是用html5 拖拽的所以也不支持ie9 以下浏览器

接下来我们先看看简单的简单的dome,先加载他的拖拽js Sortable.js 插件,和app.css. 创建一个简单的拖拽很简单 只要传递一个dom节点进去就可以,第二个参数传一个空对象进去

当然app.css,加不加无所谓,如果不加的话要加一个样式就是

.sortable-ghost { opacity: 0.4; background-color: #F4E2C9; }

拖拽的时候有阴影效果更好看些

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://pile(tpl)({title: 'test'})</script> 意思是当节点是TEMPLATE标签的时候则表示该搜索标签已经到达了最顶端 */ while (el && (el = el.previousElementSibling)) { if (el.nodeName.toUpperCase() !== 'TEMPLATE' && _matches(el, selector)) { index++; } } return index; } /*********************************************************************************************** *函数名 :_matches *函数功能描述 : 匹配tag和tag,匹配clsss和tag, *函数参数 : el: 类型:obj,当前拖拽节点dom selector: 类型:string, tag或者clasname *函数返回值 : 类型:Boolean,真假,selector如果传递的是tag,则当前的el的tag和selector的tag要同样,或当前的el的class含有selector 中的calss则返回真,否则返回假 *作者 : *函数创建日期 : *函数修改日期 : *修改人 : *修改原因 : *版本 : *历史版本 : ***********************************************************************************************/ function _matches(/**HTMLElement*/el, /**String*/selector) { /* el 目标节点 selector = /[uo]l/i.test(el.nodeName) ? 'li' : '>*', selector=>* */ if (el) { //split 字符串截取 //没有.则返回为空 但是selector 的值还是原来的 li 但是selector 类型变成了数组 //shift 删除数组第一个字符串并返回该字符串 //toUpperCase 把字符串变成大写 //整个思维是把一个字符串比如 ".aa .ccc .bbb .ddd" 然后提取到改class中的第一个变成大写 AA selector = selector.split('.'); // 这里分割判断是class还是tag var tag = selector.shift().toUpperCase(), // class //join 把数组["a","b","c"]变成a|b|c // (?=)会作为匹配校验,但不会出现在匹配结果字符串里面 就是前后必须要匹配有空格 但是不会匹配上空格 //比如匹配 " aa bb cc " 匹配到 [aa,bb,cc] re = new RegExp('\\s(' + selector.join('|') + ')(?=\\s)', 'g'); // return ( //tag === '' el.nodeName.toUpperCase() == tag //selector.length=2 tag === '' true //el.nodeName.toUpperCase() == tag 如果父节点是ul ol 则这里条件为真 (tag === '' || el.nodeName.toUpperCase() == tag) && //匹配 class 的长度等于标签的长度,。这里意思是在el中匹配的class含有selector的class就能匹配上 (!selector.length || ((' ' + el.className + ' ').match(re) || []).length == selector.length) ); } return false; } /*********************************************************************************************** *函数名 :_throttle *函数功能描述 : 回调初始化一个函数 并且调用该回调函数 *函数参数 : callback: 类型:function,回调函数 ms: 类型:number, 毫秒 *函数返回值 : 类型:function,函数,可以用来声明一个函数作用 *作者 : *函数创建日期 : *函数修改日期 : *修改人 : *修改原因 : *版本 : *历史版本 : ***********************************************************************************************/ function _throttle(callback, ms) { var args, _this; return function () { if (args === void 0) { args = arguments; //arguments 就是callback中的callback 所以参数决定来源于它 _this = this; //执行回调函数 setTimeout(function () { if (args.length === 1) { //当callback 函数一个参数的时候 callback.call(_this, args[0]); } else { callback.apply(_this, args);//当callback 函数多个参数的时候 } args = void 0; }, ms); } }; } /*********************************************************************************************** *函数名 :_extend *函数功能描述 :类合并 *函数参数 : dst:类型:obj,子类 src:类型:obj,父类 *函数返回值 : dst 子类 *作者 : *函数创建日期 : *函数修改日期 : *修改人 : *修改原因 : *版本 : *历史版本 : ***********************************************************************************************/ function _extend(dst, src) { if (dst && src) { for (var key in src) { //遍历对象 if (src.hasOwnProperty(key)) { //过滤原型 dst[key] = src[key]; } } } return dst; }//声明一个类utils // Export utils Sortable.utils = { on: _on, off: _off, css: _css, find: _find, is: function (el, selector) { return !!_closest(el, selector, el); }, extend: _extend, throttle: _throttle, closest: _closest, toggleClass: _toggleClass, index: _index }; /** * Create sortable instance * @param {HTMLElement} el * @param {Object} [options] */ /*********************************************************************************************** *函数名 :Sortable.create *函数功能描述 :在类Sortable中添加多个一个方法,而调用Sortable构造函数实例化给Sortable.create 属性,创建了拖拽功能 *函数参数 : el:类型:obj,拖拽列表的dom节点 options:类型:obj,拖拽的参数 *函数返回值 : dst 子类 *作者 : *函数创建日期 : *函数修改日期 : *修改人 : *修改原因 : *版本 : *历史版本 : ***********************************************************************************************/ Sortable.create = function (el, options) { return new Sortable(el, options); }; // Export Sortable.version = '1.4.2'; //版本 return Sortable;});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章