鼠标横向滚动的思路
- 阻止鼠标滚动影响纵向滚动条的行为
- 找到影响滚动条的容器的 scrollLeft 属性为
- 根据鼠标的滚轮方向,决定滚动条是向左还是向右滚动
案例实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="./jquery.min.js"></script>
</head>
<style>
#son {
height: 4000px;
width: 4000px;
}
#parent {
position: absolute;
top: 500px;
left: 500px;
border: 1px solid red;
width: 300px;
height: 300px;
overflow: auto;
}
</style>
<body>
<!-- 父容器的宽度是500px,子容器的宽度是4000px,因此父容器会出现滚动条 -->
<div style="padding: 15px;" id="parent">
<div id="son"></div>
</div>
</body>
<script>
let son = document.getElementById("son");
let parent = document.getElementById("parent");
window.onload = function() {
let $son = $("#son");
son.onwheel = function(e) {
//禁止事件默认行为(此处禁止鼠标滚轮行为关联到"屏幕滚动条上下移动"行为)
e.preventDefault();
console.log(e);
// son 组件本身是没有滚动条的,因此 scrollLeft 属性为0
console.log($son.scrollLeft());
if (e.wheelDelta) { //判断浏览器IE,谷歌滑轮事件
if (e.wheelDelta > 0) { //当滑轮向上滚动时
//事件
console.log(parent.scrollLeft);
parent.scrollLeft = parent.scrollLeft - 50
}
if (e.wheelDelta < 0) { //当滑轮向下滚动时
//事件
console.log(parent.scrollLeft);
parent.scrollLeft = parent.scrollLeft + 50
}
} else if (e.detail) { //Firefox滑轮事件
if (e.detail> 0) { //当滑轮向上滚动时
//事件
console.log(parent.scrollLeft);
parent.scrollLeft = parent.scrollLeft - 50
}
if (e.detail< 0) { //当滑轮向下滚动时
//事件
console.log(parent.scrollLeft);
parent.scrollLeft = parent.scrollLeft + 50
}
}
}
}
</script>
</html>
理解测试过程中 scrollLeft 属性值为0的情况
<!DOCTYPE html>
<html lang="en" id="root">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="./jquery.min.js"></script>
</head>
<style>
#son {
height: 2000px;
width: 2000px;
}
</style>
<body id="parent">
<div id="son"></div>
</body>
<script>
let sonWidget = document.getElementById("son");
let parent = document.getElementById("parent");
let root = document.getElementById("root");
debugger
window.onload = function() {
let $son = $("#son");
sonWidget.onwheel = function(e) {
//禁止事件默认行为(此处禁止鼠标滚轮行为关联到"屏幕滚动条上下移动"行为)
e.preventDefault();
console.log(e);
console.log($son.scrollLeft());
// 获取 body scrollLeft 属性,无论滚动条放在那里,都是为0,因为body是没有滚动条的
console.log(parent.scrollLeft);
// 实际上滚动条是 根节点 html 的,因此想要获取滚动条的宽度,应用用 document的scrollLeft
console.log($(document).scrollLeft())
if (e.wheelDelta) { //判断浏览器IE,谷歌滑轮事件
if (e.wheelDelta > 0) { //当滑轮向上滚动时
//事件
console.log(root.scrollLeft);
root.scrollLeft = root.scrollLeft - 50
}
if (e.wheelDelta < 0) { //当滑轮向下滚动时
//事件
console.log(root.scrollLeft);
root.scrollLeft = root.scrollLeft + 50
}
} else if (e.detail) { //Firefox滑轮事件
if (e.detail> 0) { //当滑轮向上滚动时
//事件
console.log(root.scrollLeft);
root.scrollLeft = root.scrollLeft - 50
}
if (e.detail< 0) { //当滑轮向下滚动时
//事件
console.log(root.scrollLeft);
root.scrollLeft = root.scrollLeft + 50
}
}
};
};
</script>
</html>
解释说明
- son 组件的宽度是4000px
- 父容器 body 组件因此被子组件“撑开”,导致父组件的宽度也是 4000px
- 浏览器出现了滚动条
- 滚动条是整个窗口的,不是body的,因此真正的滚动条是html不是 body的,所以查询body的scrollLeft属性始终为0
如何判断鼠标滚动方向
var scrollFunc = function (e) {
e = e || window.event;
if (e.wheelDelta) { //判断浏览器IE,谷歌滑轮事件
if (e.wheelDelta > 0) { //当滑轮向上滚动时
//事件
}
if (e.wheelDelta < 0) { //当滑轮向下滚动时
//事件
}
} else if (e.detail) { //Firefox滑轮事件
if (e.detail> 0) { //当滑轮向上滚动时
//事件
}
if (e.detail< 0) { //当滑轮向下滚动时
//事件
}
}
}
//给页面绑定滑轮滚动事件
if (document.addEventListener) {//firefox
document.addEventListener('DOMMouseScroll', scrollFunc, false);
}
//滚动滑轮触发scrollFunc方法 //ie 谷歌
window.onmousewheel = document.onmousewheel = scrollFunc;
- 需要考虑兼容性问题 火狐 和 非火狐
- 火狐根据 detail 属性,如果大于零是向上滚动,如果小于0是向下滚动
- 非火狐根据 wheelDelta 属性,如果大于零是向上滚动,如果小于0是向下滚动