Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
touchx
uni-app
提交
440a131c
U
uni-app
项目概览
touchx
/
uni-app
与 Fork 源项目一致
Fork自
DCloud / uni-app
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-app
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
440a131c
编写于
11月 20, 2019
作者:
M
mehaotian
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: 解决 scroll-view movable-area movable-view picker-view-column 垂直滑动与下拉刷新冲突的问题
上级
7f25b749
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
560 addition
and
491 deletion
+560
-491
src/core/view/components/movable-area/index.vue
src/core/view/components/movable-area/index.vue
+178
-167
src/core/view/components/movable-view/index.vue
src/core/view/components/movable-view/index.vue
+9
-1
src/core/view/components/picker-view-column/index.vue
src/core/view/components/picker-view-column/index.vue
+332
-320
src/core/view/components/scroll-view/index.vue
src/core/view/components/scroll-view/index.vue
+14
-3
src/shared/index.js
src/shared/index.js
+1
-0
src/shared/scroll.js
src/shared/scroll.js
+26
-0
未找到文件。
src/core/view/components/movable-area/index.vue
浏览文件 @
440a131c
<
script
>
function
calc
(
e
)
{
return
Math
.
sqrt
(
e
.
x
*
e
.
x
+
e
.
y
*
e
.
y
)
}
export
default
{
name
:
'
MovableArea
'
,
props
:
{
scaleArea
:
{
type
:
Boolean
,
default
:
false
}
},
data
()
{
return
{
width
:
0
,
height
:
0
,
items
:
[]
}
},
created
:
function
()
{
this
.
gapV
=
{
x
:
null
,
y
:
null
}
this
.
pinchStartLen
=
null
},
mounted
:
function
()
{
this
.
_resize
()
},
methods
:
{
_resize
()
{
this
.
_getWH
()
this
.
items
.
forEach
(
function
(
item
,
index
)
{
item
.
componentInstance
.
setParent
()
})
},
_find
(
target
,
items
=
this
.
items
)
{
var
root
=
this
.
$el
function
get
(
node
)
{
for
(
let
i
=
0
;
i
<
items
.
length
;
i
++
)
{
const
item
=
items
[
i
]
if
(
node
===
item
.
componentInstance
.
$el
)
{
return
item
}
}
if
(
node
===
root
||
node
===
document
.
body
||
node
===
document
)
{
return
null
}
return
get
(
node
.
parentNode
)
}
return
get
(
target
)
},
<
script
>
import
{
disableScrollBounce
}
from
'
uni-shared
'
function
calc
(
e
)
{
return
Math
.
sqrt
(
e
.
x
*
e
.
x
+
e
.
y
*
e
.
y
)
}
export
default
{
name
:
'
MovableArea
'
,
props
:
{
scaleArea
:
{
type
:
Boolean
,
default
:
false
}
},
data
()
{
return
{
width
:
0
,
height
:
0
,
items
:
[]
}
},
created
:
function
()
{
this
.
gapV
=
{
x
:
null
,
y
:
null
}
this
.
pinchStartLen
=
null
},
mounted
:
function
()
{
this
.
_resize
()
},
methods
:
{
_resize
()
{
this
.
_getWH
()
this
.
items
.
forEach
(
function
(
item
,
index
)
{
item
.
componentInstance
.
setParent
()
})
},
_find
(
target
,
items
=
this
.
items
)
{
var
root
=
this
.
$el
function
get
(
node
)
{
for
(
let
i
=
0
;
i
<
items
.
length
;
i
++
)
{
const
item
=
items
[
i
]
if
(
node
===
item
.
componentInstance
.
$el
)
{
return
item
}
}
if
(
node
===
root
||
node
===
document
.
body
||
node
===
document
)
{
return
null
}
return
get
(
node
.
parentNode
)
}
return
get
(
target
)
},
_touchstart
(
t
)
{
var
i
=
t
.
touches
if
(
i
)
{
if
(
i
.
length
>
1
)
{
var
r
=
{
x
:
i
[
1
].
pageX
-
i
[
0
].
pageX
,
y
:
i
[
1
].
pageY
-
i
[
0
].
pageY
}
this
.
pinchStartLen
=
calc
(
r
)
this
.
gapV
=
r
if
(
!
this
.
scaleArea
)
{
var
touch0
=
this
.
_find
(
i
[
0
].
target
)
var
touch1
=
this
.
_find
(
i
[
1
].
target
)
this
.
_scaleMovableView
=
touch0
&&
touch0
===
touch1
?
touch0
:
null
}
}
}
},
_touchmove
(
t
)
{
var
n
=
t
.
touches
if
(
n
)
{
if
(
n
.
length
>
1
)
{
t
.
preventDefault
()
var
i
=
{
x
:
n
[
1
].
pageX
-
n
[
0
].
pageX
,
y
:
n
[
1
].
pageY
-
n
[
0
].
pageY
}
if
(
this
.
gapV
.
x
!==
null
&&
this
.
pinchStartLen
>
0
)
{
var
r
=
calc
(
i
)
/
this
.
pinchStartLen
this
.
_updateScale
(
r
)
}
this
.
gapV
=
i
}
}
},
disableScrollBounce
({
disable
:
true
})
var
i
=
t
.
touches
if
(
i
)
{
if
(
i
.
length
>
1
)
{
var
r
=
{
x
:
i
[
1
].
pageX
-
i
[
0
].
pageX
,
y
:
i
[
1
].
pageY
-
i
[
0
].
pageY
}
this
.
pinchStartLen
=
calc
(
r
)
this
.
gapV
=
r
if
(
!
this
.
scaleArea
)
{
var
touch0
=
this
.
_find
(
i
[
0
].
target
)
var
touch1
=
this
.
_find
(
i
[
1
].
target
)
this
.
_scaleMovableView
=
touch0
&&
touch0
===
touch1
?
touch0
:
null
}
}
}
},
_touchmove
(
t
)
{
var
n
=
t
.
touches
if
(
n
)
{
if
(
n
.
length
>
1
)
{
t
.
preventDefault
()
var
i
=
{
x
:
n
[
1
].
pageX
-
n
[
0
].
pageX
,
y
:
n
[
1
].
pageY
-
n
[
0
].
pageY
}
if
(
this
.
gapV
.
x
!==
null
&&
this
.
pinchStartLen
>
0
)
{
var
r
=
calc
(
i
)
/
this
.
pinchStartLen
this
.
_updateScale
(
r
)
}
this
.
gapV
=
i
}
}
},
_touchend
(
e
)
{
var
t
=
e
.
touches
if
(
!
(
t
&&
t
.
length
))
{
if
(
e
.
changedTouches
)
{
this
.
gapV
.
x
=
0
this
.
gapV
.
y
=
0
this
.
pinchStartLen
=
null
if
(
this
.
scaleArea
)
{
this
.
items
.
forEach
(
function
(
item
)
{
item
.
componentInstance
.
_endScale
()
})
}
else
{
if
(
this
.
_scaleMovableView
)
{
this
.
_scaleMovableView
.
componentInstance
.
_endScale
()
}
}
}
}
},
_updateScale
(
e
)
{
if
(
e
&&
e
!==
1
)
{
if
(
this
.
scaleArea
)
{
this
.
items
.
forEach
(
function
(
item
)
{
item
.
componentInstance
.
_setScale
(
e
)
})
}
else
{
if
(
this
.
_scaleMovableView
)
{
this
.
_scaleMovableView
.
componentInstance
.
_setScale
(
e
)
}
}
}
},
_getWH
()
{
var
style
=
window
.
getComputedStyle
(
this
.
$el
)
var
rect
=
this
.
$el
.
getBoundingClientRect
()
this
.
width
=
rect
.
width
-
[
'
Left
'
,
'
Right
'
].
reduce
(
function
(
all
,
item
)
{
return
all
+
parseFloat
(
style
[
'
border
'
+
item
+
'
Width
'
])
+
parseFloat
(
style
[
'
padding
'
+
item
])
},
0
)
this
.
height
=
rect
.
height
-
[
'
Top
'
,
'
Bottom
'
].
reduce
(
function
(
all
,
item
)
{
return
all
+
parseFloat
(
style
[
'
border
'
+
item
+
'
Width
'
])
+
parseFloat
(
style
[
'
padding
'
+
item
])
},
0
)
}
},
render
(
createElement
)
{
var
items
=
[]
if
(
this
.
$slots
.
default
)
{
this
.
$slots
.
default
.
forEach
(
vnode
=>
{
if
(
vnode
.
componentOptions
&&
vnode
.
componentOptions
.
tag
===
'
v-uni-movable-view
'
)
{
items
.
push
(
vnode
)
}
})
}
this
.
items
=
items
var
$listeners
=
Object
.
assign
({},
this
.
$listeners
)
var
events
=
[
'
touchstart
'
,
'
touchmove
'
,
'
touchend
'
]
events
.
forEach
(
event
=>
{
var
existing
=
$listeners
[
event
]
var
ours
=
this
[
`_
${
event
}
`
]
$listeners
[
event
]
=
existing
?
[].
concat
(
existing
,
ours
)
:
ours
})
return
createElement
(
'
uni-movable-area
'
,
{
on
:
$listeners
},
[
createElement
(
'
v-uni-resize-sensor
'
,
{
on
:
{
resize
:
this
.
_resize
}
}),
...
items
])
}
}
</
script
>
<
style
>
uni-movable-area
{
display
:
block
;
position
:
relative
;
width
:
10px
;
height
:
10px
;
}
uni-movable-area
[
hidden
]
{
display
:
none
;
}
disableScrollBounce
({
disable
:
false
})
var
t
=
e
.
touches
if
(
!
(
t
&&
t
.
length
))
{
if
(
e
.
changedTouches
)
{
this
.
gapV
.
x
=
0
this
.
gapV
.
y
=
0
this
.
pinchStartLen
=
null
if
(
this
.
scaleArea
)
{
this
.
items
.
forEach
(
function
(
item
)
{
item
.
componentInstance
.
_endScale
()
})
}
else
{
if
(
this
.
_scaleMovableView
)
{
this
.
_scaleMovableView
.
componentInstance
.
_endScale
()
}
}
}
}
},
_updateScale
(
e
)
{
if
(
e
&&
e
!==
1
)
{
if
(
this
.
scaleArea
)
{
this
.
items
.
forEach
(
function
(
item
)
{
item
.
componentInstance
.
_setScale
(
e
)
})
}
else
{
if
(
this
.
_scaleMovableView
)
{
this
.
_scaleMovableView
.
componentInstance
.
_setScale
(
e
)
}
}
}
},
_getWH
()
{
var
style
=
window
.
getComputedStyle
(
this
.
$el
)
var
rect
=
this
.
$el
.
getBoundingClientRect
()
this
.
width
=
rect
.
width
-
[
'
Left
'
,
'
Right
'
].
reduce
(
function
(
all
,
item
)
{
return
all
+
parseFloat
(
style
[
'
border
'
+
item
+
'
Width
'
])
+
parseFloat
(
style
[
'
padding
'
+
item
])
},
0
)
this
.
height
=
rect
.
height
-
[
'
Top
'
,
'
Bottom
'
].
reduce
(
function
(
all
,
item
)
{
return
all
+
parseFloat
(
style
[
'
border
'
+
item
+
'
Width
'
])
+
parseFloat
(
style
[
'
padding
'
+
item
])
},
0
)
}
},
render
(
createElement
)
{
var
items
=
[]
if
(
this
.
$slots
.
default
)
{
this
.
$slots
.
default
.
forEach
(
vnode
=>
{
if
(
vnode
.
componentOptions
&&
vnode
.
componentOptions
.
tag
===
'
v-uni-movable-view
'
)
{
items
.
push
(
vnode
)
}
})
}
this
.
items
=
items
var
$listeners
=
Object
.
assign
({},
this
.
$listeners
)
var
events
=
[
'
touchstart
'
,
'
touchmove
'
,
'
touchend
'
]
events
.
forEach
(
event
=>
{
var
existing
=
$listeners
[
event
]
var
ours
=
this
[
`_
${
event
}
`
]
$listeners
[
event
]
=
existing
?
[].
concat
(
existing
,
ours
)
:
ours
})
return
createElement
(
'
uni-movable-area
'
,
{
on
:
$listeners
},
[
createElement
(
'
v-uni-resize-sensor
'
,
{
on
:
{
resize
:
this
.
_resize
}
}),
...
items
])
}
}
</
script
>
<
style
>
uni-movable-area
{
display
:
block
;
position
:
relative
;
width
:
10px
;
height
:
10px
;
}
uni-movable-area
[
hidden
]
{
display
:
none
;
}
</
style
>
src/core/view/components/movable-view/index.vue
浏览文件 @
440a131c
...
...
@@ -11,7 +11,9 @@ import {
Friction
,
STD
}
from
'
./utils
'
import
{
disableScrollBounce
}
from
'
uni-shared
'
var
requesting
=
false
function
_requestAnimationFrame
(
e
)
{
...
...
@@ -278,6 +280,9 @@ export default {
__handleTouchStart
:
function
()
{
if
(
!
this
.
_isScaling
)
{
if
(
!
this
.
disabled
)
{
disableScrollBounce
({
disable
:
true
})
if
(
this
.
_FA
)
{
this
.
_FA
.
cancel
()
}
...
...
@@ -383,6 +388,9 @@ export default {
__handleTouchEnd
:
function
()
{
var
self
=
this
if
(
!
this
.
_isScaling
&&
!
this
.
disabled
&&
this
.
_isTouching
)
{
disableScrollBounce
({
disable
:
true
})
this
.
$el
.
style
.
willChange
=
'
auto
'
this
.
_isTouching
=
false
if
(
!
this
.
_checkCanMove
&&
!
this
.
_revise
(
'
out-of-bounds
'
)
&&
this
.
inertia
)
{
...
...
src/core/view/components/picker-view-column/index.vue
浏览文件 @
440a131c
<
script
>
import
touchtrack
from
'
uni-mixins/touchtrack
'
import
scroller
from
'
uni-mixins/scroller/index
'
import
{
Friction
}
from
'
uni-mixins/scroller/Friction
'
import
{
Spring
}
from
'
uni-mixins/scroller/Spring
'
function
onClick
(
dom
,
callback
)
{
const
MAX_MOVE
=
20
const
hasTouchSupport
=
navigator
.
maxTouchPoints
let
x
=
0
let
y
=
0
dom
.
addEventListener
(
hasTouchSupport
?
'
touchstart
'
:
'
mousedown
'
,
(
event
)
=>
{
const
info
=
hasTouchSupport
?
event
.
changedTouches
[
0
]
:
event
x
=
info
.
clientX
y
=
info
.
clientY
})
dom
.
addEventListener
(
hasTouchSupport
?
'
touchend
'
:
'
mouseup
'
,
(
event
)
=>
{
const
info
=
hasTouchSupport
?
event
.
changedTouches
[
0
]
:
event
if
(
Math
.
abs
(
info
.
clientX
-
x
)
<
MAX_MOVE
&&
Math
.
abs
(
info
.
clientY
-
y
)
<
MAX_MOVE
)
{
callback
(
info
)
}
})
}
export
default
{
name
:
'
PickerViewColumn
'
,
mixins
:
[
touchtrack
,
scroller
],
data
()
{
return
{
scope
:
`picker-view-column-
${
Date
.
now
()}
`
,
inited
:
false
,
indicatorStyle
:
''
,
indicatorClass
:
''
,
indicatorHeight
:
34
,
maskStyle
:
''
,
maskClass
:
''
,
current
:
this
.
$parent
.
getItemValue
(
this
),
length
:
0
}
},
computed
:
{
height
()
{
return
this
.
$parent
.
height
},
maskSize
()
{
return
(
this
.
height
-
this
.
indicatorHeight
)
/
2
}
},
watch
:
{
indicatorHeight
(
val
)
{
this
.
_setItemHeight
(
val
)
if
(
this
.
inited
)
{
this
.
update
()
}
},
current
(
val
)
{
this
.
$parent
.
setItemValue
(
this
,
val
)
},
length
(
val
)
{
if
(
this
.
inited
)
{
this
.
update
(
val
)
}
}
},
created
:
function
()
{
var
$parent
=
this
.
$parent
this
.
indicatorStyle
=
$parent
.
indicatorStyle
this
.
indicatorClass
=
$parent
.
indicatorClass
this
.
maskStyle
=
$parent
.
maskStyle
this
.
maskClass
=
$parent
.
maskClass
this
.
deltaY
=
0
},
mounted
:
function
()
{
this
.
touchtrack
(
this
.
$refs
.
main
,
'
_handleTrack
'
,
true
)
this
.
setCurrent
(
this
.
current
)
this
.
$nextTick
(()
=>
{
this
.
init
()
this
.
update
()
})
onClick
(
this
.
$el
,
this
.
_handleTap
.
bind
(
this
))
},
methods
:
{
_setItemHeight
(
height
)
{
var
style
=
document
.
createElement
(
'
style
'
)
style
.
innerText
=
`.uni-picker-view-content.
${
this
.
scope
}
>*{height:
${
height
}
px;overflow: hidden;}`
document
.
head
.
appendChild
(
style
)
},
_handleTrack
:
function
(
e
)
{
if
(
this
.
_scroller
)
{
switch
(
e
.
detail
.
state
)
{
case
'
start
'
:
<
script
>
import
touchtrack
from
'
uni-mixins/touchtrack
'
import
scroller
from
'
uni-mixins/scroller/index
'
import
{
Friction
}
from
'
uni-mixins/scroller/Friction
'
import
{
Spring
}
from
'
uni-mixins/scroller/Spring
'
import
{
disableScrollBounce
}
from
'
uni-shared
'
function
onClick
(
dom
,
callback
)
{
const
MAX_MOVE
=
20
const
hasTouchSupport
=
navigator
.
maxTouchPoints
let
x
=
0
let
y
=
0
dom
.
addEventListener
(
hasTouchSupport
?
'
touchstart
'
:
'
mousedown
'
,
(
event
)
=>
{
const
info
=
hasTouchSupport
?
event
.
changedTouches
[
0
]
:
event
x
=
info
.
clientX
y
=
info
.
clientY
})
dom
.
addEventListener
(
hasTouchSupport
?
'
touchend
'
:
'
mouseup
'
,
(
event
)
=>
{
const
info
=
hasTouchSupport
?
event
.
changedTouches
[
0
]
:
event
if
(
Math
.
abs
(
info
.
clientX
-
x
)
<
MAX_MOVE
&&
Math
.
abs
(
info
.
clientY
-
y
)
<
MAX_MOVE
)
{
callback
(
info
)
}
})
}
export
default
{
name
:
'
PickerViewColumn
'
,
mixins
:
[
touchtrack
,
scroller
],
data
()
{
return
{
scope
:
`picker-view-column-
${
Date
.
now
()}
`
,
inited
:
false
,
indicatorStyle
:
''
,
indicatorClass
:
''
,
indicatorHeight
:
34
,
maskStyle
:
''
,
maskClass
:
''
,
current
:
this
.
$parent
.
getItemValue
(
this
),
length
:
0
}
},
computed
:
{
height
()
{
return
this
.
$parent
.
height
},
maskSize
()
{
return
(
this
.
height
-
this
.
indicatorHeight
)
/
2
}
},
watch
:
{
indicatorHeight
(
val
)
{
this
.
_setItemHeight
(
val
)
if
(
this
.
inited
)
{
this
.
update
()
}
},
current
(
val
)
{
this
.
$parent
.
setItemValue
(
this
,
val
)
},
length
(
val
)
{
if
(
this
.
inited
)
{
this
.
update
(
val
)
}
}
},
created
:
function
()
{
var
$parent
=
this
.
$parent
this
.
indicatorStyle
=
$parent
.
indicatorStyle
this
.
indicatorClass
=
$parent
.
indicatorClass
this
.
maskStyle
=
$parent
.
maskStyle
this
.
maskClass
=
$parent
.
maskClass
this
.
deltaY
=
0
},
mounted
:
function
()
{
this
.
touchtrack
(
this
.
$refs
.
main
,
'
_handleTrack
'
,
true
)
this
.
setCurrent
(
this
.
current
)
this
.
$nextTick
(()
=>
{
this
.
init
()
this
.
update
()
})
onClick
(
this
.
$el
,
this
.
_handleTap
.
bind
(
this
))
},
methods
:
{
_setItemHeight
(
height
)
{
var
style
=
document
.
createElement
(
'
style
'
)
style
.
innerText
=
`.uni-picker-view-content.
${
this
.
scope
}
>*{height:
${
height
}
px;overflow: hidden;}`
document
.
head
.
appendChild
(
style
)
},
_handleTrack
:
function
(
e
)
{
if
(
this
.
_scroller
)
{
switch
(
e
.
detail
.
state
)
{
case
'
start
'
:
this
.
_handleTouchStart
(
e
)
break
case
'
move
'
:
this
.
_handleTouchMove
(
e
)
break
case
'
end
'
:
case
'
cancel
'
:
disableScrollBounce
({
disable
:
true
})
break
case
'
move
'
:
this
.
_handleTouchMove
(
e
)
break
case
'
end
'
:
case
'
cancel
'
:
this
.
_handleTouchEnd
(
e
)
}
}
},
_handleTap
:
function
({
clientY
})
{
if
(
!
this
.
_scroller
.
isScrolling
())
{
var
rect
=
this
.
$el
.
getBoundingClientRect
()
var
r
=
clientY
-
rect
.
top
-
this
.
height
/
2
var
o
=
this
.
indicatorHeight
/
2
if
(
!
(
Math
.
abs
(
r
)
<=
o
))
{
var
a
=
Math
.
ceil
((
Math
.
abs
(
r
)
-
o
)
/
this
.
indicatorHeight
)
var
s
=
r
<
0
?
-
a
:
a
var
current
=
Math
.
min
(
this
.
current
+
s
,
this
.
length
-
1
)
this
.
current
=
current
=
Math
.
max
(
current
,
0
)
this
.
_scroller
.
scrollTo
(
current
*
this
.
indicatorHeight
)
}
}
},
_handleWheel
(
$event
)
{
const
deltaY
=
this
.
deltaY
+
$event
.
deltaY
if
(
Math
.
abs
(
deltaY
)
>
10
)
{
this
.
deltaY
=
0
var
current
=
Math
.
min
(
this
.
current
+
(
deltaY
<
0
?
-
1
:
1
),
this
.
length
-
1
)
this
.
current
=
current
=
Math
.
max
(
current
,
0
)
this
.
_scroller
.
scrollTo
(
current
*
this
.
indicatorHeight
)
}
else
{
this
.
deltaY
=
deltaY
}
$event
.
preventDefault
()
},
setCurrent
:
function
(
current
)
{
if
(
current
!==
this
.
current
)
{
this
.
current
=
current
if
(
this
.
inited
)
{
this
.
update
()
}
}
},
init
:
function
()
{
this
.
initScroller
(
this
.
$refs
.
content
,
{
enableY
:
true
,
enableX
:
false
,
enableSnap
:
true
,
itemSize
:
this
.
indicatorHeight
,
friction
:
new
Friction
(
0.0001
),
spring
:
new
Spring
(
2
,
90
,
20
),
onSnap
:
(
index
)
=>
{
if
((
!
isNaN
(
index
))
&&
index
!==
this
.
current
)
{
this
.
current
=
index
}
}
})
this
.
inited
=
true
},
update
:
function
()
{
this
.
$nextTick
(()
=>
{
var
current
=
Math
.
min
(
this
.
current
,
this
.
length
-
1
)
current
=
Math
.
max
(
current
,
0
)
this
.
_scroller
.
update
(
current
*
this
.
indicatorHeight
,
undefined
,
this
.
indicatorHeight
)
})
},
_resize
({
height
})
{
this
.
indicatorHeight
=
height
}
},
render
(
createElement
)
{
this
.
length
=
(
this
.
$slots
.
default
&&
this
.
$slots
.
default
.
length
)
||
0
return
createElement
(
'
uni-picker-view-column
'
,
{
on
:
{
wheel
:
this
.
_handleWheel
}
},
[
createElement
(
'
div
'
,
{
ref
:
'
main
'
,
staticClass
:
'
uni-picker-view-group
'
},
[
createElement
(
'
div
'
,
{
ref
:
'
mask
'
,
staticClass
:
'
uni-picker-view-mask
'
,
class
:
this
.
maskClass
,
style
:
`background-size: 100%
${
this
.
maskSize
}
px;
${
this
.
maskStyle
}
`
}),
createElement
(
'
div
'
,
{
ref
:
'
indicator
'
,
staticClass
:
'
uni-picker-view-indicator
'
,
class
:
this
.
indicatorClass
,
style
:
this
.
indicatorStyle
},
[
createElement
(
'
v-uni-resize-sensor
'
,
{
attrs
:
{
initial
:
true
},
on
:
{
resize
:
this
.
_resize
}
})]),
createElement
(
'
div
'
,
{
ref
:
'
content
'
,
staticClass
:
'
uni-picker-view-content
'
,
class
:
this
.
scope
,
style
:
`padding:
${
this
.
maskSize
}
px 0;`
},
[
this
.
$slots
.
default
]
)
])
]
)
}
}
</
script
>
<
style
>
uni-picker-view-column
{
-webkit-flex
:
1
;
flex
:
1
;
position
:
relative
;
height
:
100%
;
overflow
:
hidden
;
}
uni-picker-view-column
[
hidden
]
{
display
:
none
;
}
.uni-picker-view-group
{
height
:
100%
;
}
.uni-picker-view-mask
{
transform
:
translateZ
(
0
);
-webkit-transform
:
translateZ
(
0
);
}
.uni-picker-view-indicator
,
.uni-picker-view-mask
{
position
:
absolute
;
left
:
0
;
width
:
100%
;
z-index
:
3
;
}
.uni-picker-view-mask
{
top
:
0
;
height
:
100%
;
margin
:
0
auto
;
background
:
linear-gradient
(
180deg
,
hsla
(
0
,
0%
,
100%
,
0.95
),
hsla
(
0
,
0%
,
100%
,
0.6
)
),
linear-gradient
(
0deg
,
hsla
(
0
,
0%
,
100%
,
0.95
),
hsla
(
0
,
0%
,
100%
,
0.6
));
background-position
:
top
,
bottom
;
background-size
:
100%
102px
;
background-repeat
:
no-repeat
;
}
.uni-picker-view-indicator
{
height
:
34px
;
/* top: 102px; */
top
:
50%
;
transform
:
translateY
(
-50%
);
}
.uni-picker-view-indicator
,
.uni-picker-view-mask
{
position
:
absolute
;
left
:
0
;
width
:
100%
;
z-index
:
3
;
pointer-events
:
none
;
}
.uni-picker-view-content
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
will-change
:
transform
;
padding
:
102px
0
;
}
.uni-picker-view-content
>
*
{
height
:
34px
;
overflow
:
hidden
;
}
.uni-picker-view-indicator
:after
,
.uni-picker-view-indicator
:before
{
content
:
" "
;
position
:
absolute
;
left
:
0
;
right
:
0
;
height
:
1px
;
color
:
#e5e5e5
;
}
.uni-picker-view-indicator
:before
{
top
:
0
;
border-top
:
1px
solid
#e5e5e5
;
-webkit-transform-origin
:
0
0
;
transform-origin
:
0
0
;
-webkit-transform
:
scaleY
(
0.5
);
transform
:
scaleY
(
0.5
);
}
.uni-picker-view-indicator
:after
{
bottom
:
0
;
border-bottom
:
1px
solid
#e5e5e5
;
-webkit-transform-origin
:
0
100%
;
transform-origin
:
0
100%
;
-webkit-transform
:
scaleY
(
0.5
);
transform
:
scaleY
(
0.5
);
}
.uni-picker-view-indicator
:after
,
.uni-picker-view-indicator
:before
{
content
:
" "
;
position
:
absolute
;
left
:
0
;
right
:
0
;
height
:
1px
;
color
:
#e5e5e5
;
}
disableScrollBounce
({
disable
:
false
})
}
}
},
_handleTap
:
function
({
clientY
})
{
if
(
!
this
.
_scroller
.
isScrolling
())
{
var
rect
=
this
.
$el
.
getBoundingClientRect
()
var
r
=
clientY
-
rect
.
top
-
this
.
height
/
2
var
o
=
this
.
indicatorHeight
/
2
if
(
!
(
Math
.
abs
(
r
)
<=
o
))
{
var
a
=
Math
.
ceil
((
Math
.
abs
(
r
)
-
o
)
/
this
.
indicatorHeight
)
var
s
=
r
<
0
?
-
a
:
a
var
current
=
Math
.
min
(
this
.
current
+
s
,
this
.
length
-
1
)
this
.
current
=
current
=
Math
.
max
(
current
,
0
)
this
.
_scroller
.
scrollTo
(
current
*
this
.
indicatorHeight
)
}
}
},
_handleWheel
(
$event
)
{
const
deltaY
=
this
.
deltaY
+
$event
.
deltaY
if
(
Math
.
abs
(
deltaY
)
>
10
)
{
this
.
deltaY
=
0
var
current
=
Math
.
min
(
this
.
current
+
(
deltaY
<
0
?
-
1
:
1
),
this
.
length
-
1
)
this
.
current
=
current
=
Math
.
max
(
current
,
0
)
this
.
_scroller
.
scrollTo
(
current
*
this
.
indicatorHeight
)
}
else
{
this
.
deltaY
=
deltaY
}
$event
.
preventDefault
()
},
setCurrent
:
function
(
current
)
{
if
(
current
!==
this
.
current
)
{
this
.
current
=
current
if
(
this
.
inited
)
{
this
.
update
()
}
}
},
init
:
function
()
{
this
.
initScroller
(
this
.
$refs
.
content
,
{
enableY
:
true
,
enableX
:
false
,
enableSnap
:
true
,
itemSize
:
this
.
indicatorHeight
,
friction
:
new
Friction
(
0.0001
),
spring
:
new
Spring
(
2
,
90
,
20
),
onSnap
:
(
index
)
=>
{
if
((
!
isNaN
(
index
))
&&
index
!==
this
.
current
)
{
this
.
current
=
index
}
}
})
this
.
inited
=
true
},
update
:
function
()
{
this
.
$nextTick
(()
=>
{
var
current
=
Math
.
min
(
this
.
current
,
this
.
length
-
1
)
current
=
Math
.
max
(
current
,
0
)
this
.
_scroller
.
update
(
current
*
this
.
indicatorHeight
,
undefined
,
this
.
indicatorHeight
)
})
},
_resize
({
height
})
{
this
.
indicatorHeight
=
height
}
},
render
(
createElement
)
{
this
.
length
=
(
this
.
$slots
.
default
&&
this
.
$slots
.
default
.
length
)
||
0
return
createElement
(
'
uni-picker-view-column
'
,
{
on
:
{
wheel
:
this
.
_handleWheel
}
},
[
createElement
(
'
div
'
,
{
ref
:
'
main
'
,
staticClass
:
'
uni-picker-view-group
'
},
[
createElement
(
'
div
'
,
{
ref
:
'
mask
'
,
staticClass
:
'
uni-picker-view-mask
'
,
class
:
this
.
maskClass
,
style
:
`background-size: 100%
${
this
.
maskSize
}
px;
${
this
.
maskStyle
}
`
}),
createElement
(
'
div
'
,
{
ref
:
'
indicator
'
,
staticClass
:
'
uni-picker-view-indicator
'
,
class
:
this
.
indicatorClass
,
style
:
this
.
indicatorStyle
},
[
createElement
(
'
v-uni-resize-sensor
'
,
{
attrs
:
{
initial
:
true
},
on
:
{
resize
:
this
.
_resize
}
})]),
createElement
(
'
div
'
,
{
ref
:
'
content
'
,
staticClass
:
'
uni-picker-view-content
'
,
class
:
this
.
scope
,
style
:
`padding:
${
this
.
maskSize
}
px 0;`
},
[
this
.
$slots
.
default
]
)
])
])
}
}
</
script
>
<
style
>
uni-picker-view-column
{
-webkit-flex
:
1
;
flex
:
1
;
position
:
relative
;
height
:
100%
;
overflow
:
hidden
;
}
uni-picker-view-column
[
hidden
]
{
display
:
none
;
}
.uni-picker-view-group
{
height
:
100%
;
}
.uni-picker-view-mask
{
transform
:
translateZ
(
0
);
-webkit-transform
:
translateZ
(
0
);
}
.uni-picker-view-indicator
,
.uni-picker-view-mask
{
position
:
absolute
;
left
:
0
;
width
:
100%
;
z-index
:
3
;
}
.uni-picker-view-mask
{
top
:
0
;
height
:
100%
;
margin
:
0
auto
;
background
:
linear-gradient
(
180deg
,
hsla
(
0
,
0%
,
100%
,
0.95
),
hsla
(
0
,
0%
,
100%
,
0.6
)),
linear-gradient
(
0deg
,
hsla
(
0
,
0%
,
100%
,
0.95
),
hsla
(
0
,
0%
,
100%
,
0.6
));
background-position
:
top
,
bottom
;
background-size
:
100%
102px
;
background-repeat
:
no-repeat
;
}
.uni-picker-view-indicator
{
height
:
34px
;
/* top: 102px; */
top
:
50%
;
transform
:
translateY
(
-50%
);
}
.uni-picker-view-indicator
,
.uni-picker-view-mask
{
position
:
absolute
;
left
:
0
;
width
:
100%
;
z-index
:
3
;
pointer-events
:
none
;
}
.uni-picker-view-content
{
position
:
absolute
;
top
:
0
;
left
:
0
;
width
:
100%
;
will-change
:
transform
;
padding
:
102px
0
;
}
.uni-picker-view-content
>*
{
height
:
34px
;
overflow
:
hidden
;
}
.uni-picker-view-indicator
:after
,
.uni-picker-view-indicator
:before
{
content
:
" "
;
position
:
absolute
;
left
:
0
;
right
:
0
;
height
:
1px
;
color
:
#e5e5e5
;
}
.uni-picker-view-indicator
:before
{
top
:
0
;
border-top
:
1px
solid
#e5e5e5
;
-webkit-transform-origin
:
0
0
;
transform-origin
:
0
0
;
-webkit-transform
:
scaleY
(
0.5
);
transform
:
scaleY
(
0.5
);
}
.uni-picker-view-indicator
:after
{
bottom
:
0
;
border-bottom
:
1px
solid
#e5e5e5
;
-webkit-transform-origin
:
0
100%
;
transform-origin
:
0
100%
;
-webkit-transform
:
scaleY
(
0.5
);
transform
:
scaleY
(
0.5
);
}
.uni-picker-view-indicator
:after
,
.uni-picker-view-indicator
:before
{
content
:
" "
;
position
:
absolute
;
left
:
0
;
right
:
0
;
height
:
1px
;
color
:
#e5e5e5
;
}
</
style
>
src/core/view/components/scroll-view/index.vue
浏览文件 @
440a131c
...
...
@@ -17,12 +17,13 @@
<
script
>
import
scroller
from
'
uni-mixins/scroller/index
'
import
{
supportsPassive
supportsPassive
,
disableScrollBounce
}
from
'
uni-shared
'
const
passiveOptions
=
supportsPassive
?
{
passive
:
true
}
:
false
export
default
{
name
:
'
ScrollView
'
,
mixins
:
[
scroller
],
...
...
@@ -151,8 +152,12 @@ export default {
event
.
stopPropagation
()
}
}
this
.
__handleTouchStart
=
function
(
event
)
{
if
(
event
.
touches
.
length
===
1
)
{
disableScrollBounce
({
disable
:
true
})
needStop
=
null
touchStart
=
{
x
:
event
.
touches
[
0
].
pageX
,
...
...
@@ -160,11 +165,17 @@ export default {
}
}
}
this
.
__handleTouchEnd
=
function
(
event
)
{
disableScrollBounce
({
disable
:
false
})
}
this
.
$refs
.
main
.
addEventListener
(
'
touchstart
'
,
this
.
__handleTouchStart
,
passiveOptions
)
this
.
$refs
.
main
.
addEventListener
(
'
touchmove
'
,
this
.
__handleTouchMove
,
passiveOptions
)
this
.
$refs
.
main
.
addEventListener
(
'
scroll
'
,
this
.
__handleScroll
,
supportsPassive
?
{
passive
:
false
}
:
false
)
this
.
$refs
.
main
.
addEventListener
(
'
touchend
'
,
this
.
__handleTouchEnd
,
passiveOptions
)
},
activated
()
{
// 还原 scroll-view 滚动位置
...
...
@@ -177,6 +188,7 @@ export default {
this
.
$refs
.
main
.
removeEventListener
(
'
scroll
'
,
this
.
__handleScroll
,
supportsPassive
?
{
passive
:
false
}
:
false
)
this
.
$refs
.
main
.
removeEventListener
(
'
touchend
'
,
this
.
__handleTouchEnd
,
passiveOptions
)
},
methods
:
{
scrollTo
:
function
(
t
,
n
)
{
...
...
@@ -359,7 +371,6 @@ export default {
main
.
style
.
overflowY
=
this
.
scrollY
?
'
auto
'
:
'
hidden
'
main
.
scrollTop
=
val
}
this
.
$refs
.
content
.
removeEventListener
(
'
transitionend
'
,
this
.
__transitionEnd
)
this
.
$refs
.
content
.
removeEventListener
(
'
webkitTransitionEnd
'
,
this
.
__transitionEnd
)
},
...
...
src/shared/index.js
浏览文件 @
440a131c
...
...
@@ -2,3 +2,4 @@ export * from './env'
export
*
from
'
./util
'
export
*
from
'
./color
'
export
*
from
'
./query
'
export
*
from
'
./scroll
'
src/shared/scroll.js
0 → 100644
浏览文件 @
440a131c
let
view
let
pullToRefreshStyle
let
disabled
export
function
disableScrollBounce
({
disable
})
{
function
exec
()
{
if
(
!
view
)
{
view
=
plus
.
webview
.
currentWebview
()
}
if
(
!
disabled
)
{
pullToRefreshStyle
=
(
view
.
getStyle
()
||
{}).
pullToRefresh
||
{}
}
disabled
=
disable
if
(
pullToRefreshStyle
.
support
)
{
view
.
setPullToRefresh
(
Object
.
assign
({},
pullToRefreshStyle
,
{
support
:
!
disable
}))
}
}
if
(
plus
.
os
.
name
===
'
iOS
'
)
{
// 延迟执行避免iOS13触摸卡死
setTimeout
(
exec
,
20
)
}
else
{
exec
()
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录