javascript 如何在不使用 jQuery 的情况下创建一个简单的页面垂直滚动条?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27322881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I create a simple page vertical scroll bar without using jQuery?
提问by Samantha J T Star
I have looked at I think all the scrollbars code but have not yet been able to find a simple one that does not use jQuery or a somewhat complex library.
我看过我认为所有的滚动条代码,但还没有找到一个不使用 jQuery 或有点复杂的库的简单代码。
Has anyone created there own simple scrollbar using just Javascript? What I am looking for is an example of how this can be done. In particular I have a simple Bootstrap web page with:
有没有人只使用 Javascript 创建过自己的简单滚动条?我正在寻找的是如何做到这一点的一个例子。特别是我有一个简单的 Bootstrap 网页,其中包含:
<body>
<header> ....</header>
<main> ......</main>
</body>
What I would like to do is to be able to have a small in page scroll bar appear to the right of the <main>
area if the content there is larger than will fit on a single page. For styling purposes I would like this notto be the browser default scroll bar.
我想要做的是,<main>
如果该区域的内容大于单个页面的大小,则能够在该区域的右侧显示一个小的页面滚动条。出于样式目的,我希望这不是浏览器默认滚动条。
Here's an example of what I am looking for but this one does use jQuery so I cannot use it on my site:
这是我正在寻找的一个例子,但这个例子确实使用了 jQuery,所以我不能在我的网站上使用它:
http://manos.malihu.gr/repository/custom-scrollbar/demo/examples/complete_examples.html
http://manos.malihu.gr/repository/custom-scrollbar/demo/examples/complete_examples.html
I am looking for some way to do this using Javascript in a modern browser IE9 and above. As I think this would be useful for many people I have opened up a bounty of 200 for this in the hope that someone could provide a good example of a draggable page scrollbar that also would respond to the mousewheel when over the page content area.
我正在寻找在现代浏览器 IE9 及更高版本中使用 Javascript 的某种方法。因为我认为这对许多人有用,所以我为此开放了 200 的赏金,希望有人可以提供一个可拖动页面滚动条的好例子,该滚动条在页面内容区域上也会响应鼠标滚轮。
Just an update. I am not looking for a mobile solution for this. I am just looking for a solution that would work inside a PC / Mac browser. The site is not set up or suitable for a phone. It's possible to use on an IPad / tablet but for those needs I would like to be able to have the scrollbar default to use just the normal tablet scrolling method.
只是一个更新。我不是在为此寻找移动解决方案。我只是在寻找一种可以在 PC/Mac 浏览器中运行的解决方案。该站点未设置或不适合手机。可以在 iPad / 平板电脑上使用,但对于这些需求,我希望能够让滚动条默认使用普通平板电脑滚动方法。
回答by AdamSchuld
Surprisingly, there is not a great, simple solution out there using vanilla JavaScript. I made a pure JS lightweight, minimal cross browser solution. Adjust to your own needs and aesthetics
令人惊讶的是,没有使用 vanilla JavaScript 的出色、简单的解决方案。我做了一个纯 JS 轻量级的、最小的跨浏览器解决方案。根据您自己的需求和审美进行调整
*Update 2019
The W3C has a working document that is on standards track to improve this out of the box through the css specification. Although limiting, if you want to use cutting edge css you can now style your scroll bars through the scrollbar-color
and scrollbar-width
. For more information please check https://drafts.csswg.org/css-scrollbars/
* 2019 年更新
W3C 有一份工作文档,该文档正处于标准轨道上,可通过 css 规范开箱即用地改进这一点。尽管有限制,但如果您想使用尖端的 css,您现在可以通过scrollbar-color
和来设置滚动条的样式scrollbar-width
。有关更多信息,请查看https://drafts.csswg.org/css-scrollbars/
Examples:
Here is the fiddleand CodePen
HTML
HTML
<body>
<div id="main" class="scrollable">
<div class="content-wrapper">
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Incidunt accusamus maxime voluptatem quasi. Recusandae optio nobis ratione iste consectetur consequatur cupiditate saepe laborum natus neque a provident eum explicabo delectus qui accusantium nostrum reiciendis soluta hic ut at sed laboriosam possimus repudiandae deserunt velit rerum. Aliquam ratione itaque corrupti aperiam quisquam unde aspernatur odio id repellendus corporis eaque expedita in ab minus possimus! Quo tempore consequatur repellat consectetur nemo molestiae perferendis ipsum esse nesciunt blanditiis nobis dicta? Laudantium quaerat inventore deleniti exercitationem explicabo quos pariatur sunt earum labore sed eius blanditiis architecto consequuntur ad consectetur unde sapiente nisi. Sunt eos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Incidunt accusamus maxime voluptatem quasi. Recusandae optio nobis ratione iste consectetur consequatur cupiditate saepe laborum natus neque a provident eum explicabo delectus qui accusantium nostrum reiciendis soluta hic ut at sed laboriosam possimus repudiandae deserunt velit rerum. Aliquam ratione itaque corrupti aperiam quisquam unde aspernatur odio id repellendus corporis eaque expedita in ab minus possimus! Quo tempore consequatur repellat consectetur nemo molestiae perferendis ipsum esse nesciunt blanditiis nobis dicta? Laudantium quaerat inventore deleniti exercitationem explicabo quos pariatur sunt earum labore sed eius blanditiis architecto consequuntur ad consectetur unde sapiente nisi. Sunt eos.</p>
</div>
</div>
</div>
<div>Not special and not contained within scrolling</div>
</body>
CSS
CSS
.scrollable {
padding: 0% 10%;
position: relative;
border: 1px solid gray;
overflow: hidden;
height: 400px;
}
.scrollable.showScroll::after {
position: absolute;
content: '';
top: 5%;
right: 7px;
height: 90%;
width: 3px;
background: rgba(224, 224, 255, .3);
}
.scrollable .content-wrapper {
width: 100%;
height: 100%;
padding-right: 50%;
overflow-y: scroll;
}
.scroller {
z-index: 5;
cursor: pointer;
position: absolute;
width: 10px;
border-radius: 5px;
background: rgb(111, 111, 190);
top: 0px;
right: 3px;
-webkit-transition: top .08s;
-moz-transition: top .08s;
-ms-transition: top .08s;
-o-transition: top .08s;
transition: top .08s;
}
.content {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
JS
JS
(function () {
var scrollContainer = document.querySelector('.scrollable'),
scrollContentWrapper = document.querySelector('.scrollable .content-wrapper'),
scrollContent = document.querySelector('.scrollable .content'),
contentPosition = 0,
scrollerBeingDragged = false,
scroller,
topPosition,
scrollerHeight;
function calculateScrollerHeight() {
// *Calculation of how tall scroller should be
var visibleRatio = scrollContainer.offsetHeight / scrollContentWrapper.scrollHeight;
return visibleRatio * scrollContainer.offsetHeight;
}
function moveScroller(evt) {
// Move Scroll bar to top offset
var scrollPercentage = evt.target.scrollTop / scrollContentWrapper.scrollHeight;
topPosition = scrollPercentage * (scrollContainer.offsetHeight - 5); // 5px arbitrary offset so scroll bar doesn't move too far beyond content wrapper bounding box
scroller.style.top = topPosition + 'px';
}
function startDrag(evt) {
normalizedPosition = evt.pageY;
contentPosition = scrollContentWrapper.scrollTop;
scrollerBeingDragged = true;
}
function stopDrag(evt) {
scrollerBeingDragged = false;
}
function scrollBarScroll(evt) {
if (scrollerBeingDragged === true) {
var mouseDifferential = evt.pageY - normalizedPosition;
var scrollEquivalent = mouseDifferential * (scrollContentWrapper.scrollHeight / scrollContainer.offsetHeight);
scrollContentWrapper.scrollTop = contentPosition + scrollEquivalent;
}
}
function createScroller() {
// *Creates scroller element and appends to '.scrollable' div
// create scroller element
scroller = document.createElement("div");
scroller.className = 'scroller';
// determine how big scroller should be based on content
scrollerHeight = calculateScrollerHeight();
if (scrollerHeight / scrollContainer.offsetHeight < 1){
// *If there is a need to have scroll bar based on content size
scroller.style.height = scrollerHeight + 'px';
// append scroller to scrollContainer div
scrollContainer.appendChild(scroller);
// show scroll path divot
scrollContainer.className += ' showScroll';
// attach related draggable listeners
scroller.addEventListener('mousedown', startDrag);
window.addEventListener('mouseup', stopDrag);
window.addEventListener('mousemove', scrollBarScroll)
}
}
createScroller();
// *** Listeners ***
scrollContentWrapper.addEventListener('scroll', moveScroller);
}());
The concept is simple. We have a main div with a 'scrollable' class. The JavaScript recognizes this element and appends a scroller div that you can style yourself with CSS. By nesting the content-wrapper child div we can effectively push the native scroller outside of the parent div while still controlling padding.
这个概念很简单。我们有一个带有“可滚动”类的主 div。JavaScript 识别此元素并附加一个滚动条 div,您可以使用 CSS 设置自己的样式。通过嵌套 content-wrapper 子 div,我们可以有效地将原生滚动条推到父 div 之外,同时仍然控制填充。
Here is a diagram:
这是一个图表:
The reason we need to maintain native scrolling ability is because the JavaScript scroll event only fires on elements that have overflow set to scroll. See MDN reference on scroll. The benefit being that if JS is disabled, we will still gracefully fallback to scrolling without a scrollbar.
我们需要保持原生滚动能力的原因是因为 JavaScript 滚动事件只在溢出设置为滚动的元素上触发。请参阅关于滚动的 MDN 参考。好处是如果 JS 被禁用,我们仍然会优雅地回退到没有滚动条的滚动。
NOTE
You should note that you will have to adjust your version to recalculate the scroller size in certain cases:
1.) Where the screen is resized or
2.) If more content is appended.
注意
您应该注意,在某些情况下,您必须调整您的版本以重新计算滚动条大小:
1.) 调整屏幕大小的位置或
2.) 如果附加了更多内容。
Secondly, modifications will have to be made if you have multiple 'scrollable' elements. In this case, you will need to loop over those elements to both append a scroller div and listen for the scroll event.
其次,如果您有多个“可滚动”元素,则必须进行修改。在这种情况下,您需要遍历这些元素以附加滚动 div 并侦听滚动事件。
回答by Buzinas
I know that there is already an answer to this question, but as soon as the OP wanted a simple vanilla javascript solution, that works on modern browsers - and I think that more people would probably need that too, I'll be late answering this question here, because I've developed a very simple and lightweight library in pure vanilla JS(DEMO), and it's only 1KB after gzipping and minification.
我知道这个问题已经有了答案,但是一旦 OP 想要一个简单的 vanilla javascript 解决方案,它适用于现代浏览器 - 我认为更多的人可能也需要它,我会迟到回答这个问题在这里,因为我已经用纯香草 JS( DEMO)开发了一个非常简单和轻量级的库,并且在 gzip 和缩小后它只有 1KB。
It uses the native scroll, so it works on all the modern browsers (Firefox, Chrome, Opera, Safari, Edge), and on IE10 and IE11. You can also use it in IE9 by including a classList polyfill.
它使用本机滚动,因此适用于所有现代浏览器(Firefox、Chrome、Opera、Safari、Edge)以及 IE10 和 IE11。您还可以通过包含 classList polyfill 在 IE9 中使用它。
All Android, iOS and Windows Phone browsers are supported either.
也支持所有 Android、iOS 和 Windows Phone 浏览器。
See a more detailed answer here: Custom scrollbars
在此处查看更详细的答案:自定义滚动条
Or read the full tutorial in the SimpleScrollbar's Github README page.
或者阅读SimpleScrollbar 的 Github README 页面中的完整教程。
回答by Glen Swift
There is an awesome baron.js library. It can be user with jQuery or without it as well. The idea is exactly the same that @AdamSchuld describe in his answer.
有一个很棒的baron.js 库。它可以是使用 jQuery 或不使用 jQuery 的用户。这个想法与@AdamSchuld 在他的回答中描述的完全相同。
Its advantages:
它的优点:
Doesn't replace native system scroll mechanic (it is important when you want your scrollbar to look customized but save original platform or device behavior).
Customizable scrollbar design with full CSS support.
No strong dependencies on jQuery.
Plugin system (fixable headers, sticky footer, autotests and more)
Can be inited on hidden blocks
不替换本机系统滚动机制(当您希望滚动条看起来自定义但保存原始平台或设备行为时,这一点很重要)。
具有完整 CSS 支持的可定制滚动条设计。
对 jQuery 没有很强的依赖。
插件系统(可修复的页眉、粘性页脚、自动测试等)
可以在隐藏块上初始化
Here is simple demo of it.
这是它的简单演示。