对drag插件的优化
parent
a2d9603eaa
commit
64799069d3
|
@ -3,7 +3,7 @@
|
||||||
> 使用时,在目标元素上添加`:drag`属性即可以实现拖拽功能。
|
> 使用时,在目标元素上添加`:drag`属性即可以实现拖拽功能。
|
||||||
|
|
||||||
## 依赖
|
## 依赖
|
||||||
> 依赖`yua`框架
|
> 依赖`Anot`框架
|
||||||
|
|
||||||
## 浏览器兼容性
|
## 浏览器兼容性
|
||||||
+ chrome
|
+ chrome
|
||||||
|
@ -24,62 +24,62 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<style>
|
<style>
|
||||||
* {margin:0;padding:0}
|
* {margin:0;padding:0}
|
||||||
.box {width:100px;height:100px;background:#f30;}
|
.box {width:200px;height:100px;background:#aaa;}
|
||||||
|
.box .handle {width:200px;height:30px;background:#f30;}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body :controller="test">
|
<body :controller="test">
|
||||||
|
|
||||||
<div class="box" :drag></div>
|
<div class="box" :drag></div>
|
||||||
|
|
||||||
<script src="/js/yua.js"></script>
|
|
||||||
<script>
|
|
||||||
|
|
||||||
require(['lib/drag/main'], function(){
|
|
||||||
|
|
||||||
yua({
|
|
||||||
$id: 'test'
|
|
||||||
})
|
|
||||||
yua.scan()
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
```html
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<style>
|
|
||||||
* {margin:0;padding:0}
|
|
||||||
.box {width:200px;height:100px;background:#aaa;}
|
|
||||||
.box .handle {width:200px;height:30px;background:#f30;}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body :controller="test">
|
|
||||||
|
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="handle" :drag="box"></div>
|
<div class="handle" :drag="box"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Anot from 'lib/drag/index.js'
|
||||||
require(['lib/drag/main'], function(){
|
Anot({
|
||||||
|
$id: 'test'
|
||||||
yua({
|
})
|
||||||
$id: 'test'
|
|
||||||
})
|
|
||||||
yua.scan()
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 额外参数
|
||||||
|
|
||||||
|
### `data-limit`
|
||||||
|
> 用于限制元素的拖动范围,默认没有限制。 可选值为 "window"和"parent", 分别为 "限制在可视区"和"限制在父级元素的范围"
|
||||||
|
|
||||||
|
### `data-axis`
|
||||||
|
> 用于限制拖动的方向, 默认值为 "xy",即不限制方向。可选值为 "x"和"y", 即只能在"x轴"或"y轴"方向拖动。
|
||||||
|
|
||||||
|
### `data-beforedrag`
|
||||||
|
> 拖动前的回调,如果有设置回调方法, 则该回调的返回值,可决定该元素是否能被拖拽, 可用于在特殊场景下,临时禁用拖拽。
|
||||||
|
> `注:`
|
||||||
|
> 1. 该回调方法,会传入3个参数, 第1个为被拖拽的元素(dom对象), 第2个参数为 该元素的x轴绝对坐标, 第3个元素为y轴绝对坐标;
|
||||||
|
> 2. 该回调方法, 返回false时, 本次拖拽将临时失效, 返回其他值,或没有返回值,则忽略。
|
||||||
|
|
||||||
|
|
||||||
|
### `data-dragging`
|
||||||
|
> 元素被拖动时的回调。
|
||||||
|
> `注:`
|
||||||
|
> 1.该回调方法,会传入3个参数, 第1个为被拖拽的元素(dom对象), 第2个参数为 该元素的x轴绝对坐标, 第3个元素为y轴绝对坐标;
|
||||||
|
|
||||||
|
|
||||||
|
### `data-dragged`
|
||||||
|
> 元素被拖动结束后的回调。
|
||||||
|
> `注:`
|
||||||
|
> 1. 该回调方法,会传入3个参数, 第1个为被拖拽的元素(dom对象), 第2个参数为 该元素的x轴绝对坐标, 第3个元素为y轴绝对坐标;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,14 @@ Anot.directive('drag', {
|
||||||
priority: 1500,
|
priority: 1500,
|
||||||
init: function(binding) {
|
init: function(binding) {
|
||||||
binding.expr = '"' + binding.expr + '"'
|
binding.expr = '"' + binding.expr + '"'
|
||||||
Anot(binding.element).css('cursor', 'move')
|
let ico = document.documentMode ? 'move' : 'grab'
|
||||||
|
|
||||||
|
if (window.sidebar) {
|
||||||
|
ico = '-moz-' + ico
|
||||||
|
} else if (window.chrome) {
|
||||||
|
ico = '-webkit-' + ico
|
||||||
|
}
|
||||||
|
Anot(binding.element).css('cursor', ico)
|
||||||
//取得拖动的3种状态回调
|
//取得拖动的3种状态回调
|
||||||
//按下,且拖拽之前
|
//按下,且拖拽之前
|
||||||
binding.beforedrag = getBindingCallback(
|
binding.beforedrag = getBindingCallback(
|
||||||
|
@ -69,16 +75,19 @@ Anot.directive('drag', {
|
||||||
delete binding.element.dataset.dragged
|
delete binding.element.dataset.dragged
|
||||||
},
|
},
|
||||||
update: function(val) {
|
update: function(val) {
|
||||||
var _this = this,
|
let _this = this
|
||||||
target = val ? this.element.parentNode : this.element,
|
let target = val ? this.element.parentNode : this.element
|
||||||
$drag = Anot(this.element),
|
let $drag = Anot(this.element)
|
||||||
$doc = Anot(document),
|
let $doc = Anot(document)
|
||||||
$target = null,
|
let $target = null
|
||||||
parentElem = null
|
let parentElem = null
|
||||||
|
|
||||||
// val值不为空时, 获取真正的拖动元素
|
// val值不为空时, 获取真正的拖动元素
|
||||||
// 仅从父级上找
|
// 仅从父级上找
|
||||||
while (val && target) {
|
while (val && target) {
|
||||||
|
if (!target.classList) {
|
||||||
|
Anot.error(`${this.name}=${this.expr}, 解析异常[元素不存在]`)
|
||||||
|
}
|
||||||
if (target.classList.contains(val) || target.id === val) {
|
if (target.classList.contains(val) || target.id === val) {
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
|
@ -91,11 +100,17 @@ Anot.directive('drag', {
|
||||||
parentElem = target.parentNode
|
parentElem = target.parentNode
|
||||||
}
|
}
|
||||||
|
|
||||||
var dx, dy, mx, my, ox, oy, fox, foy, tw, th, ww, wh, bst, bsl
|
let dx, dy, mx, my, ox, oy, fox, foy, tw, th, ww, wh, bst, bsl
|
||||||
|
let cssTransition
|
||||||
$drag.bind('mousedown', function(ev) {
|
$drag.bind('mousedown', function(ev) {
|
||||||
var gcs = getComputedStyle(target),
|
let gcs = getComputedStyle(target)
|
||||||
cst = gcs.transform.replace(/matrix\((.*)\)/, '$1'),
|
let cst = gcs.transform.replace(/matrix\((.*)\)/, '$1')
|
||||||
offset = $target.offset()
|
let offset = $target.offset()
|
||||||
|
|
||||||
|
if (gcs.transitionDuration !== '0s') {
|
||||||
|
cssTransition = gcs.transitionDuration
|
||||||
|
target.style.transitionDuration = '0s'
|
||||||
|
}
|
||||||
|
|
||||||
cst = cst !== 'none' ? cst.split(', ') : [1, 0, 0, 1, 0, 0]
|
cst = cst !== 'none' ? cst.split(', ') : [1, 0, 0, 1, 0, 0]
|
||||||
cst[4] -= 0
|
cst[4] -= 0
|
||||||
|
@ -127,24 +142,29 @@ Anot.directive('drag', {
|
||||||
|
|
||||||
//拖拽前回调
|
//拖拽前回调
|
||||||
if (_this.beforedrag) {
|
if (_this.beforedrag) {
|
||||||
var result = _this.beforedrag.call(_this.vmodels, target, ox, oy)
|
let result = _this.beforedrag.call(
|
||||||
|
_this.vmodels,
|
||||||
|
target,
|
||||||
|
ox + dx,
|
||||||
|
oy + dy
|
||||||
|
)
|
||||||
if (result === false) {
|
if (result === false) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//限制区域, 4个值依次是: 上, 下, 左, 右
|
//限制区域, 4个值依次是: 上, 下, 左, 右
|
||||||
var limit = [0, wh - th, 0, ww - tw]
|
let limit = [0, wh - th, 0, ww - tw]
|
||||||
|
|
||||||
if (_this.limit === 'parent') {
|
if (_this.limit === 'parent') {
|
||||||
var pgcs = getComputedStyle(parentElem),
|
let pgcs = getComputedStyle(parentElem)
|
||||||
pcst = pgcs.transform.replace(/matrix\((.*)\)/, '$1'),
|
let pcst = pgcs.transform.replace(/matrix\((.*)\)/, '$1')
|
||||||
poffset = Anot(parentElem).offset()
|
let poffset = Anot(parentElem).offset()
|
||||||
|
|
||||||
pcst = pcst !== 'none' ? pcst.split(', ') : [1, 0, 0, 1, 0, 0]
|
pcst = pcst !== 'none' ? pcst.split(', ') : [1, 0, 0, 1, 0, 0]
|
||||||
|
|
||||||
var pox = poffset.left - pcst[4] - bsl,
|
let pox = poffset.left - pcst[4] - bsl
|
||||||
poy = poffset.top - pcst[5] - bst
|
let poy = poffset.top - pcst[5] - bst
|
||||||
|
|
||||||
limit = [
|
limit = [
|
||||||
poy,
|
poy,
|
||||||
|
@ -154,66 +174,69 @@ Anot.directive('drag', {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
var mvfn = $doc.bind('mousemove', function(ev) {
|
let mvfn = $doc.bind('mousemove', function(ev) {
|
||||||
//坐标轴限制
|
// 防止拖动到边缘时导致页面滚动
|
||||||
|
ev.preventDefault()
|
||||||
|
|
||||||
|
//坐标轴限制
|
||||||
|
if (_this.axis !== 'y') {
|
||||||
|
cst[4] = ev.pageX - mx + dx
|
||||||
|
}
|
||||||
|
if (_this.axis !== 'x') {
|
||||||
|
cst[5] = ev.pageY - my + dy
|
||||||
|
}
|
||||||
|
|
||||||
|
fox = ox + cst[4] //修正的offset
|
||||||
|
foy = oy + cst[5] //修正的offset
|
||||||
|
|
||||||
|
//如果不允许溢出可视区
|
||||||
|
if (!_this.overflow) {
|
||||||
if (_this.axis !== 'y') {
|
if (_this.axis !== 'y') {
|
||||||
cst[4] = ev.pageX - mx + dx
|
if (fox <= limit[2]) {
|
||||||
|
fox = limit[2]
|
||||||
|
//修正矩阵
|
||||||
|
cst[4] = fox - ox
|
||||||
|
}
|
||||||
|
if (fox >= limit[3]) {
|
||||||
|
fox = limit[3]
|
||||||
|
//修正矩阵
|
||||||
|
cst[4] = fox - ox
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_this.axis !== 'x') {
|
if (_this.axis !== 'x') {
|
||||||
cst[5] = ev.pageY - my + dy
|
if (foy <= limit[0]) {
|
||||||
}
|
foy = limit[0]
|
||||||
|
//修正矩阵
|
||||||
;(fox = ox + cst[4]), //修正的offset
|
cst[5] = foy - oy
|
||||||
(foy = oy + cst[5]) //修正的offset
|
|
||||||
|
|
||||||
//如果不允许溢出可视区
|
|
||||||
if (!_this.overflow) {
|
|
||||||
if (_this.axis !== 'y') {
|
|
||||||
if (fox <= limit[2]) {
|
|
||||||
fox = limit[2]
|
|
||||||
//修正矩阵
|
|
||||||
cst[4] = fox - ox
|
|
||||||
}
|
|
||||||
if (fox >= limit[3]) {
|
|
||||||
fox = limit[3]
|
|
||||||
//修正矩阵
|
|
||||||
cst[4] = fox - ox
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (foy >= limit[1]) {
|
||||||
if (_this.axis !== 'x') {
|
foy = limit[1]
|
||||||
if (foy <= limit[0]) {
|
//修正矩阵
|
||||||
foy = limit[0]
|
cst[5] = foy - oy
|
||||||
//修正矩阵
|
|
||||||
cst[5] = foy - oy
|
|
||||||
}
|
|
||||||
if (foy >= limit[1]) {
|
|
||||||
foy = limit[1]
|
|
||||||
//修正矩阵
|
|
||||||
cst[5] = foy - oy
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$target.css({
|
$target.css({
|
||||||
transform: 'matrix(' + cst.join(', ') + ')'
|
transform: 'matrix(' + cst.join(', ') + ')'
|
||||||
})
|
|
||||||
|
|
||||||
//拖拽过程的回调
|
|
||||||
if (_this.dragging) {
|
|
||||||
_this.dragging.call(_this.vmodels, target, fox, foy)
|
|
||||||
}
|
|
||||||
// 防止拖动到边缘时导致页面滚动
|
|
||||||
ev.preventDefault()
|
|
||||||
}),
|
|
||||||
upfn = $doc.bind('mouseup', function(ev) {
|
|
||||||
$doc.unbind('mousemove', mvfn)
|
|
||||||
$doc.unbind('mouseup', upfn)
|
|
||||||
//结束回调
|
|
||||||
if (_this.dragged) {
|
|
||||||
_this.dragged.call(_this.vmodels, target, fox, foy)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//拖拽过程的回调
|
||||||
|
if (_this.dragging) {
|
||||||
|
_this.dragging.call(_this.vmodels, target, fox, foy)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let upfn = $doc.bind('mouseup', function(ev) {
|
||||||
|
$doc.unbind('mousemove', mvfn)
|
||||||
|
$doc.unbind('mouseup', upfn)
|
||||||
|
|
||||||
|
target.style.transitionDuration = cssTransition
|
||||||
|
//结束回调
|
||||||
|
if (_this.dragged) {
|
||||||
|
_this.dragged.call(_this.vmodels, target, fox, foy)
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Reference in New Issue