完成滚动组件的迁移
parent
32f89ab889
commit
ed727a36b8
|
@ -43,7 +43,7 @@
|
|||
- [ ] `wc-datepicker`日期选择器
|
||||
- [ ] `wc-timepicker`时间选择器
|
||||
- [x] `wc-code`代码高亮插件
|
||||
- [ ] `wc-scroll`滚动组件
|
||||
- [x] `wc-scroll`滚动组件
|
||||
- [ ] `wc-silder`滑块组件
|
||||
- [ ] `wc-progress`进度条组件
|
||||
- [ ] `wc-tree`树形菜单组件
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
"author": "yutent",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@bd/wcui-cli": "^1.1.0"
|
||||
"@bd/wcui-cli": "^1.2.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import { nextTick, css, html, Component } from '@bd/core'
|
||||
|
||||
class Dropdown extends Component {
|
||||
mounted() {
|
||||
console.log('Dropdown: ', this.$refs)
|
||||
}
|
||||
|
||||
foo() {}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="aa" ref="aa" @click=${this.foo}>
|
||||
<div class="bb" ref="bb">
|
||||
<slot ref="dd"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cc" ref="cc">${this.foo}</div>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
Dropdown.reg('dropdown')
|
|
@ -4,258 +4,456 @@
|
|||
* @date 2023/03/20 15:17:25
|
||||
*/
|
||||
|
||||
import { css, bind, html, unbind, Component } from '@bd/core'
|
||||
import { css, html, bind, unbind, Component } from '@bd/core'
|
||||
|
||||
class Scroll extends Component {
|
||||
static props = {
|
||||
axis: 'xy',
|
||||
distance: 0
|
||||
axis: 'xy', // 滚动方向, 默认x轴和y轴都可以滚动
|
||||
delay: 1000, // 节流防抖延迟
|
||||
distance: 1 // 触发距离阀值, 单位像素
|
||||
}
|
||||
dragging = false
|
||||
hovering = false
|
||||
|
||||
static styles = [
|
||||
css`
|
||||
:host {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
}
|
||||
.scroller {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.container {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
overflow: auto;
|
||||
scrollbar-width: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
scrollbar-width: 0;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
scrollbar-width: none; //火狐专属
|
||||
}
|
||||
.scroll-bar {
|
||||
position: absolute;
|
||||
background: #909399;
|
||||
width: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: opacity ease-in-out 0.2s;
|
||||
.content {
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
}
|
||||
}
|
||||
`,
|
||||
css`
|
||||
/* 横向 */
|
||||
|
||||
&.vertical {
|
||||
width: 8px;
|
||||
.is-horizontal,
|
||||
.is-vertical {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
z-index: 10240;
|
||||
opacity: 0;
|
||||
user-select: none;
|
||||
transition: opacity 0.3s linear, visibility 0.3s linear;
|
||||
|
||||
.thumb {
|
||||
display: block;
|
||||
border-radius: 5px;
|
||||
background: rgba(44, 47, 53, 0.25);
|
||||
cursor: default;
|
||||
transition: width 0.1s linear, height 0.1s linear;
|
||||
|
||||
&:hover {
|
||||
background: rgba(44, 47, 53, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.is-horizontal {
|
||||
flex-direction: column;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
|
||||
.thumb {
|
||||
width: 0;
|
||||
height: 6px;
|
||||
|
||||
&:hover {
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 纵向 */
|
||||
.is-vertical {
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
&.horizon {
|
||||
height: 8px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
width: 10px;
|
||||
height: 100%;
|
||||
|
||||
.thumb {
|
||||
width: 6px;
|
||||
height: 0;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.5 !important;
|
||||
width: 10px;
|
||||
}
|
||||
}
|
||||
:host([disabled]) {
|
||||
overflow: hidden !important;
|
||||
.scroll-bar {
|
||||
visibility: hidden;
|
||||
}
|
||||
`,
|
||||
css`
|
||||
:host(:hover) {
|
||||
.is-horizontal,
|
||||
.is-vertical {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
:host([axis='x']) {
|
||||
overflow-x: auto;
|
||||
.wrapper {
|
||||
overflow-y: hidden;
|
||||
.vertical {
|
||||
}
|
||||
.is-vertical {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
:host([axis='y']) {
|
||||
overflow-y: auto;
|
||||
.wrapper {
|
||||
overflow-x: hidden;
|
||||
.horizon {
|
||||
}
|
||||
.is-horizontal {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
:host([disabled]) {
|
||||
.wrapper {
|
||||
overflow: hidden;
|
||||
}
|
||||
.is-vertical,
|
||||
.is-horizontal {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
`
|
||||
]
|
||||
|
||||
stamp = 0
|
||||
|
||||
cache = {
|
||||
width: 0, // 滚动组件的真实宽度(可视宽高)
|
||||
height: 0, // 滚动组件的真实高度(可视宽高)
|
||||
widthFixed: 0, // 滚动组件的宽度修正值
|
||||
heightFixed: 0, // 滚动组件的高度修正值
|
||||
scrollWidth: 0, // 滚动组件的滚动宽度
|
||||
scrollHeight: 0, // 滚动组件的滚动高度
|
||||
xBar: 0, // 横轴长度
|
||||
yBar: 0, // 纵轴长度
|
||||
thumbX: 0, //横向条滚动距离
|
||||
thumbY: 0 // 纵向条滚动距离
|
||||
}
|
||||
|
||||
get scrollTop() {
|
||||
return this.$refs.scroller.scrollTop
|
||||
return this.$refs.box?.scrollTop || 0
|
||||
}
|
||||
set scrollTop(val) {
|
||||
this.$refs.scroller.scrollTop = val
|
||||
|
||||
set scrollTop(n) {
|
||||
n = +n
|
||||
if (n === n) {
|
||||
this.$refs.box.scrollTop = n
|
||||
}
|
||||
get scrollHeight() {
|
||||
return this.$refs.scroller.scrollHeight
|
||||
}
|
||||
set scrollHeight(val) {
|
||||
this.$refs.scroller.scrollHeight = val
|
||||
}
|
||||
|
||||
get scrollLeft() {
|
||||
return this.$refs.scroller.scrollLeft
|
||||
return this.$refs.box?.scrollLeft || 0
|
||||
}
|
||||
set scrollLeft(val) {
|
||||
this.$refs.scroller.scrollLeft = val
|
||||
|
||||
set scrollLeft(n) {
|
||||
n = +n
|
||||
if (n === n) {
|
||||
this.$refs.box.scrollLeft = n
|
||||
}
|
||||
}
|
||||
|
||||
get scrollHeight() {
|
||||
return this.$refs.box?.scrollHeight
|
||||
}
|
||||
|
||||
get scrollWidth() {
|
||||
return this.$refs.scroller.scrollWidth
|
||||
}
|
||||
set scrollWidth(val) {
|
||||
this.$refs.scroller.scrollWidth = val
|
||||
}
|
||||
render() {
|
||||
return html`
|
||||
<div ref="scroller" class="scroller">
|
||||
<slot ref="slot"></slot>
|
||||
</div>
|
||||
<div ref="vertical" class="scroll-bar vertical"></div>
|
||||
<div ref="horizon" class="scroll-bar horizon"></div>
|
||||
`
|
||||
return this.$refs.box?.scrollWidth
|
||||
}
|
||||
|
||||
onmouseenter() {
|
||||
this.hovering = true
|
||||
this.$refs.vertical.style.opacity = 0.3
|
||||
this.$refs.horizon.style.opacity = 0.3
|
||||
}
|
||||
onmouseleave() {
|
||||
this.hovering = false
|
||||
if (!this.dragging) {
|
||||
this.$refs.vertical.style.opacity = 0
|
||||
this.$refs.horizon.style.opacity = 0
|
||||
}
|
||||
}
|
||||
onmousedown(e) {
|
||||
this.dragging = true
|
||||
const {
|
||||
clientHeight,
|
||||
scrollHeight,
|
||||
clientWidth,
|
||||
scrollWidth,
|
||||
verticalHeight,
|
||||
horizonWidth
|
||||
} = this
|
||||
let start, cur
|
||||
const isVerticalScroll = e.target === this.$refs.vertical
|
||||
if (isVerticalScroll) {
|
||||
start = e.clientY
|
||||
cur = this.scrollTop
|
||||
__init__(ev) {
|
||||
//
|
||||
let width = this.offsetWidth
|
||||
let height = this.offsetHeight
|
||||
let scrollWidth = this.scrollWidth
|
||||
let scrollHeight = this.scrollHeight
|
||||
let clientWidth = this.$refs.box.clientWidth
|
||||
let clientHeight = this.$refs.box.clientHeight
|
||||
|
||||
let yBar = 50 // 滚动条的高度
|
||||
let xBar = 50 // 滚动条的宽度
|
||||
let { widthFixed, heightFixed } = this.cache
|
||||
let needFixed = false
|
||||
let style = ''
|
||||
|
||||
this.scrollLeft = 0
|
||||
this.scrollTop = 0
|
||||
|
||||
// 已经修正过宽度
|
||||
if (widthFixed > 0) {
|
||||
needFixed = scrollHeight === clientHeight
|
||||
widthFixed = needFixed ? 0 : widthFixed
|
||||
} else {
|
||||
start = e.clientX
|
||||
cur = this.scrollLeft
|
||||
// 高度超出, 说明出现横向滚动条
|
||||
if (scrollHeight > clientHeight) {
|
||||
// width - clientWidth 等于滚动条的宽度, 下同
|
||||
needFixed = true
|
||||
widthFixed = width + (width - clientWidth)
|
||||
}
|
||||
}
|
||||
|
||||
const onmousemove = bind(document, 'mousemove', e => {
|
||||
let dif, rang, progress
|
||||
if (isVerticalScroll) {
|
||||
dif = e.clientY - start
|
||||
rang = clientHeight - verticalHeight
|
||||
progress = dif / rang
|
||||
this.scrollTop = cur + progress * (scrollHeight - clientHeight)
|
||||
if (heightFixed > 0) {
|
||||
needFixed = scrollWidth === clientWidth
|
||||
heightFixed = needFixed ? 0 : heightFixed
|
||||
} else {
|
||||
dif = e.clientX - start
|
||||
rang = clientWidth - horizonWidth
|
||||
progress = dif / rang
|
||||
this.scrollLeft = cur + progress * (scrollWidth - clientWidth)
|
||||
if (scrollWidth > clientWidth) {
|
||||
needFixed = true
|
||||
heightFixed = height + (height - clientHeight)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
this.onmouseup = bind(document, 'mouseup', () => {
|
||||
this.dragging = false
|
||||
if (!this.hovering) {
|
||||
this.$refs.vertical.style.opacity = 0
|
||||
this.$refs.horizon.style.opacity = 0
|
||||
this.cache.widthFixed = widthFixed
|
||||
this.cache.heightFixed = heightFixed
|
||||
|
||||
if (needFixed) {
|
||||
if (widthFixed > 0) {
|
||||
style += `width:${widthFixed}px;`
|
||||
}
|
||||
unbind(document, 'mousemove', onmousemove)
|
||||
})
|
||||
|
||||
if (heightFixed > 0) {
|
||||
style += `height:${heightFixed}px;`
|
||||
}
|
||||
onscroll(ev) {
|
||||
const {
|
||||
distance,
|
||||
scrollTop,
|
||||
scrollLeft,
|
||||
clientHeight,
|
||||
scrollHeight,
|
||||
clientWidth,
|
||||
scrollWidth,
|
||||
verticalHeight,
|
||||
horizonWidth
|
||||
} = this
|
||||
const { vertical, horizon } = this.$refs
|
||||
const verticalProgress = scrollTop / (scrollHeight - clientHeight) || 0
|
||||
const horizonProgress = scrollLeft / (scrollWidth - clientWidth) || 0
|
||||
vertical.style.transform = `translateY(${
|
||||
(clientHeight - verticalHeight) * verticalProgress
|
||||
}px)`
|
||||
horizon.style.transform = `translateX(${
|
||||
(clientWidth - horizonWidth) * horizonProgress
|
||||
}px)`
|
||||
if (!ev) {
|
||||
//事件对象不存在,则是手动调用的 不触发事件。
|
||||
this.$refs.box.style.cssText = style
|
||||
|
||||
// 需要修正视图容器, 修正完之后, 需要重新获取滚动宽高
|
||||
scrollWidth = this.$refs.box.scrollWidth
|
||||
scrollHeight = this.$refs.box.scrollHeight
|
||||
}
|
||||
// 修正由于未知原因,导致父容器产生滚动距离
|
||||
// 导致的内容被遮挡的bug
|
||||
this.$refs.box.parentNode.scrollTop = 0
|
||||
|
||||
yBar = (height * (height / scrollHeight)) >> 0
|
||||
xBar = (width * (width / scrollWidth)) >> 0
|
||||
|
||||
if (yBar < 50) {
|
||||
yBar = 50
|
||||
}
|
||||
if (xBar < 50) {
|
||||
xBar = 50
|
||||
}
|
||||
|
||||
// 100%或主体高度比滚动条还短时不显示
|
||||
if (xBar >= width) {
|
||||
xBar = 0
|
||||
}
|
||||
if (yBar >= height) {
|
||||
yBar = 0
|
||||
}
|
||||
|
||||
this.cache.height = height
|
||||
this.cache.width = width
|
||||
this.cache.scrollHeight = scrollHeight
|
||||
this.cache.scrollWidth = scrollWidth
|
||||
this.cache.yBar = yBar
|
||||
this.cache.xBar = xBar
|
||||
|
||||
this.$refs.x.style.width = xBar + 'px'
|
||||
this.$refs.y.style.height = yBar + 'px'
|
||||
}
|
||||
|
||||
_fetchScrollX(moveX) {
|
||||
var { scrollWidth, width, xBar } = this.cache
|
||||
|
||||
if (moveX < 0) {
|
||||
moveX = 0
|
||||
} else if (moveX > width - xBar) {
|
||||
moveX = width - xBar
|
||||
}
|
||||
this.scrollLeft = (scrollWidth - width) * (moveX / (width - xBar))
|
||||
this.$refs.x.style.transform = `translateX(${moveX}px)`
|
||||
|
||||
return moveX
|
||||
}
|
||||
|
||||
_fetchScrollY(moveY) {
|
||||
var { scrollHeight, height, yBar } = this.cache
|
||||
|
||||
if (moveY < 0) {
|
||||
moveY = 0
|
||||
} else if (moveY > height - yBar) {
|
||||
moveY = height - yBar
|
||||
}
|
||||
|
||||
this.scrollTop = (scrollHeight - height) * (moveY / (height - yBar))
|
||||
this.$refs.y.style.transform = `translateY(${moveY}px)`
|
||||
return moveY
|
||||
}
|
||||
|
||||
_fireReachEnd(action = 'reach-bottom') {
|
||||
var delay = this.delay
|
||||
var { scrollHeight, height } = this.cache
|
||||
var top = this.$refs.box.scrollTop
|
||||
var now = Date.now()
|
||||
|
||||
if (now - this.stamp > delay) {
|
||||
if (action === 'reach-bottom') {
|
||||
if (height + top < scrollHeight) {
|
||||
return
|
||||
}
|
||||
if (this.verticalHeight) {
|
||||
if (scrollHeight - scrollTop - clientHeight <= distance) {
|
||||
this.$emit('reach-bottom')
|
||||
}
|
||||
if (scrollTop === 0) {
|
||||
this.$emit('reach-top')
|
||||
}
|
||||
}
|
||||
}
|
||||
initScrollBar() {
|
||||
const { axis, clientHeight, scrollHeight, clientWidth, scrollWidth } = this
|
||||
const { vertical, horizon } = this.$refs
|
||||
// console.log(this.$refs)
|
||||
if (clientHeight !== scrollHeight) {
|
||||
this.verticalHeight = (clientHeight / scrollHeight) * clientHeight
|
||||
} else {
|
||||
this.verticalHeight = 0
|
||||
}
|
||||
if (clientWidth !== scrollWidth) {
|
||||
this.horizonWidth = (clientWidth / scrollWidth) * clientWidth
|
||||
} else {
|
||||
this.horizonWidth = 0
|
||||
}
|
||||
if (axis.includes('x')) {
|
||||
horizon.style.width = this.horizonWidth + 'px'
|
||||
bind(horizon, 'mousedown', this.onmousedown.bind(this))
|
||||
}
|
||||
if (axis.includes('y')) {
|
||||
vertical.style.height = this.verticalHeight + 'px'
|
||||
bind(vertical, 'mousedown', this.onmousedown.bind(this))
|
||||
if (top > 0) {
|
||||
return
|
||||
}
|
||||
}
|
||||
#watchResize() {
|
||||
const slotList = this.$refs.slot.assignedNodes()
|
||||
if (slotList) {
|
||||
slotList.forEach(element => {
|
||||
if (element.nodeType === 1) {
|
||||
this.resizeObserver.observe(element)
|
||||
}
|
||||
})
|
||||
|
||||
this.stamp = now
|
||||
this.$emit(action)
|
||||
}
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.$on('mouseenter', this.onmouseenter)
|
||||
this.$on('mouseleave', this.onmouseleave)
|
||||
this.onscroll = bind(
|
||||
this.$refs.scroller,
|
||||
'scroll',
|
||||
this.onscroll.bind(this)
|
||||
)
|
||||
this.resizeObserver = new ResizeObserver(() => {
|
||||
this.initScrollBar()
|
||||
this.onscroll()
|
||||
let startX,
|
||||
startY,
|
||||
moveX,
|
||||
moveY,
|
||||
mousemoveFn = ev => {
|
||||
let { thumbY, thumbX } = this.cache
|
||||
if (startX !== undefined) {
|
||||
moveX = this._fetchScrollX(thumbX + ev.pageX - startX)
|
||||
}
|
||||
|
||||
if (startY !== undefined) {
|
||||
moveY = this._fetchScrollY(thumbY + ev.pageY - startY)
|
||||
}
|
||||
},
|
||||
mouseupFn = ev => {
|
||||
if (Math.abs(ev.pageY - startY) > this.distance) {
|
||||
this._fireReachEnd(ev.pageY > startY ? 'reach-bottom' : 'reach-top')
|
||||
}
|
||||
startX = undefined
|
||||
startY = undefined
|
||||
this.cache.thumbX = moveX || 0
|
||||
this.cache.thumbY = moveY || 0
|
||||
delete this._active
|
||||
unbind(document, 'mousemove', mousemoveFn)
|
||||
unbind(document, 'mouseup', mouseupFn)
|
||||
}
|
||||
|
||||
// 鼠标滚动事件
|
||||
this._scrollFn = bind(this.$refs.box, 'scroll', ev => {
|
||||
ev.stopPropagation()
|
||||
// 拖拽时忽略滚动事件
|
||||
if (this._active) {
|
||||
return
|
||||
}
|
||||
var axis = this.axis
|
||||
var {
|
||||
xBar,
|
||||
yBar,
|
||||
thumbX,
|
||||
thumbY,
|
||||
scrollHeight,
|
||||
scrollWidth,
|
||||
width,
|
||||
height
|
||||
} = this.cache
|
||||
var currTop = this.$refs.box.scrollTop
|
||||
var currLeft = this.$refs.box.scrollLeft
|
||||
|
||||
// x轴 y轴 都为0时, 不作任何处理
|
||||
if (xBar === 0 && yBar === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
//
|
||||
if (axis === 'y' || axis === 'xy') {
|
||||
if (yBar) {
|
||||
// 修正滚动条的位置
|
||||
// 滚动比例 y 滚动条的可移动距离
|
||||
let fixedY = (currTop / (scrollHeight - height)) * (height - yBar)
|
||||
|
||||
fixedY = fixedY >> 0
|
||||
|
||||
if (fixedY !== thumbY) {
|
||||
this.cache.thumbY = fixedY
|
||||
this.$refs.y.style.transform = `translateY(${fixedY}px)`
|
||||
|
||||
if (Math.abs(fixedY - thumbY) > this.distance) {
|
||||
this._fireReachEnd(fixedY > thumbY ? 'reach-bottom' : 'reach-top')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (axis === 'x' || axis === 'xy') {
|
||||
if (xBar) {
|
||||
// 修正滚动条的位置
|
||||
// 滚动比例 x 滚动条的可移动距离
|
||||
let fixedX = (currLeft / (scrollWidth - width)) * (width - xBar)
|
||||
|
||||
fixedX = fixedX >> 0
|
||||
|
||||
if (fixedX !== thumbX) {
|
||||
this.cache.thumbX = fixedX
|
||||
this.$refs.x.style.transform = `translateX(${fixedX}px)`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.$emit('scroll')
|
||||
})
|
||||
this.#watchResize()
|
||||
this.$refs.slot.addEventListener('slotchange', () => this.#watchResize())
|
||||
|
||||
this._yBarFn = bind(this.$refs.y, 'mousedown', ev => {
|
||||
startY = ev.pageY
|
||||
|
||||
this._active = true
|
||||
|
||||
bind(document, 'mousemove', mousemoveFn)
|
||||
bind(document, 'mouseup', mouseupFn)
|
||||
})
|
||||
|
||||
this._xBarFn = bind(this.$refs.x, 'mousedown', ev => {
|
||||
startX = ev.pageX
|
||||
this._active = true
|
||||
|
||||
bind(document, 'mousemove', mousemoveFn)
|
||||
bind(document, 'mouseup', mouseupFn)
|
||||
})
|
||||
|
||||
this.__observer = new ResizeObserver(this.__init__.bind(this))
|
||||
this.__observer.observe(this.$refs.cont)
|
||||
}
|
||||
unmounted() {
|
||||
this.resizeObserver.disconnect()
|
||||
unbind(document, 'mouseup', this.onmouseup)
|
||||
this.$of('mouseenter', this.onmouseenter)
|
||||
this.$of('mouseleave', this.onmouseleave)
|
||||
this.$of('scroll', this.onscroll)
|
||||
unbind(this.$refs.vertical, 'mousedown', this.onmousedown)
|
||||
unbind(this.$refs.horizon, 'mousedown', this.onmousedown)
|
||||
this.__observer.disconnect()
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div class="container">
|
||||
<div class="wrapper" ref="box">
|
||||
<div class="content" ref="cont"><slot></slot></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="is-horizontal"><span ref="x" class="thumb"></span></div>
|
||||
<div class="is-vertical"><span ref="y" class="thumb"></span></div>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue