解决思路就是想办法获得滑块距离左边元素的距离。
方法一
<!DOCTYPE html>
<html lang="zh-cn">
<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>demo2</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
#sliderPack{
width: 1600px;
height:600px;
border:1px solid red;
position: relative; /* 包裹滑块的容器的定位要设置成相对定位 */
margin: 100px auto;
}
#slider{
position: absolute; /* 滑块的定位要设置成绝对定位 */
width: 300px;
height: 300px;
left:0;
top:0;
background-color: blue;
border: 2px solid green;
}
</style>
<body>
<div id="sliderPack">
<div id="slider"></div>
</div>
<script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
<script>
$(function(){
let sliderPack = document.getElementById("sliderPack");
let slider =document.getElementById("slider");
let x;
let y;
let left;
let top;
let isDown = false;
slider.onmousedown=function(e){
x = e.clientX; //获取鼠标到浏览器客户区最左边的坐标(距离)
y = e.clientY; //获取鼠标到浏览器客户区最顶端的坐标(距离)
left = this.offsetLeft; //获取 slider元素 左端到 sliderPack元素 左端的距离
top = this.offsetTop; //获取 slider元素 上端到 sliderPack元素 上端的距离
isDown = true; //开启滑动
this.style.cursor ="move"; //鼠标的样式变成移动样式
}
sliderPack.onmousemove = function(e){
if(!isDown){
// 检查 slider元素 是否已经被鼠标按住,没有被按住则不继续执行脚本
return false;
}
let newX = e.clientX; //鼠标移动过后,鼠标到浏览器客户区最左边的坐标(距离)
let newY = e.clientY; //鼠标移动过后,鼠标到浏览器客户区最顶端的坐标(距离)
let newLeft = newX - (x - left);
//x - left 的差 是 sliderPack元素 左端到浏览器客户区的距离 加上 鼠标到 slider元素 左端的距离 的和
// newX 减 上述的和 是 slider元素 左端到 sliderPack元素 左端 的距离
// 还是不太理解的可以看下面的方法二,方法二更直观
let newTop = newY - (y - top);
//同理
if(newLeft<0){
newLeft = 0;
//如果 slider元素 左端到 sliderPack元素 的距离小于零,说明 slider元素 的左端的边界已经移出 sliderPack元素左端的边界,
//因为要使 slider元素 左边的边界 不移出 sliderPack元素 左端的边界,所以 slider元素 左端到 sliderPack元素 左端的距离设置为零(最小值)
}
if(newLeft>1600 - slider.offsetWidth){
newLeft = 1600 - slider.offsetWidth;//offsetWidth 方法 获得 元素的总宽度,即 width + padding + border;
//如果 slider元素 左端到 sliderPack元素 左端的距离大于 sliderPack元素 的宽度与slider元素 的宽度的差 ,说明 slider元素 的右端 的边界已经移出sliderPack元素 右端的边界,
//因为要使 slider元素 不移出 sliderPack 元素右端的边界,所以 slider元素 左端到 sliderPack元素 左端的距离设置为 sliderPack元素 的宽度 与 slider元素 的宽度的差(最大值)
}
if(newTop<0){
newTop = 0;//同上
}
if(newTop > 600 - slider.offsetHeight){
newTop = 600 - slider.offsetHeight; //同上
}
slider.style.left = newLeft + "px"; //改变 slider元素 左端到 sliderPack元素 左端的距离
slider.style.top = newTop + "px";//改变 slider元素 顶端到 sliderPack元素 顶端的距离
}
sliderPack.onmouseup = function(){
isDown = false; //松开鼠标的时候,把滑动开关关闭
slider.style.cursor ="default"; //把鼠标的样式调回默认值
}
sliderPack.onmouseleave = function(){
isDown = false; //鼠标离开sliderPack元素的时候也把滑动开关关闭
slider.style.cursor ="default";//把鼠标的样式调回默认值
}
})
</script>
</body>
</html>
方法二
<!DOCTYPE html>
<html lang="zh-cn">
<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>demo2</title>
</head>
<style>
*{
margin: 0;
padding: 0;
}
#sliderPack{
width: 1600px;
height:600px;
border:1px solid red;
position: relative; /* 包裹滑块的容器的定位要设置成相对定位 */
margin: 100px auto;
}
#slider{
position: absolute; /* 滑块的定位要设置成绝对定位 */
width: 300px;
height: 300px;
left:0;
top:0;
background-color: blue;
border: 2px solid green;
}
</style>
<body>
<div id="sliderPack">
<div id="slider"></div>
</div>
<script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
<script>
$(function(){
let sliderPack = document.getElementById("sliderPack");
let slider =document.getElementById("slider");
let a;
let b;
let isDown = false;
slider.onmousedown=function(e){
a = e.offsetX; //获取 鼠标 到 slider元素 左端的距离(坐标)
b = e.offsetY; //获取 鼠标 到 slider元素 定端的距离(坐标)
isDown = true; //开启滑动
this.style.cursor = "move"; //鼠标的样式变成移动样式
}
sliderPack.onmousemove = function(e){
if(!isDown){
// 检查 slider元素 是否已经被鼠标按住,没有被按住则不继续执行脚本
return false;
}
let newX = e.clientX; //鼠标移动过后,鼠标到浏览器客户区最左边的坐标(距离)
let newY = e.clientY; //鼠标移动过后,鼠标到浏览器客户区最顶端的坐标(距离)
let newLeft = newX - (a+$(sliderPack).offset().left);
//$(sliderPack).offset().left 这里用了jQuery里的方法,获取 sliderPack 元素 左端到文档最左端的距离
// a+$(sliderPack).offset().left 就是 sliderPack 元素 左端到文档最左端的距离 加上 鼠标到 slider元素 左端的距离 的和
// newX 减 上述的和 是 slider元素 左端到 sliderPack元素 左端 的距离
let newTop = newY - (b + $(sliderPack).offset().top);
//同理
if(newLeft<0){
newLeft = 0;
//如果 slider元素 左端到 sliderPack元素 的距离小于零,说明 slider元素 的左端的边界已经移出 sliderPack元素左端的边界,
//因为要使 slider元素 左边的边界 不移出 sliderPack元素 左端的边界,所以 slider元素 左端到 sliderPack元素 左端的距离设置为零(最小值)
}
if(newLeft>1600 - slider.offsetWidth){
newLeft = 1600 - slider.offsetWidth;//offsetWidth 方法 获得 元素的总宽度,即 width + padding + border;
//如果 slider元素 左端到 sliderPack元素 左端的距离大于 sliderPack元素 的宽度与slider元素 的宽度的差 ,说明 slider元素 的右端 的边界已经移出sliderPack元素 右端的边界,
//因为要使 slider元素 不移出 sliderPack 元素右端的边界,所以 slider元素 左端到 sliderPack元素 左端的距离设置为 sliderPack元素 的宽度 与 slider元素 的宽度的差(最大值)
}
if(newTop<0){
newTop = 0;//同上
}
if(newTop > 600 - slider.offsetHeight){
newTop = 600 - slider.offsetHeight; //同上
}
slider.style.left = newLeft + "px"; //改变 slider元素 左端到 sliderPack元素 左端的距离
slider.style.top = newTop + "px";//改变 slider元素 顶端到 sliderPack元素 顶端的距离
}
sliderPack.onmouseup = function(){
isDown = false; //松开鼠标的时候,把滑动开关关闭
slider.style.cursor = "default"; //把鼠标的样式调回默认值
}
sliderPack.onmouseleave = function(){
isDown = false; //鼠标离开sliderPack元素的时候也把滑动开关关闭
slider.style.cursor = "default";//把鼠标的样式调回默认值
}
})
</script>
</body>
</html>