This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0

对drag插件的优化

old
宇天 2018-05-05 18:36:45 +08:00
parent a2d9603eaa
commit 64799069d3
2 changed files with 137 additions and 114 deletions

View File

@ -3,7 +3,7 @@
> 使用时,在目标元素上添加`:drag`属性即可以实现拖拽功能。 > 使用时,在目标元素上添加`:drag`属性即可以实现拖拽功能。
## 依赖 ## 依赖
> 依赖`yua`框架 > 依赖`Anot`框架
## 浏览器兼容性 ## 浏览器兼容性
+ chrome + chrome
@ -18,38 +18,6 @@
> 具体请看示例: > 具体请看示例:
> **注意:** `拖拽的元素不是本身时,只会往父级一级一级找相匹配的` > **注意:** `拖拽的元素不是本身时,只会往父级一级一级找相匹配的`
```html
<!DOCTYPE html>
<html>
<head>
<style>
* {margin:0;padding:0}
.box {width:100px;height:100px;background:#f30;}
</style>
</head>
<body :controller="test">
<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 ```html
<!DOCTYPE html> <!DOCTYPE html>
@ -63,23 +31,55 @@
</head> </head>
<body :controller="test"> <body :controller="test">
<div class="box" :drag></div>
<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({
yua({
$id: 'test' $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轴绝对坐标;

View File

@ -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,7 +174,10 @@ Anot.directive('drag', {
] ]
} }
var mvfn = $doc.bind('mousemove', function(ev) { let mvfn = $doc.bind('mousemove', function(ev) {
// 防止拖动到边缘时导致页面滚动
ev.preventDefault()
//坐标轴限制 //坐标轴限制
if (_this.axis !== 'y') { if (_this.axis !== 'y') {
cst[4] = ev.pageX - mx + dx cst[4] = ev.pageX - mx + dx
@ -163,8 +186,8 @@ Anot.directive('drag', {
cst[5] = ev.pageY - my + dy cst[5] = ev.pageY - my + dy
} }
;(fox = ox + cst[4]), //修正的offset fox = ox + cst[4] //修正的offset
(foy = oy + cst[5]) //修正的offset foy = oy + cst[5] //修正的offset
//如果不允许溢出可视区 //如果不允许溢出可视区
if (!_this.overflow) { if (!_this.overflow) {
@ -203,12 +226,12 @@ Anot.directive('drag', {
if (_this.dragging) { if (_this.dragging) {
_this.dragging.call(_this.vmodels, target, fox, foy) _this.dragging.call(_this.vmodels, target, fox, foy)
} }
// 防止拖动到边缘时导致页面滚动 })
ev.preventDefault() let upfn = $doc.bind('mouseup', function(ev) {
}),
upfn = $doc.bind('mouseup', function(ev) {
$doc.unbind('mousemove', mvfn) $doc.unbind('mousemove', mvfn)
$doc.unbind('mouseup', upfn) $doc.unbind('mouseup', upfn)
target.style.transitionDuration = cssTransition
//结束回调 //结束回调
if (_this.dragged) { if (_this.dragged) {
_this.dragged.call(_this.vmodels, target, fox, foy) _this.dragged.call(_this.vmodels, target, fox, foy)