像许多人一样,我一直在寻找以下东西:
- 在大多数现代浏览器中保持一致的样式和功能
- 不是一些可笑的 3000 行臃肿的 jQuery 扩展 cr*p
...但是唉——什么也没有!
好吧,如果一项工作值得做……我就能在大约 30 分钟内启动并运行一些东西。免责声明:它有很多已知的(可能还有一些未知的)问题,但这让我想知道在许多产品中其他 2920 行 JS 到底有什么用!
(window => {
let initCoords;
const coords_update = e => {
if (initCoords) {
const elem = initCoords.bar.closest('.scrollr');
const eSuffix = initCoords.axis.toUpperCase();
const sSuffix = initCoords.axis == 'x' ? 'Left' : 'Top';
const dSuffix = initCoords.axis == 'x' ? 'Width' : 'Height';
const max = elem['scroll' + dSuffix] - elem['client' + dSuffix];
const room = elem['client' + dSuffix] - initCoords.bar['client' + dSuffix];
const delta = e['page' + eSuffix] - initCoords.abs;
const abs = initCoords.p0 + delta;
elem['scroll' + sSuffix] = max * abs / room;
}
};
const scrollr_resize = elem => {
const xBar = elem.querySelector('.track.x .bar');
const yBar = elem.querySelector('.track.y .bar');
const xRel = elem.clientWidth / elem.scrollWidth;
const yRel = elem.clientHeight / elem.scrollHeight;
xBar.style.width = (100 * xRel).toFixed(2) + '%';
yBar.style.height = (100 * yRel).toFixed(2) + '%';
};
const scrollr_init = elem => {
const xTrack = document.createElement('span');
const yTrack = document.createElement('span');
const xBar = document.createElement('span');
const yBar = document.createElement('span');
xTrack.className = 'track x';
yTrack.className = 'track y';
xBar.className = 'bar';
yBar.className = 'bar';
xTrack.appendChild(xBar);
yTrack.appendChild(yBar);
elem.appendChild(xTrack);
elem.appendChild(yTrack);
elem.addEventListener('wheel', scrollr_OnWheel);
elem.addEventListener('scroll', scrollr_OnScroll);
xTrack.addEventListener('wheel', xTrack_OnWheel);
xTrack.addEventListener('click', xTrack_OnClick);
xTrack.addEventListener('mouseover', () => xTrack.classList.add('active'));
xTrack.addEventListener('mouseout', () => {
if (!initCoords) xTrack.classList.remove('active');
});
yTrack.addEventListener('click', yTrack_OnClick);
yTrack.addEventListener('mouseover', () => yTrack.classList.add('active'));
yTrack.addEventListener('mouseout', () => {
if (!initCoords) yTrack.classList.remove('active');
});
xBar.addEventListener('click', bar_OnClick);
xBar.addEventListener('mousedown', xBar_OnMouseDown);
yBar.addEventListener('click', bar_OnClick);
yBar.addEventListener('mousedown', yBar_OnMouseDown);
scrollr_resize(elem);
};
window.addEventListener('load', e => {
const scrollrz = Array.from(document.querySelectorAll('.scrollr'));
scrollrz.forEach(scrollr_init);
});
window.addEventListener('resize', e => {
const scrollrz = Array.from(document.querySelectorAll('.scrollr'));
scrollrz.forEach(scrollr_resize);
});
window.addEventListener('mousemove', coords_update);
window.addEventListener('mouseup', e => {
initCoords = null;
Array.from(document.querySelectorAll('.track.active'))
.forEach(elem => elem.classList.remove('active'));
});
function xBar_OnMouseDown(e) {
const p0 = this.offsetLeft;
initCoords = {
axis: 'x',
abs: e.pageX,
bar: this,
p0
};
}
function yBar_OnMouseDown(e) {
const p0 = this.offsetTop;
initCoords = {
axis: 'y',
abs: e.pageY,
bar: this,
p0
};
}
function bar_OnClick(e) {
e.stopPropagation();
}
function xTrack_OnClick(e) {
const elem = this.closest('.scrollr');
const xBar = this.querySelector('.bar');
let unit = elem.clientWidth - 30;
if (e.offsetX <= xBar.offsetLeft) unit *= -1;
elem.scrollLeft += unit;
}
function yTrack_OnClick(e) {
const elem = this.closest('.scrollr');
const yBar = this.querySelector('.bar');
let unit = elem.clientHeight - 30;
if (e.offsetY <= yBar.offsetTop) unit *= -1;
elem.scrollTop += unit;
}
function xTrack_OnWheel(e) {
e.stopPropagation();
const elem = this.closest('.scrollr');
const left0 = elem.scrollLeft;
const delta = e.deltaY !== 0 ? e.deltaY : e.deltaX;
elem.scrollLeft += delta;
const moved = left0 !== elem.scrollLeft;
if (moved) e.preventDefault();
}
function scrollr_OnWheel(e) {
const left0 = this.scrollLeft;
const top0 = this.scrollTop;
this.scrollLeft += e.deltaX;
this.scrollTop += e.deltaY;
const moved = left0 !== this.scrollLeft || top0 !== this.scrollTop;
if (moved) e.preventDefault();
}
function scrollr_OnScroll(e) {
const xTrack = this.querySelector('.track.x');
const yTrack = this.querySelector('.track.y');
const xBar = xTrack.querySelector('.bar');
const yBar = yTrack.querySelector('.bar');
const xMax = this.scrollWidth - this.clientWidth;
const yMax = this.scrollHeight - this.clientHeight;
const xFrac = this.scrollLeft / xMax;
const yFrac = this.scrollTop / yMax;
const xAbs = xFrac * (this.clientWidth - xBar.clientWidth);
const yAbs = yFrac * (this.clientHeight - yBar.clientHeight);
xTrack.style.left = this.scrollLeft + 'px';
xTrack.style.bottom = -this.scrollTop + 'px';
xBar.style.left = xAbs + 'px';
yTrack.style.top = this.scrollTop + 'px';
yTrack.style.right = -this.scrollLeft + 'px';
yBar.style.top = yAbs + 'px';
};
})(window);
.scrollr {
overflow: hidden;
position: relative;
}
.track {
position: absolute;
cursor: pointer;
transition: background-color .3s;
user-select: none;
}
.track.x {
left: 0;
bottom: 0;
width: 100%;
height: 10px;
}
.track.y {
top: 0;
right: 0;
height: 100%;
width: 10px;
}
.bar {
position: absolute;
background-color: yellow;
transition: background-color .3s, opacity .3s, width .3s, height .3s, margin .3s;
display: block;
width: 100%;
height: 100%;
opacity: .7;
}
.track.x .bar {
min-width: 25px;
height: 3px;
margin: 5px 0 2px 0;
}
.track.y .bar {
min-height: 25px;
width: 3px;
margin: 0 2px 0 5px;
}
.track.active {
background-color: #ccc;
}
.track.active .bar {
background-color: #999;
margin: 0;
opacity: 1;
}
.track.x.active .bar {
height: 10px;
}
.track.y.active .bar {
width: 10px;
}
/* Custom client stuff */
.content {
background: red;
}
.content p {
width: 450px;
margin: 0;
}
.scrollr {
max-width: 350px;
max-height: 150px;
}
<div class="scrollr content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc diam magna, molestie sit amet auctor nec, dictum quis mi. Duis pellentesque lacinia pretium. Donec pulvinar, risus sit amet dapibus mattis, eros urna bibendum elit, vel mollis sapien arcu
vitae mi. Fusce vulputate vestibulum metus dapibus eleifend. Quisque ut dictum orci. Nunc bibendum, sapien ac condimentum placerat, arcu orci mollis nunc, vitae sollicitudin arcu nulla quis enim. Praesent non tellus vitae quam tempor maximus vel sed
dolor. Donec id ante ultricies, iaculis sem ut, sollicitudin enim. Quisque id mauris est. Maecenas viverra urna vitae velit semper, vel ultricies augue feugiat. Pellentesque in libero porttitor, lacinia metus in, maximus nisi. Phasellus commodo ligula
vel arcu iaculis hendrerit vitae vel diam. Sed sed lorem maximus, vestibulum leo ut, posuere libero. Donec arcu dui, euismod id aliquet sed, porttitor vitae elit.</p>
<p>Sed aliquam eget justo sit amet dictum. Suspendisse potenti. In placerat orci quis vehicula vehicula. Proin tempor laoreet suscipit. Proin non nulla lacinia est ullamcorper maximus et a sem. Nulla at lacus rhoncus, malesuada ante in, imperdiet sem.
Mauris convallis tristique metus in iaculis. Nulla laoreet ligula non interdum tincidunt. Morbi sed venenatis arcu, sed gravida est. Fusce malesuada ullamcorper lacus, in vulputate risus finibus non.</p>
<p>Suspendisse sapien leo, auctor non ex vitae, volutpat laoreet tortor. Suspendisse sodales libero velit, sed pulvinar lectus feugiat vel. Sed erat eros, porttitor id enim nec, ornare hendrerit nibh. Phasellus at nisi lectus. Cras semper lobortis condimentum.
Etiam nunc felis, vehicula vitae tincidunt pellentesque, pretium sit amet dui. Duis aliquet ultrices lacus eget efficitur. Ut imperdiet velit sed enim laoreet, sed semper libero hendrerit. Donec malesuada auctor sollicitudin.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc diam magna, molestie sit amet auctor nec, dictum quis mi. Duis pellentesque lacinia pretium. Donec pulvinar, risus sit amet dapibus mattis, eros urna bibendum elit, vel mollis sapien arcu
vitae mi. Fusce vulputate vestibulum metus dapibus eleifend. Quisque ut dictum orci. Nunc bibendum, sapien ac condimentum placerat, arcu orci mollis nunc, vitae sollicitudin arcu nulla quis enim. Praesent non tellus vitae quam tempor maximus vel sed
dolor. Donec id ante ultricies, iaculis sem ut, sollicitudin enim. Quisque id mauris est. Maecenas viverra urna vitae velit semper, vel ultricies augue feugiat. Pellentesque in libero porttitor, lacinia metus in, maximus nisi. Phasellus commodo ligula
vel arcu iaculis hendrerit vitae vel diam. Sed sed lorem maximus, vestibulum leo ut, posuere libero. Donec arcu dui, euismod id aliquet sed, porttitor vitae elit.</p>
<p>Sed aliquam eget justo sit amet dictum. Suspendisse potenti. In placerat orci quis vehicula vehicula. Proin tempor laoreet suscipit. Proin non nulla lacinia est ullamcorper maximus et a sem. Nulla at lacus rhoncus, malesuada ante in, imperdiet sem.
Mauris convallis tristique metus in iaculis. Nulla laoreet ligula non interdum tincidunt. Morbi sed venenatis arcu, sed gravida est. Fusce malesuada ullamcorper lacus, in vulputate risus finibus non.</p>
<p>Suspendisse sapien leo, auctor non ex vitae, volutpat laoreet tortor. Suspendisse sodales libero velit, sed pulvinar lectus feugiat vel. Sed erat eros, porttitor id enim nec, ornare hendrerit nibh. Phasellus at nisi lectus. Cras semper lobortis condimentum.
Etiam nunc felis, vehicula vitae tincidunt pellentesque, pretium sit amet dui. Duis aliquet ultrices lacus eget efficitur. Ut imperdiet velit sed enim laoreet, sed semper libero hendrerit. Donec malesuada auctor sollicitudin.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc diam magna, molestie sit amet auctor nec, dictum quis mi. Duis pellentesque lacinia pretium. Donec pulvinar, risus sit amet dapibus mattis, eros urna bibendum elit, vel mollis sapien arcu
vitae mi. Fusce vulputate vestibulum metus dapibus eleifend. Quisque ut dictum orci. Nunc bibendum, sapien ac condimentum placerat, arcu orci mollis nunc, vitae sollicitudin arcu nulla quis enim. Praesent non tellus vitae quam tempor maximus vel sed
dolor. Donec id ante ultricies, iaculis sem ut, sollicitudin enim. Quisque id mauris est. Maecenas viverra urna vitae velit semper, vel ultricies augue feugiat. Pellentesque in libero porttitor, lacinia metus in, maximus nisi. Phasellus commodo ligula
vel arcu iaculis hendrerit vitae vel diam. Sed sed lorem maximus, vestibulum leo ut, posuere libero. Donec arcu dui, euismod id aliquet sed, porttitor vitae elit.</p>
<p>Sed aliquam eget justo sit amet dictum. Suspendisse potenti. In placerat orci quis vehicula vehicula. Proin tempor laoreet suscipit. Proin non nulla lacinia est ullamcorper maximus et a sem. Nulla at lacus rhoncus, malesuada ante in, imperdiet sem.
Mauris convallis tristique metus in iaculis. Nulla laoreet ligula non interdum tincidunt. Morbi sed venenatis arcu, sed gravida est. Fusce malesuada ullamcorper lacus, in vulputate risus finibus non.</p>
<p>Suspendisse sapien leo, auctor non ex vitae, volutpat laoreet tortor. Suspendisse sodales libero velit, sed pulvinar lectus feugiat vel. Sed erat eros, porttitor id enim nec, ornare hendrerit nibh. Phasellus at nisi lectus. Cras semper lobortis condimentum.
Etiam nunc felis, vehicula vitae tincidunt pellentesque, pretium sit amet dui. Duis aliquet ultrices lacus eget efficitur. Ut imperdiet velit sed enim laoreet, sed semper libero hendrerit. Donec malesuada auctor sollicitudin.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc diam magna, molestie sit amet auctor nec, dictum quis mi. Duis pellentesque lacinia pretium. Donec pulvinar, risus sit amet dapibus mattis, eros urna bibendum elit, vel mollis sapien arcu
vitae mi. Fusce vulputate vestibulum metus dapibus eleifend. Quisque ut dictum orci. Nunc bibendum, sapien ac condimentum placerat, arcu orci mollis nunc, vitae sollicitudin arcu nulla quis enim. Praesent non tellus vitae quam tempor maximus vel sed
dolor. Donec id ante ultricies, iaculis sem ut, sollicitudin enim. Quisque id mauris est. Maecenas viverra urna vitae velit semper, vel ultricies augue feugiat. Pellentesque in libero porttitor, lacinia metus in, maximus nisi. Phasellus commodo ligula
vel arcu iaculis hendrerit vitae vel diam. Sed sed lorem maximus, vestibulum leo ut, posuere libero. Donec arcu dui, euismod id aliquet sed, porttitor vitae elit.</p>
<p>Sed aliquam eget justo sit amet dictum. Suspendisse potenti. In placerat orci quis vehicula vehicula. Proin tempor laoreet suscipit. Proin non nulla lacinia est ullamcorper maximus et a sem. Nulla at lacus rhoncus, malesuada ante in, imperdiet sem.
Mauris convallis tristique metus in iaculis. Nulla laoreet ligula non interdum tincidunt. Morbi sed venenatis arcu, sed gravida est. Fusce malesuada ullamcorper lacus, in vulputate risus finibus non.</p>
<p>Suspendisse sapien leo, auctor non ex vitae, volutpat laoreet tortor. Suspendisse sodales libero velit, sed pulvinar lectus feugiat vel. Sed erat eros, porttitor id enim nec, ornare hendrerit nibh. Phasellus at nisi lectus. Cras semper lobortis condimentum.
Etiam nunc felis, vehicula vitae tincidunt pellentesque, pretium sit amet dui. Duis aliquet ultrices lacus eget efficitur. Ut imperdiet velit sed enim laoreet, sed semper libero hendrerit. Donec malesuada auctor sollicitudin.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc diam magna, molestie sit amet auctor nec, dictum quis mi. Duis pellentesque lacinia pretium. Donec pulvinar, risus sit amet dapibus mattis, eros urna bibendum elit, vel mollis sapien arcu
vitae mi. Fusce vulputate vestibulum metus dapibus eleifend. Quisque ut dictum orci. Nunc bibendum, sapien ac condimentum placerat, arcu orci mollis nunc, vitae sollicitudin arcu nulla quis enim. Praesent non tellus vitae quam tempor maximus vel sed
dolor. Donec id ante ultricies, iaculis sem ut, sollicitudin enim. Quisque id mauris est. Maecenas viverra urna vitae velit semper, vel ultricies augue feugiat. Pellentesque in libero porttitor, lacinia metus in, maximus nisi. Phasellus commodo ligula
vel arcu iaculis hendrerit vitae vel diam. Sed sed lorem maximus, vestibulum leo ut, posuere libero. Donec arcu dui, euismod id aliquet sed, porttitor vitae elit.</p>
<p>Sed aliquam eget justo sit amet dictum. Suspendisse potenti. In placerat orci quis vehicula vehicula. Proin tempor laoreet suscipit. Proin non nulla lacinia est ullamcorper maximus et a sem. Nulla at lacus rhoncus, malesuada ante in, imperdiet sem.
Mauris convallis tristique metus in iaculis. Nulla laoreet ligula non interdum tincidunt. Morbi sed venenatis arcu, sed gravida est. Fusce malesuada ullamcorper lacus, in vulputate risus finibus non.</p>
<p>Suspendisse sapien leo, auctor non ex vitae, volutpat laoreet tortor. Suspendisse sodales libero velit, sed pulvinar lectus feugiat vel. Sed erat eros, porttitor id enim nec, ornare hendrerit nibh. Phasellus at nisi lectus. Cras semper lobortis condimentum.
Etiam nunc felis, vehicula vitae tincidunt pellentesque, pretium sit amet dui. Duis aliquet ultrices lacus eget efficitur. Ut imperdiet velit sed enim laoreet, sed semper libero hendrerit. Donec malesuada auctor sollicitudin.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc diam magna, molestie sit amet auctor nec, dictum quis mi. Duis pellentesque lacinia pretium. Donec pulvinar, risus sit amet dapibus mattis, eros urna bibendum elit, vel mollis sapien arcu
vitae mi. Fusce vulputate vestibulum metus dapibus eleifend. Quisque ut dictum orci. Nunc bibendum, sapien ac condimentum placerat, arcu orci mollis nunc, vitae sollicitudin arcu nulla quis enim. Praesent non tellus vitae quam tempor maximus vel sed
dolor. Donec id ante ultricies, iaculis sem ut, sollicitudin enim. Quisque id mauris est. Maecenas viverra urna vitae velit semper, vel ultricies augue feugiat. Pellentesque in libero porttitor, lacinia metus in, maximus nisi. Phasellus commodo ligula
vel arcu iaculis hendrerit vitae vel diam. Sed sed lorem maximus, vestibulum leo ut, posuere libero. Donec arcu dui, euismod id aliquet sed, porttitor vitae elit.</p>
<p>Sed aliquam eget justo sit amet dictum. Suspendisse potenti. In placerat orci quis vehicula vehicula. Proin tempor laoreet suscipit. Proin non nulla lacinia est ullamcorper maximus et a sem. Nulla at lacus rhoncus, malesuada ante in, imperdiet sem.
Mauris convallis tristique metus in iaculis. Nulla laoreet ligula non interdum tincidunt. Morbi sed venenatis arcu, sed gravida est. Fusce malesuada ullamcorper lacus, in vulputate risus finibus non.</p>
<p>Suspendisse sapien leo, auctor non ex vitae, volutpat laoreet tortor. Suspendisse sodales libero velit, sed pulvinar lectus feugiat vel. Sed erat eros, porttitor id enim nec, ornare hendrerit nibh. Phasellus at nisi lectus. Cras semper lobortis condimentum.
Etiam nunc felis, vehicula vitae tincidunt pellentesque, pretium sit amet dui. Duis aliquet ultrices lacus eget efficitur. Ut imperdiet velit sed enim laoreet, sed semper libero hendrerit. Donec malesuada auctor sollicitudin.</p>
</div>
运行代码片段Hide results
展开片段