首先,我们要明白我们这次所要完成的功能有三个:
第一:设置一个触发元素,当这个元素触发时可以出现遮罩层;
第二:遮罩层中间部分可以拿来显示新的内容;
第三:当遮罩层触发后,在指定区域触发滚轮事件,从而可以用滚轮来控制上下浏览;
我们先来满足第一个功能:
设置一个触发元素,我们可以利用a标签点击触发。然后我们需要用一个div来制作遮罩层,当然,遮罩层打开之后肯定还需要可以关闭的,所以在遮罩层div里加入一个button按钮,方便关闭。
之后我们要考虑到,遮罩层平时肯定是看不到的,需要触发后才看得到,关闭之后又看不到了。所以在未触发遮罩层之前,我们把遮罩层和遮罩层所显示的内容设置为不可见,触发之后设置为可见,关闭之后又设置为不可见。
所以在遮罩层的css样式在未触发前应设为display:none;触发后设置为display:block;关闭遮罩层后又变为display:none;
而显示内容的div的css样式在未触发前应设为visibility:hidden;触发后设置为visibility:visible;关闭遮罩层后又变为visibility:hidden;
然后我们来满足第二个功能,遮罩层中间部分可以拿来显示新的内容,这一部分只需要在html中输入内容,css中改变样式,最后别忘了在最外层div加入visibility:hidden;即可
然后我们来满足第三个功能,这也是这次最为核心最为复杂的一个部分了
在这个部分里面我们又要进行思考,遮罩层触发后,在所显示内容区域,一里面包含内容和滚动条。
我们先来考虑内容,内容需要一个div来包裹,即设置了visibility:hidden;那个div。然后还需要一个视窗div,因为内容肯定很长很长,不可能把内容全部展现出来,这样不太美观也不太方便,所以需要设置一个视窗div来随着每次滚动滚轮获取新的内容,不会把浏览器页面扩展的很长很长。
最后还需要一个内容div,就是在内容div里随便写很多想写的内容啦,很长很长都行,因为能显示出来的内容只有视窗div那么大,若需要获取其他内容,则需要滚动滚轮来触发事件。
再来考虑一下滚动条,滚动条高度肯定要和视窗div高度一样,滚动条里的滚动块所在位置可以显示当前在视窗div中所浏览的内容是在内容div的哪个部分。之后需要给滚动条和滚动块设置不同的背景以便区分,然后滚动块给一个合适的高度,当然肯定不可能比滚动条的长度还高撒。
然后整理一下我们所需要的数据,
展示内容的区域(滚轮事件在这里面才可以触发);
视窗div的高度;
内容div的高度;
滚动条的高度;
滚动块;
接下来要判断,内容div里面的内容够不够视窗div显示,即内容div高度大于和小于视窗div高度的两种情况下滚动块应该是多长。
当内容div高度<视窗div高度,即内容不长,能在当前视窗div完全浏览完:滚动块长度等于滚动条长度
当内容div高度>视窗div高度,即内容超出当前视窗div:滚动块长度=(视窗div高/内容div高)*滚动条高,如果不好理解可以这样想:根据等比关系,滚动块长:滚动条高=视窗div高:内容div高
之后应该绑定事件,即设置在什么地方触发滚轮事件,若考虑充分点,还应考虑各种浏览器的兼容问题
触发的滚轮事件,肯定有往上滚和往下滚两种情况,所以还需要再滚轮事件触发后判断是往上滚还是往下滚
当往下滚时,需要考虑每次滚动后滚动块距离滚动条顶部的距离,同时,内容div里的内容应该是往上移动(因为未显示的内容肯定要往上移动到视窗div来显示呀)
你以为这就完了?nonono,当滚动块滚动到底部之后,内容div的内容应该不会再往上移动了,滚动块所在位置也不会变,若滚动块未滚动到底部,那么滚动块离滚动条的顶部的距离应该是当前离顶部的距离加上一个速度变量
内容div离顶部的距离应该是根据滚动条等比换算而来的,即内容div离顶部的位置:内容div高-视窗高=滚动块离滚动条顶部的位置:滚动条高-滚动块高,最后要注意内容div是向上移动哦,所以要别忘记取反。
当往上滚时,若滚动块已经达到了顶部,则滚动块离顶部位置应变为0,内容div离顶部位置也应该变为0,若还未到达顶部,则滚动块离顶部位置应该是滚动块当前离顶部位置减去一个速度变量
内容div离顶部距离也可以这样推导出来,内容div离顶部距离:内容div高-视窗div高=滚动块当前离顶部距离:滚动条高-滚动块当前高;最后要注意内容div这个时候是该往下移动噢,所以div离顶部距离的值应该一直为正,但是由于之前先往下滚动了,所以此时div离顶部距离的值为负,所以仍需,让它再平衡过来。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>title>
<style>
*{
padding: 0;
margin: 0;
}
body{
/*这些背景图不用在意,主要为了能查看区域大小*/
background-image:url(67.jpg);
background-size: cover;
}
.wrapper{
position: absolute;
left: 50%;
top:50%;
transform: translate(-50%,-50%);
width: 800px;
height: 700px;
border: 1px solid #000;
background-image: url(64.jpg);
background-size:cover;
visibility: hidden;
}
.view_box{
position: absolute;
left: 100px;
top:50%;
transform: translateY(-50%);
width:600px;
height: 500px;
overflow: hidden;
}
.content{
position: absolute;
top: 0;
width: 100%;
background-color: rgba(0,0,0,0.6);
}
.content div{
height: 100px;
color:white;
width:100%;
}
.bar_box{
position: absolute;
right: 90px;
top:50%;
transform: translateY(-50%);
height: 500px;
width: 4px;
border-radius: 2px;
background-color: rgba(25, 25, 25,.7);
overflow:hidden;
}
.bar{
position: absolute;
top:0;
height: 20px;
width: 100%;
border-radius:2px;
background-color: rgb(197, 179, 179);
}
.mask{
width: 100%;
height: 100%;
position: fixed;
top:0;
left: 0;
display:none;
background-color: rgba(0, 0, 0, 0.6);
}
.mask button{
position: absolute;
top:1em;
right:1em;
font-size:2em;
color:white;
background-color: transparent;
border:none;
outline: none;
cursor: pointer;
}
style>
head>
<body>
<a id="a" style="color:white;cursor:pointer;">点击我触发遮罩层a>
<div class="mask" id="mask">
<button id="close">点击我关闭遮罩层button>
div>
<script>
var a = document.getElementById("a");
var mask = document.getElementById("mask");
a.onclick = function(){
mask.style.display = "block";
wrapper.style.visibility="visible";
}
//document.onclick就是给页面添加点击事件。
document.onclick = function(event){
event = event || window.event;
//兼容获取触动事件时被传递过来的对象,event.srcElement是IE中的用法,event.target是非IE中的用法。target 事件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口。
var aaa =event.target?event.target:event.srcElement;
if (aaa.id == "close"){
mask.style.display = "none";
wrapper.style.visibility="hidden";
}
}
<!--这是滚轮控制内容浏览的js代码-->
script>
<div id="wrapper" class="wrapper">
<div id="view_box" class="view_box">
<div id="content" class="content">
//下面个video可以无视,只是在写的时候在内容区嵌入了一个mp4
<div>这是内容div>
<div>这是内容div>
<p align="center">
<video src="2.mp4" controls style="max-width:90%; border:2px solid white;box-shadow: 0 0 1em #D1EEEE;">
video>
p>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
<div>这是内容div>
div>
div>
<div id="bar_box" class="bar_box">
<div id="bar" class="bar">div>
div>
div>
<script>
var wrapper = document.getElementById('wrapper');
var view_box = document.getElementById('view_box');
var view_box_height = view_box.offsetHeight;
var content = document.getElementById('content');
var content_height = content.offsetHeight;
var bar_box = document.getElementById('bar_box');
var bar_box_height = bar_box.offsetHeight;
var bar = document.getElementById('bar');
if(view_box_height / content_height < 1) {
bar.style.height = (view_box_height / content_height) * bar_box_height + 'px';
} else {
bar.style.height = bar_box_height + 'px';
}
//绑定事件(做兼容处理)
wrapper.onmousewheel = function (e){
// e.wheelDelta < 0 向下
// e.wheelDelta > 0 向上
scrollRoll(e);
//阻止浏览器默认事件,主要是防止遮罩层里的内容滚动时,浏览器滚动条也跟着滚动
e.preventDefault()
}
//兼容 Firefox
wrapper.addEventListener('DOMMouseScroll',function (e) {
// e.detail > 0 滑轮向下滚动
// e.detail < 0 滑轮向上滚动
scrollRoll(e);
e.preventDefault()
},false)
function scrollRoll (e) {
e = e || window.event;
if (e.detail > 0) {
down();
} else if (e.detail < 0) {
up();
}
if (e.wheelDelta > 0) {
up();
} else if (e.wheelDelta < 0) {
down();
}
}
function down () {
var speed = 8;
if (bar.offsetTop >= bar_box_height - bar.offsetHeight) {
bar.style.top = bar_box_height - bar.offsetHeight + 'px';
//注意:内容区应该向上移动
content.style.top = - (content_height - view_box_height) + 'px';
} else {
bar.style.top = bar.offsetTop + speed + 'px';
content.style.top = - bar.offsetTop / (bar_box_height - bar.offsetHeight) * (content_height - view_box_height) + 'px';
}
}
function up () {
var speed = 8;
if (bar.offsetTop <= 0) {
bar.style.top = 0 + 'px';
content.style.top = 0 + 'px';
} else {
bar.style.top = bar.offsetTop - speed + 'px';
content.style.top = - bar.offsetTop / (bar_box_height - bar.offsetHeight) * (content_height - view_box_height) + 'px';
}
}
script>
body>
html>