Sortable.js 1.8.3
http://rubaxa.github.io/Sortable/
写在最前
实习的时候接到的第一个任务涉及到拖拽排序的需求,当时采用了Sortable.js这个插件。正式工作后,多次出现相关的需求,也越来越多使用到它。在大神同事的带动下,学习了一下它的源码,发现确实值得一读。特以此篇,作为解读过程中的笔记记录。
源码解读
代码规范
Sortable用下划线标明所有内部方法,并对其进行绑定。
整体结构
|
|
Sortable将sortableFactory
函数作为sortableModule
的参数,通过一个立即执行函数实现。在sortableModule
中依次对Require
、Node
和Meteor
做了兼容。
智能滚动:_autoScroll
当元素被拖拽出含滚动条的父区域时,此函数会根据设定的scroll
选项,判断是否需要将页面进行自动滚动。程序通过以下代码设置滚动元素scrollEl
。
程序首先将滚动元素设置为当前鼠标按下的根节点rootEl
,根据比较offsetWidth
(offsetHeight
)和scrollWidth
(scrollHeight
)来判断哪个父节点存在滚动条,若存在则将当前元素设置为滚动元素。
Tip: 这里以及源码中很多位置判断,都涉及到了容易混淆的几个长宽变量。这里借用以下图解方便学习记忆。
之后通过计算vx
和vy
两个变量来确定滚动方向。当鼠标与某边缘的距离小于设置好的灵敏度sens
时,就会改变相应的vx
和vy
。此外当找不到相应的滚动元素时,会将当前窗口设置为滚动元素进行计算。
这里用到了getBoundingClientRect
函数,它会返回一个矩形对象,其中包含了四个距离位置和一个宽度值,四个距离如下解释,具体含义也可从下面的图中看出。
top
:元素上边距离页面上边的距离;right
:元素右边距离页面左边的距离;bottom
:元素下边距离页面上边的距离;left
:元素左边距离页面左边的距离;
另外,有一个与getBoundingClientRect
相似的函数getClientRects
,它们之间的区别在于后者返回的是一个TextRectangle
集合,从下面的结果可以看出两者差异。
基础方法
浏览器支持判断
Sortable中有一些对于浏览器支持的判断,可用于浏览器对H5和CSS3支持的检验。
切换类名:_toggleClass
Sortable中提供一个toggleClass
函数用于切换类名,其中用到了className
和classList
两种不同的方式。
这里很好地体现了这两种方式的特性。借用张鑫旭大神的话,className
类似于切水果的一刀切,因此在当前对象class
为空时,就直接用className
进行赋值。而反之则可通过classList
的add
和remove
方法来进行类名切换。
获取/改变样式:_css
程序里提供_css
函数用于处理元素样式,根据给出的参数确定是获取属性值,还是设置属性。函数中首先通过getComputedStyle
来获取元素的所有CSS属性值,随后用currentStyle
解决IE兼容性问题。当提供val
参数后,同样对webkit特有的样式和属性类型进行了判断。
其中getComputedStyle
的用法为var style = window.getComputedStyle("元素", "伪类");
,虽然只能获取样式,不能设置,但可以获取到最终应用在元素上的所有CSS属性对象(厉害哟)。
排序方法:sort
程序中提供一个排序方法,特意列出的原因在于,工作初期自己对于拖拽排序的考虑过于复杂,认为在每一次拖拽操作后都需要对每个元素对应的数据进行相应的排序操作。之后发现其实只需在最后保存的时候,根据当时的DOM节点状态,对相应数据进行整理即可。
下面的sort
函数没有涉及到数据处理,但思维类似。虽然这是一个很简单的思路,但刚开始一直没有考虑到,在工作上花费了不必要的时间。