我正在尝试创建一个可以向左/向右拖动的水平滑块,它将相应地更新其变换平移位置。我想尝试用纯javascript来处理这个问题,所以请不要使用外部库。
到目前为止,我已经在初始加载时工作,并将拖动到它的位置,但之后它不会再次更新以继续。
var object = document.querySelector('.js-slider-container'),
initX, firstX;
object.addEventListener('mousedown', function(e) {
e.preventDefault();
initX = this.style.transform;
firstX = e.pageX;
this.addEventListener('mousemove', dragIt, false);
console.log(initX);
window.addEventListener('mouseup', function() {
object.removeEventListener('mousemove', dragIt, false);
}, false);
}, false);
object.addEventListener('touchstart', function(e) {
e.preventDefault();
initX = this.style.transform;
var touch = e.touches;
firstX = touch[0].pageX;
this.addEventListener('touchmove', swipeIt, false);
window.addEventListener('touchend', function(e) {
e.preventDefault();
object.removeEventListener('touchmove', swipeIt, false);
}, false);
}, false);
function dragIt(e) {
this.style.transform = `translate3d(${initX+e.pageX-firstX}px,0,0)`;
}
function swipeIt(e) {
var contact = e.touches;
this.style.transform = `translate3d(${initX+contact[0].pageX-firstX}px,0,0)`;
}
这里有一个jsfiddle来展示我的意思,它在初始运行时有效,但从那时起不会继续更新它的位置。我也不知道如何限制它的左右位置以避免过度滚动。
感谢任何建议,欢呼
最初,this.style.transform
的值将是一个空字符串""
,稍后拖动时将更新为translate3d(-578px, 0px, 0px)
。
您在计算中直接使用这个字符串值,而没有只选择x
值,因此它失败了。
我们可以使用RegEx来选择x
值,如下所示,然后在计算中使用它。
const txMatch = this.style.transform.match(/translate3d((-?d+)px,.+)/);
initX = txMatch ? +(txMatch[1] || 0) : 0;
var object = document.querySelector('.js-slider-container'),
initX, firstX;
object.addEventListener('mousedown', function(e) {
e.preventDefault();
const txMatch = this.style.transform.match(/translate3d((-?d+)px,.+)/);
initX = txMatch ? +(txMatch[1] || 0) : 0;
firstX = e.pageX;
this.addEventListener('mousemove', dragIt, false);
window.addEventListener('mouseup', function() {
object.removeEventListener('mousemove', dragIt, false);
}, false);
}, false);
object.addEventListener('touchstart', function(e) {
e.preventDefault();
const txMatch = this.style.transform.match(/translate3d((-?d+)px,.+)/);
initX = txMatch ? +(txMatch[1] || 0) : 0;
var touch = e.touches;
firstX = touch[0].pageX;
this.addEventListener('touchmove', swipeIt, false);
window.addEventListener('touchend', function(e) {
object.removeEventListener('touchmove', swipeIt, false);
}, false);
}, false);
function dragIt(e) {
const maxMove = this.offsetWidth - this.parentElement.offsetWidth;
const x = initX + e.pageX - firstX;
if (x >= 0 || x <= -maxMove) {
return;
}
this.style.transform = `translate3d(${x}px,0,0)`;
}
function swipeIt(e) {
var contact = e.touches;
this.style.transform = `translate3d(${initX+contact[0].pageX-firstX}px,0,0)`;
}
*,
*:before,
*:after {
-webkit-box-sizing: inherit;
box-sizing: inherit;
}
.container_full-vh {
position: relative;
height: 100vh;
}
section {
padding: 400px 0;
}
/* Slider */
.slider {
position: absolute;
top: 0;
left: 0;
bottom: 0;
z-index: 9;
will-change: transform;
display: flex;
align-items: center;
width: 100%;
height: 100vh;
overflow-x: hidden;
}
.slider-container {
position: relative;
left: 10px;
display: grid;
align-items: center;
grid-template-columns: repeat(7, 33.3333vw);
grid-column-gap: 4.167vw;
padding: 0 8.33333vw;
height: unset;
cursor: grab;
}
.slider-item {
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
will-change: transform;
position: relative;
overflow: hidden;
opacity: 1;
visibility: inherit;
}
.slider-item_img-wrap {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
overflow: hidden;
opacity: 1;
visibility: inherit;
}
.slider-item:before,
.slider-item_img-wrap:before {
content: "";
display: block;
padding-bottom: calc(100%/0.8);
}
.slider-item_img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
max-width: unset;
pointer-events: none;
user-select: none;
transform-origin: left center;
transform: scale(1.75);
will-change: transform;
}
.slider-item_content {
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
z-index: 1;
user-select: none;
}
.slider-item_content-heading {
display: flex;
overflow: hidden;
}
.slider-item_content-heading h3 {
pointer-events: none;
font-size: 7.569vw;
line-height: 6.944vw;
color: white;
text-transform: uppercase;
transform-origin: left bottom;
will-change: transform;
}
<div class="container_full-vh">
<section>
<div class="js-slider slider">
<div class="js-slider-container slider-container">
<div class="slider-item">
<div class="slider-item_img-wrap">
<img src="https://images.unsplash.com/photo-1479839672679-a46483c0e7c8?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=80&ar=0.8" class="slider-item_img">
</div>
<div class="slider-item_content">
<div class="slider-item_content-heading">
<h3>Indigo</h3>
</div>
</div>
</div>
<div class="slider-item">
<div class="slider-item_img-wrap">
<img src="https://images.unsplash.com/photo-1566688342604-dbe3e7357104?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80&ar=0.8" class="slider-item_img">
</div>
<div class="slider-item_content">
<div class="slider-item_content-heading">
<h3>Rouge</h3>
</div>
</div>
</div>
<div class="slider-item">
<div class="slider-item_img-wrap">
<img src="https://images.unsplash.com/photo-1472835560847-37d024ebacdc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=80&ar=0.8" class="slider-item_img">
</div>
<div class="slider-item_content">
<div class="slider-item_content-heading">
<h3>Juane</h3>
</div>
</div>
</div>
<div class="slider-item">
<div class="slider-item_img-wrap">
<img src="https://images.unsplash.com/photo-1541320823636-40247af897bf?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=80&ar=0.8" class="slider-item_img">
</div>
<div class="slider-item_content">
<div class="slider-item_content-heading">
<h3>Orange</h3>
</div>
</div>
</div>
<div class="slider-item">
<div class="slider-item_img-wrap">
<img src="https://images.unsplash.com/photo-1566787020216-3e4f973ec5ec?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=80&ar=0.8" class="slider-item_img">
</div>
<div class="slider-item_content">
<div class="slider-item_content-heading">
<h3>Vert</h3>
</div>
</div>
</div>
</div>
</div>
</section>
</div>