|
@@ -15,10 +15,10 @@ class XScrollbar {
|
|
this.$dom.classList.add('x-scrollbar')
|
|
this.$dom.classList.add('x-scrollbar')
|
|
|
|
|
|
// 移动端检测
|
|
// 移动端检测
|
|
- this.isMobile = window.navigator.userAgent.toLowerCase().indexOf('mobile') != -1
|
|
|
|
|
|
+ this.isMobile = window.navigator.userAgent.toLowerCase().includes('mobile')
|
|
|
|
|
|
// 合并配置
|
|
// 合并配置
|
|
- let defaultOptions = {
|
|
|
|
|
|
+ const defaultOptions = {
|
|
// 响应容器和内容大小改变(自动更新滚动条)
|
|
// 响应容器和内容大小改变(自动更新滚动条)
|
|
autoUpdate: true,
|
|
autoUpdate: true,
|
|
// 阻止向上传递滚动事件
|
|
// 阻止向上传递滚动事件
|
|
@@ -28,7 +28,7 @@ class XScrollbar {
|
|
// 自动隐藏
|
|
// 自动隐藏
|
|
autoHide: true,
|
|
autoHide: true,
|
|
}
|
|
}
|
|
- let defaultStyle = {
|
|
|
|
|
|
+ const defaultStyle = {
|
|
// 滑块大小
|
|
// 滑块大小
|
|
thumbSize: '5px',
|
|
thumbSize: '5px',
|
|
// 轨道颜色
|
|
// 轨道颜色
|
|
@@ -41,8 +41,8 @@ class XScrollbar {
|
|
Object.assign(this, defaultOptions, defaultStyle, options)
|
|
Object.assign(this, defaultOptions, defaultStyle, options)
|
|
|
|
|
|
// 构造dom
|
|
// 构造dom
|
|
- let scrollLeft = this.$dom.scrollLeft
|
|
|
|
- let scrollTop = this.$dom.scrollTop
|
|
|
|
|
|
+ const scrollLeft = this.$dom.scrollLeft
|
|
|
|
+ const scrollTop = this.$dom.scrollTop
|
|
this.$container = this.html2dom('<div class="x-scrollbar__container"></div>')
|
|
this.$container = this.html2dom('<div class="x-scrollbar__container"></div>')
|
|
this.$content = this.html2dom('<div class="x-scrollbar__content"></div>')
|
|
this.$content = this.html2dom('<div class="x-scrollbar__content"></div>')
|
|
this.$trackX = this.html2dom('<div class="x-scrollbar__track-x"></div>')
|
|
this.$trackX = this.html2dom('<div class="x-scrollbar__track-x"></div>')
|
|
@@ -51,21 +51,19 @@ class XScrollbar {
|
|
this.$thumbY = this.html2dom('<div class="x-scrollbar__thumb-y"></div>')
|
|
this.$thumbY = this.html2dom('<div class="x-scrollbar__thumb-y"></div>')
|
|
this.$trackX.appendChild(this.$thumbX)
|
|
this.$trackX.appendChild(this.$thumbX)
|
|
this.$trackY.appendChild(this.$thumbY)
|
|
this.$trackY.appendChild(this.$thumbY)
|
|
- let childNodes = []
|
|
|
|
- Array.prototype.forEach.call(this.$dom.childNodes, function (node) {
|
|
|
|
|
|
+ const childNodes = []
|
|
|
|
+ Array.prototype.forEach.call(this.$dom.childNodes, node => {
|
|
childNodes.push(node)
|
|
childNodes.push(node)
|
|
})
|
|
})
|
|
- childNodes.forEach(
|
|
|
|
- function (node) {
|
|
|
|
- this.$content.appendChild(node)
|
|
|
|
- }.bind(this)
|
|
|
|
- )
|
|
|
|
|
|
+ childNodes.forEach(node => {
|
|
|
|
+ this.$content.appendChild(node)
|
|
|
|
+ })
|
|
this.$container.appendChild(this.$content)
|
|
this.$container.appendChild(this.$content)
|
|
this.$dom.appendChild(this.$container)
|
|
this.$dom.appendChild(this.$container)
|
|
|
|
|
|
// 处理内边距
|
|
// 处理内边距
|
|
- let styleObj = getComputedStyle(this.$dom)
|
|
|
|
- let padding = `${styleObj.paddingTop} ${styleObj.paddingRight} ${styleObj.paddingBottom} ${styleObj.paddingLeft}`
|
|
|
|
|
|
+ const styleObj = getComputedStyle(this.$dom)
|
|
|
|
+ const padding = `${styleObj.paddingTop} ${styleObj.paddingRight} ${styleObj.paddingBottom} ${styleObj.paddingLeft}`
|
|
if (padding != '0px 0px 0px 0px') {
|
|
if (padding != '0px 0px 0px 0px') {
|
|
this.$dom.style.padding = '0px 0px 0px 0px'
|
|
this.$dom.style.padding = '0px 0px 0px 0px'
|
|
this.$container.style.padding = padding
|
|
this.$container.style.padding = padding
|
|
@@ -137,8 +135,8 @@ class XScrollbar {
|
|
|
|
|
|
this.$trackX.style.display = this.hasXScrollbar ? 'block' : 'none'
|
|
this.$trackX.style.display = this.hasXScrollbar ? 'block' : 'none'
|
|
this.$trackY.style.display = this.hasYScrollbar ? 'block' : 'none'
|
|
this.$trackY.style.display = this.hasYScrollbar ? 'block' : 'none'
|
|
- this.$thumbX.style.width = this.thumbXWidth + 'px'
|
|
|
|
- this.$thumbY.style.height = this.thumbYHeight + 'px'
|
|
|
|
|
|
+ this.$thumbX.style.width = `${this.thumbXWidth}px`
|
|
|
|
+ this.$thumbY.style.height = `${this.thumbYHeight}px`
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -174,16 +172,16 @@ class XScrollbar {
|
|
|
|
|
|
requestAnimationFrame(() => {
|
|
requestAnimationFrame(() => {
|
|
if (this.thumbXActive) {
|
|
if (this.thumbXActive) {
|
|
- let offset = e.screenX - screenX
|
|
|
|
|
|
+ const offset = e.screenX - screenX
|
|
screenX = e.screenX
|
|
screenX = e.screenX
|
|
- let left = Math.max(Math.min(parseFloat(this.$thumbX.style.left || 0) + offset, this.thumbXMaxLeft), 0)
|
|
|
|
- this.$thumbX.style.left = left + 'px'
|
|
|
|
|
|
+ const left = Math.max(Math.min(Number.parseFloat(this.$thumbX.style.left || 0) + offset, this.thumbXMaxLeft), 0)
|
|
|
|
+ this.$thumbX.style.left = `${left}px`
|
|
this.$container.scrollLeft = (left / this.thumbXMaxLeft) * this.maxScrollLeft
|
|
this.$container.scrollLeft = (left / this.thumbXMaxLeft) * this.maxScrollLeft
|
|
} else {
|
|
} else {
|
|
- let offset = e.screenY - screenY
|
|
|
|
|
|
+ const offset = e.screenY - screenY
|
|
screenY = e.screenY
|
|
screenY = e.screenY
|
|
- let top = Math.max(Math.min(parseFloat(this.$thumbY.style.top || 0) + offset, this.thumbYMaxTop), 0)
|
|
|
|
- this.$thumbY.style.top = top + 'px'
|
|
|
|
|
|
+ const top = Math.max(Math.min(Number.parseFloat(this.$thumbY.style.top || 0) + offset, this.thumbYMaxTop), 0)
|
|
|
|
+ this.$thumbY.style.top = `${top}px`
|
|
this.$container.scrollTop = (top / this.thumbYMaxTop) * this.maxScrollTop
|
|
this.$container.scrollTop = (top / this.thumbYMaxTop) * this.maxScrollTop
|
|
}
|
|
}
|
|
})
|
|
})
|
|
@@ -194,7 +192,7 @@ class XScrollbar {
|
|
* 仅水平滚动(拨动鼠标滚轮时将作用于X轴)
|
|
* 仅水平滚动(拨动鼠标滚轮时将作用于X轴)
|
|
*/
|
|
*/
|
|
bindWheel() {
|
|
bindWheel() {
|
|
- let easeout = (start, end) => {
|
|
|
|
|
|
+ const easeout = (start, end) => {
|
|
if (Math.abs(end - start) <= 1) return end
|
|
if (Math.abs(end - start) <= 1) return end
|
|
return start + (end - start) / 4
|
|
return start + (end - start) / 4
|
|
}
|
|
}
|
|
@@ -217,13 +215,13 @@ class XScrollbar {
|
|
|
|
|
|
// 起始值
|
|
// 起始值
|
|
let scrollLeft = this.$container.scrollLeft
|
|
let scrollLeft = this.$container.scrollLeft
|
|
- let left = parseFloat(this.$thumbX.style.left || 0)
|
|
|
|
|
|
+ let left = Number.parseFloat(this.$thumbX.style.left || 0)
|
|
|
|
|
|
- let animate = () => {
|
|
|
|
|
|
+ const animate = () => {
|
|
scrollLeft = easeout(scrollLeft, this.scrollLeft)
|
|
scrollLeft = easeout(scrollLeft, this.scrollLeft)
|
|
left = easeout(left, this.left)
|
|
left = easeout(left, this.left)
|
|
this.$container.scrollLeft = scrollLeft
|
|
this.$container.scrollLeft = scrollLeft
|
|
- this.$thumbX.style.left = left + 'px'
|
|
|
|
|
|
+ this.$thumbX.style.left = `${left}px`
|
|
this.innerScroll = true
|
|
this.innerScroll = true
|
|
if (scrollLeft != this.scrollLeft) {
|
|
if (scrollLeft != this.scrollLeft) {
|
|
this.reqId = requestAnimationFrame(animate)
|
|
this.reqId = requestAnimationFrame(animate)
|
|
@@ -245,10 +243,10 @@ class XScrollbar {
|
|
this.$container.addEventListener('scroll', () => {
|
|
this.$container.addEventListener('scroll', () => {
|
|
if (this.thumbXActive || this.thumbYActive || this.innerScroll) return
|
|
if (this.thumbXActive || this.thumbYActive || this.innerScroll) return
|
|
if (this.hasXScrollbar) {
|
|
if (this.hasXScrollbar) {
|
|
- this.$thumbX.style.left = (this.$container.scrollLeft / this.maxScrollLeft) * this.thumbXMaxLeft + 'px'
|
|
|
|
|
|
+ this.$thumbX.style.left = `${(this.$container.scrollLeft / this.maxScrollLeft) * this.thumbXMaxLeft}px`
|
|
}
|
|
}
|
|
if (this.hasYScrollbar) {
|
|
if (this.hasYScrollbar) {
|
|
- this.$thumbY.style.top = (this.$container.scrollTop / this.maxScrollTop) * this.thumbYMaxTop + 'px'
|
|
|
|
|
|
+ this.$thumbY.style.top = `${(this.$container.scrollTop / this.maxScrollTop) * this.thumbYMaxTop}px`
|
|
}
|
|
}
|
|
})
|
|
})
|
|
}
|
|
}
|
|
@@ -258,7 +256,7 @@ class XScrollbar {
|
|
*/
|
|
*/
|
|
resizeObserver() {
|
|
resizeObserver() {
|
|
this.$resizeObserver = new ResizeObserver(entries => {
|
|
this.$resizeObserver = new ResizeObserver(entries => {
|
|
- let contentRect = entries[0].contentRect
|
|
|
|
|
|
+ const contentRect = entries[0].contentRect
|
|
if (!(contentRect.width || contentRect.height)) return
|
|
if (!(contentRect.width || contentRect.height)) return
|
|
this.update()
|
|
this.update()
|
|
})
|
|
})
|
|
@@ -273,10 +271,10 @@ class XScrollbar {
|
|
update() {
|
|
update() {
|
|
this.setThumbSize()
|
|
this.setThumbSize()
|
|
if (this.hasXScrollbar) {
|
|
if (this.hasXScrollbar) {
|
|
- this.$thumbX.style.left = (this.$container.scrollLeft / this.maxScrollLeft) * this.thumbXMaxLeft + 'px'
|
|
|
|
|
|
+ this.$thumbX.style.left = `${(this.$container.scrollLeft / this.maxScrollLeft) * this.thumbXMaxLeft}px`
|
|
}
|
|
}
|
|
if (this.hasYScrollbar) {
|
|
if (this.hasYScrollbar) {
|
|
- this.$thumbY.style.top = (this.$container.scrollTop / this.maxScrollTop) * this.thumbYMaxTop + 'px'
|
|
|
|
|
|
+ this.$thumbY.style.top = `${(this.$container.scrollTop / this.maxScrollTop) * this.thumbYMaxTop}px`
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -286,9 +284,9 @@ class XScrollbar {
|
|
* @returns
|
|
* @returns
|
|
*/
|
|
*/
|
|
html2dom(html) {
|
|
html2dom(html) {
|
|
- let element = document.createElement('div')
|
|
|
|
|
|
+ const element = document.createElement('div')
|
|
element.innerHTML = html
|
|
element.innerHTML = html
|
|
- let children = element.children
|
|
|
|
|
|
+ const children = element.children
|
|
if (children.length <= 1) {
|
|
if (children.length <= 1) {
|
|
return children[0]
|
|
return children[0]
|
|
} else {
|
|
} else {
|
|
@@ -303,37 +301,37 @@ class XScrollbar {
|
|
let content = `
|
|
let content = `
|
|
/* 轨道 */
|
|
/* 轨道 */
|
|
.x-scrollbar__track-x {
|
|
.x-scrollbar__track-x {
|
|
- height: ${parseInt(this.thumbSize) * 2 + 4}px;
|
|
|
|
|
|
+ height: ${Number.parseInt(this.thumbSize) * 2 + 4}px;
|
|
}
|
|
}
|
|
|
|
|
|
.x-scrollbar__track-y {
|
|
.x-scrollbar__track-y {
|
|
- width: ${parseInt(this.thumbSize) * 2 + 4}px;
|
|
|
|
|
|
+ width: ${Number.parseInt(this.thumbSize) * 2 + 4}px;
|
|
}
|
|
}
|
|
|
|
|
|
/* 滑块 */
|
|
/* 滑块 */
|
|
.x-scrollbar__track-x > .x-scrollbar__thumb-x,
|
|
.x-scrollbar__track-x > .x-scrollbar__thumb-x,
|
|
.x-scrollbar__track-y > .x-scrollbar__thumb-y {
|
|
.x-scrollbar__track-y > .x-scrollbar__thumb-y {
|
|
background: ${this.thumbBackground};
|
|
background: ${this.thumbBackground};
|
|
- border-radius: ${parseInt(this.thumbRadius || 0) != 5 ? parseInt(this.thumbRadius || 0) : parseInt(this.thumbSize)}px;
|
|
|
|
|
|
+ border-radius: ${Number.parseInt(this.thumbRadius || 0) != 5 ? Number.parseInt(this.thumbRadius || 0) : Number.parseInt(this.thumbSize)}px;
|
|
}
|
|
}
|
|
|
|
|
|
.x-scrollbar__track-x > .x-scrollbar__thumb-x {
|
|
.x-scrollbar__track-x > .x-scrollbar__thumb-x {
|
|
- height: ${parseInt(this.thumbSize)}px;
|
|
|
|
|
|
+ height: ${Number.parseInt(this.thumbSize)}px;
|
|
}
|
|
}
|
|
|
|
|
|
.x-scrollbar__track-y > .x-scrollbar__thumb-y {
|
|
.x-scrollbar__track-y > .x-scrollbar__thumb-y {
|
|
- width: ${parseInt(this.thumbSize)}px;
|
|
|
|
|
|
+ width: ${Number.parseInt(this.thumbSize)}px;
|
|
}
|
|
}
|
|
|
|
|
|
/* 激活后大小 */
|
|
/* 激活后大小 */
|
|
.x-scrollbar__track-x:hover > .x-scrollbar__thumb-x,
|
|
.x-scrollbar__track-x:hover > .x-scrollbar__thumb-x,
|
|
.x-scrollbar__track--draging > .x-scrollbar__thumb-x {
|
|
.x-scrollbar__track--draging > .x-scrollbar__thumb-x {
|
|
- height: ${parseInt(this.thumbSize) * 2}px;
|
|
|
|
|
|
+ height: ${Number.parseInt(this.thumbSize) * 2}px;
|
|
}
|
|
}
|
|
|
|
|
|
.x-scrollbar__track-y:hover > .x-scrollbar__thumb-y,
|
|
.x-scrollbar__track-y:hover > .x-scrollbar__thumb-y,
|
|
.x-scrollbar__track--draging > .x-scrollbar__thumb-y {
|
|
.x-scrollbar__track--draging > .x-scrollbar__thumb-y {
|
|
- width: ${parseInt(this.thumbSize) * 2}px;
|
|
|
|
|
|
+ width: ${Number.parseInt(this.thumbSize) * 2}px;
|
|
}
|
|
}
|
|
|
|
|
|
/* 鼠标移入轨道 || 拖动过程中 => 显示轨道 & 高亮滑块 */
|
|
/* 鼠标移入轨道 || 拖动过程中 => 显示轨道 & 高亮滑块 */
|
|
@@ -344,9 +342,9 @@ class XScrollbar {
|
|
background: ${this.trackBackground || 'transparent'};
|
|
background: ${this.trackBackground || 'transparent'};
|
|
}`
|
|
}`
|
|
|
|
|
|
- this.key = 'x-scrollbar-' + Math.abs(((1 + Math.random()) * Date.now()) | 0).toString(16)
|
|
|
|
|
|
+ this.key = `x-scrollbar-${Math.abs(Math.trunc((1 + Math.random()) * Date.now())).toString(16)}`
|
|
this.$dom.setAttribute(this.key, '')
|
|
this.$dom.setAttribute(this.key, '')
|
|
- let style = this.html2dom(`<style ${this.key}></style>`)
|
|
|
|
|
|
+ const style = this.html2dom(`<style ${this.key}></style>`)
|
|
content = content.replaceAll('\n.x-scrollbar', `\n[${this.key}] > .x-scrollbar`)
|
|
content = content.replaceAll('\n.x-scrollbar', `\n[${this.key}] > .x-scrollbar`)
|
|
content = content.replaceAll(';', ' !important;')
|
|
content = content.replaceAll(';', ' !important;')
|
|
style.innerHTML = content
|
|
style.innerHTML = content
|