HTML普通元素
- offsetTop: 元素相对于其包含块顶部的垂直偏移量。 影响他的是绝对定位top和其他元素对其造成的影响
- offsetLeft: 元素相对于其包含块左侧的水平偏移量。影响他的是绝对定位left
- offsetWidth: 元素的总宽度,包括边框、内边距和滚动条。不会被transform影响
- offsetHeight: 元素的总高度,包括边框、内边距和滚动条。不会被transform影响
- scrollTop: 元素内容被垂直滚动的像素数。只有在overflow不为hidden且元素滚动条生效时改变,下面属性一样
- scrollLeft: 元素内容被水平滚动的像素数。
这里插播两个小代码,用于求出滚动条顶部距离和底部距离的:
// 滚动条距离底部的距离
scrollBottom = Math.abs(Math.ceil(e.target.scrollHeight-e.target.offsetHeight+(e.target.offsetHeight-e.target.clientHeight)-e.target.scrollTop);
// 滚动条距离顶部的距离
scrollTop = Math.abs(Math.floor(e.target.scrollTop))
- scrollWidth:元素的内容宽度,包括溢出部分。 不管溢出是否可见都算到宽度里,高度同理
- scrollHeight: 元素的内容高度,包括溢出部分。
- clientTop: 元素上边框的宽度。对boder-top生效,outline不生效
- clientLeft: 元素左边框的宽度。 对boder-left生效,outline不生效
- clientWidth: 元素的内部宽度,不包括边框和滚动条。
- clientHeight: 元素的内部高度,不包括边框和滚动条。
screen元素
- width: 屏幕的宽度。只要你不调整分辨率,width的值是固定的
- height: 屏幕的高度。同上
- availWidth: 屏幕可用的宽度(单位:像素),减去诸如任务栏之类的界面 元素占据的空间。
- availHeight: 屏幕可用的高度(单位:像素),减去诸如任务栏之类的界面元素占据的空间。
- colorDepth: 屏幕的颜色深度(单位:位)。
- pixelDepth: 屏幕的像素深度(单位:位)。
wheel事件
- clientX: 鼠标指针在可视区域内的水平坐标。
- clientY: 鼠标指针在可视区域内的垂直坐标。
- layerX: 鼠标指针相对于触发事件的容器内部的水平坐标。
- layerY: 鼠标指针相对于触发事件的容器内部的垂直坐标。
- offsetX: 鼠标指针相对于触发事件的容器内部子元素的水平坐标,不受 CSS 定位影响。
- offsetY: 鼠标指针相对于触发事件的容器内部子元素的垂直坐标,不受 CSS 定位影响。
- pageX: 鼠标指针相对于整个文档的水平坐标。(没看出和clientX什么区别至少是你的容器始终在可视区域内时)
- pageY: 鼠标指针相对于整个文档的垂直坐标。(没看出和clientY什么区别至少是你的容器始终在可视区域内时)
- screenX: 鼠标指针相对于整个屏幕(鼠标的偏移位置需要加上什么工具栏、开发面板…一些枸杞猫吧的东西)的水平坐标。
- screenY: 鼠标指针相对于整个屏幕(鼠标的偏移位置需要加上什么任务栏、浏览器导航栏、收藏栏…一些枸杞猫吧的东西)的垂直坐标。
window元素
- innerWidth: window 对象的内部宽度(可视宽度,不包括滚动条、开发者面板)。
- innerHeight: window 对象的内部高度(可视高度,不包括滚动条、开发者面板)。
- outerWidth: window 对象的外部宽度(包括浏览器窗口的所有界面元素,如工具栏、滚动条等)。
- outerHeight: window 对象的外部高度(包括浏览器窗口的所有界面元素,如工具栏、滚动条等)。
- pageXOffset: 当前页面的水平滚动偏移量(等同于 scrollX)。
- pageYOffset: 当前页面的垂直滚动偏移量(等同于 scrollY)。
- screenX: window 对象(整个浏览器窗口)或事件相对于屏幕左边缘的水平偏移量。
- screenY: window 对象(整个浏览器窗口)或事件相对于屏幕上边缘的垂直偏移量。
- screenLeft: 只是整个浏览器窗口相对于屏幕左边缘的水平偏移量。
- screenTop: 只是整个浏览器窗口相对于屏幕上边缘的垂直偏移量。
mouse元素
- screenX: 鼠标指针相对于屏幕左边缘的水平坐标。
- screenY: 鼠标指针相对于屏幕上边缘的垂直坐标。
- clientX: 鼠标指针相对可视区域(能看见的区域宽度)左边缘的水平坐标。
- clientY: 鼠标指针相可视区域(能看见的区域高度)上边缘的垂直坐标。
- pageX: 鼠标指针相对于整个文档(包括溢出内容)左边缘的水平坐标(包括垂直滚动的偏移量)。
- pageY: 鼠标指针相对于整个文档(包括溢出内容)上边缘的垂直坐标(包括水平滚动的偏移量)。
- offsetX: 鼠标指针相对于事件目标元素左边缘的水平坐标。鼠标指针在目标元素内部的水平位置
- offsetY: 鼠标指针相对于事件目标元素上边缘的垂直坐标。鼠标指针在目标元素内部的垂直位置
- movementX: 上一个 mousemove 事件到当前事件之间,鼠标指针在水平位置上的移动距离。
- movementY: 上一个 mousemove 事件到当前事件之间,鼠标指针在垂直位置上的移动距离。
Demo1——自定义滚动条
源码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.test {
position: relative;
width: 1000px;
height: 400px;
background-color: aquamarine;
overflow: auto;
scrollbar-width: none;
}
</style>
</head>
<body>
<div class="main">
<div class="test">
<div style="height: 5000px;">1231232</div>
</div>
<div class="control" style="position:absolute; top: 360px;left: 0;">
<img id="people" style="width: 30px;" src="../img/1.png" alt="">
</div>
</div>
<div id="text"></div>
<script>
let a = document.querySelector(".test");
let p = document.querySelector("#people");
let c = document.querySelector(".control")
let togglePeople = true;
let interval = 10; // 定义滚动间隔
let lastTogglePosition = 0; // 记录上一次切换 togglePeople 的位置
a.addEventListener("scroll", function (e) {
let set = (e.target.scrollWidth - c.scrollWidth) * Math.abs(Math.floor(e.target.scrollTop)) / (e.target.scrollHeight - e.target.clientHeight)
// 将竖直滚动条的滚动位置换算成小人在元素水平上的偏移位置
c.style.left = set + 'px'
if (set - lastTogglePosition >= interval) {
togglePeople = !togglePeople;
lastTogglePosition = set; // 更新上一次记录的位置
}
if(set === 0 || e.target.scrollTop === 0){
lastTogglePosition = 0
}
if (togglePeople) {
p.setAttribute('src', '../img/2.png')
} else {
p.setAttribute('src', '../img/1.png')
}
})
</script>
</body>
</html>
Demo2——自定义滚动条(结合Linis实现平滑滚动)
源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
}
.container {
position: relative;
display: flex;
flex-direction: row-reverse;
height: 800px;
width: 800px;
background-color: rgb(255, 255, 255);
overflow: hidden;
box-shadow: 1px 1px 5px 0px rgba(0, 0, 0, 0.474);
}
.scroll-x {
flex: 8;
height: 100%;
overflow-y: auto;
scrollbar-width: none;
padding: 10px 10px;
box-sizing: border-box;
}
.scroll-diy {
position: relative;
height: 100%;
min-width: 100px;
flex: 2;
}
.diy-top,
.diy-bottom {
position: absolute;
width: 100%;
transition: bottom 0.3s;
}
.diy-top {
display: flex;
top: 0;
right: 0;
height: 88px;
flex-direction: column;
transition: all .1s ease-out;
}
.shengzi{
width: 100%;
background-image: url("../images/只有绳子.png");
background-size: 100%;
flex: 1;
}
.diy-bottom {
bottom: 0;
right: 0;
}
.diy-top img,
.diy-bottom img {
width: 100%;
}
.lang-content p:nth-child(odd) {
background-color: #f5f5f586;
line-height: 30px;
margin: 0px;
}
.lang-content p:nth-child(even) {
background-color: #ffc2c286;
line-height: 30px;
margin: 0px;
}
</style>
</head>
<body>
<!-- 滚动区域最外层盒 -->
<div class="container">
<!-- 自定义滚动条 -->
<div class="scroll-diy">
<!-- 救人 -->
<div class="diy-top">
<div class="shengzi"></div>
<img src="../images/绳子-top.png" alt="">
</div>
<!-- 被救者 -->
<div class="diy-bottom">
<img src="../images/绳子-bottom.png" alt="">
</div>
</div>
<!-- 滚动容器 -->
<div class="scroll-x">
<!-- 很高很高的内容的开始 -->
<!-- 这个区域可以换成任意一个具有高的元素 -->
<div class="lang-content">
<p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p>
</div>
<div class="lang-content">
<p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p><p>1</p><p>2</p><p>3</p><p>4</p><p>5</p><p>6</p><p>7</p><p>8</p><p>9</p><p>10</p><p>11</p>
</div>
<!-- 很高很高的内容的结尾 -->
</div>
</div>
<script src="https://unpkg.com/lenis@1.1.9/dist/lenis.min.js"></script>
<script src="./scrollDIY.js"></script>
</body>
</html>
核心js:
document.addEventListener("DOMContentLoaded", function () {
const dom = {
scrollBox: document.querySelector('.scroll-x'),
scrollBar: document.querySelector('.diy-top'),
scrollBottom: document.querySelector('.diy-bottom'),
}
const lenis = new Lenis({
wrapper: dom.scrollBox
})
function raf(time) {
lenis.raf(time)
requestAnimationFrame(raf)
}
requestAnimationFrame(raf)
// 初始偏移量
let offset = dom.scrollBar.clientHeight;
// 结束位置
let scrollHeight = dom.scrollBottom.offsetTop;
dom.scrollBox.addEventListener("scroll", function (e) {
let scrollTop = Math.abs(Math.floor(e.target.scrollTop))
// 等比缩放尺寸
dom.scrollBar.style.height = offset + scrollTop / (dom.scrollBox.scrollHeight - dom.scrollBox.offsetHeight) * (scrollHeight - offset) + 'px';
// 限制位移最大距离
if (dom.scrollBar.offsetHeight > scrollHeight) {
dom.scrollBar.style.height = scrollHeight + 'px'
}
});
})