在图像滑块前后触摸手势

时间:2019-01-21 09:16:50

标签: javascript html css mobile

目标::我想在移动设备上创建一个前后图像滑块,以便用户可以轻松地从左向右拖动。

问题:它在台式机上完美运行,但在移动设备上无法实现。似乎addEventListener('touchmove')由于某种原因无法正常工作。

这是我第一次为移动设备做一些事情,所以我可能会错过一些很明显的事情。

这是我的代码笔进行测试的链接:https://codepen.io/greg_o/pen/GzKrVZ

我也找到了这个questioncodepen,但是由于某种原因,它不是移动设备上的拖动滑块。 (或者也许只在我的手机上?)他和我没有同样的问题,所以我认为我的问题仍然值得。

JS

    let active = false;


var scrollers = document.querySelectorAll('.scroller');
var sliders = document.querySelectorAll('.slider');

scrollers.forEach(element => {
  element.addEventListener('mousedown',function scrolling(){
    active = true;
    element.classList.add('scrolling');
  });
});

sliders.forEach(element => {
  element.addEventListener('mouseup',function(){
  active = false;
  element.querySelector('.scroller').classList.remove('scrolling');
});


element.addEventListener('mouseleave',function(){
  active = false;
  element.querySelector('.scroller').classList.remove('scrolling');
});


element.addEventListener('mousemove',function(e){
  if (!active) return;
  let x = e.pageX;
  x -= element.querySelector('.wrapper').getBoundingClientRect().left;
  scrollIt(x,element);
});

  element.addEventListener('touchmove',function(e){
  //if (!active) return;
  let x = e.clientX;
  x -= element.querySelector('.wrapper').getBoundingClientRect().left;
  scrollIt(x,element);
});

});





function scrollIt(x, element){
    let transform = Math.max(0,(Math.min(x,document.querySelector('.wrapper').offsetWidth)));
    element.querySelector('.after').style.width = 'calc(' + transform + 'px + 35vw)';
    element.querySelector('.scroller').style.left = transform-25+"px";
}


scrollIt(300, document.getElementsByClassName("wrapper")[0]);
scrollIt(20, document.getElementsByClassName("wrapper")[1]);

HTML

<section id="slider_1" class='slider'>
  <div class="wrapper">
  <div class="before">
    <img class="content-image" src="https://farm2.staticflickr.com/1638/26145024230_06acd55d1b_b.jpg" draggable="false"/>   </div>
  <div class="after">
    <img class="content-image apres" src="https://farm2.staticflickr.com/1663/25814974803_d4c55ff708_b.jpg" draggable="false"/>
  </div>
    <div class="scroller">
      <svg class="scroller__thumb" xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><polygon points="0 50 37 68 37 32 0 50" style="fill:#fff"/><polygon points="100 50 64 32 64 68 100 50" style="fill:#fff"/></svg>
    </div>
  </div>
</section>


<section id="slider_2" class='slider'>
  <div class="wrapper">
  <div class="before">
    <img class="content-image" src="https://farm2.staticflickr.com/1638/26145024230_06acd55d1b_b.jpg" draggable="false"/>   </div>
  <div class="after">
    <img class="content-image apres" src="https://farm2.staticflickr.com/1663/25814974803_d4c55ff708_b.jpg" draggable="false"/>
  </div>
    <div class="scroller">
      <svg class="scroller__thumb" xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><polygon points="0 50 37 68 37 32 0 50" style="fill:#fff"/><polygon points="100 50 64 32 64 68 100 50" style="fill:#fff"/></svg>
    </div>
  </div>
</section>

CSS

#slider_1,#slider_2{
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .wrapper{
        width: 30vw;
        height: 20vw;
        position:relative;
        overflow:hidden;
        box-shadow: 0 10px 20px rgba(0,0,0,0.1), 0 6px 6px rgba(0,0,0,0.2);
    }

    .before, .after {
        width:100%;
        height:100%;
        background-repeat:no-repeat;
        background-color: white;
        background-size: cover;
        background-position: center;
        position: absolute;
        top:0;
        left:0;
        pointer-events:none;
        overflow: hidden;
    }

    .content-image{
        height:100%;
    }

    .after{
        transform: skewX(-30deg) translate(-35vw); 
    }

    .content-image.apres{
        transform: skewX(30deg) translate(35vw);
    }

    .scroller{
        width: 50px;
        height:50px;
        position: absolute;
        top:50%;
        transform:translateY(-50%);
        border-radius:50%;
        background-color: transparent;
        opacity:0.9;
        pointer-events:auto;
        cursor: move;
        box-sizing: border-box;
        border: 3px solid #fff;
    }

    .scroller:hover{
        opacity:1;
    }

    .scrolling{
        pointer-events:none;
        opacity:1;
        // z-index: 1;
    }

    .scroller__thumb{
        margin:0;
        box-sizing: border-box;
        width:100%;
        height:100%;
        padding:5px;
    }

    .scroller:before, .scroller:after{
        background: #fff;
        content:" ";
        display: block;
        width: 3px;
        height: 9999px;
        position: absolute;
        left: 50%;
        margin-left: -3.5px;
        z-index: 30;
        transition:0.1s;
    }
    .scroller:before{
        top:95%;
        left:28%;
        transform-origin:top;
        transform:rotate(30deg)
    }
    .scroller:after{
        bottom:95%;
        left:83%;
        transform-origin:bottom;
        transform:rotate(30deg)
    }

1 个答案:

答案 0 :(得分:0)

看起来像您的示例没有主要的touch事件监听器

似乎您可以使用其他选项,这是另一个选项,我检查了它是否可以在移动设备上使用,这是代码orj resource,Js Fiddle的that

代码如下:

HTML

<div class="container">
<h1>Touch Image Comparison Slider Demo</h1>
<div class="image-spliter">
    <div class="mover" style="left: 99px;"></div>
    <img class="img-left" src="https://picsum.photos/600/450/?random" style="clip: rect(0px, 199px, 400px, 0px);">
    <img class="img-right" src="https://picsum.photos/g/600/400">
</div>
</div>

Css:

img {
  width: 100%;
  vertical-align: middle;
}

.image-spliter,
img,
.mover {
  overflow: hidden;
  -webkit-touch-callout: none;
    -webkit-user-select: none;
     -khtml-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
}

.image-spliter {
  position: relative;
}

.img-left {
  position: absolute;
  top: 0;
  left:0;
}

.mover {
  position:absolute;
  width: 200px;
  height: 100%;
  top: 0;
  left:0;
  z-index: 10;
}
.mover:before,
.mover:after {
  position:absolute;
  left:50%;
  content: "";
  background: #fff;
  cursor: -webkit-grab;
  cursor: grab;
}

.mover:before {
  top: 0;
  transform:translateX(-50%);
  width: 1px;
  height: 100%;
}
.mover:after {
  top: 50%;
  transform:translate(-50%, -50%);
  width: 5px;
  height: 33%;
  border-radius: 5px;
}

Js:

(function() {

    var elsH = document.querySelectorAll(".image-spliter .mover");
    var i = elsH.length;
    while (i--) {
        var moverWidth = elsH[i].getBoundingClientRect().width;
        var imgLeft = elsH[i].nextElementSibling;
        var width = imgLeft.getBoundingClientRect().width;
        var height = imgLeft.getBoundingClientRect().height;
        elsH[i].style.left = width / 2 - moverWidth / 2 + 'px';
        //imgLeft.style.clip = "rect(0px, " + width / 2 + "px, " + height + "px, 0px)";
        imgLeft.style.clip = "rect(0px, " + width / 2 + "px, 999px, 0px)";
        var mouseDownX = 0;
        var X;
        elsH[i].addEventListener("mousedown", function(e) {
            X = e.clientX;
            mouseDownX = 1;
        });
        elsH[i].addEventListener("mouseup", function(e) {
            mouseDownX = 0;
        });
        elsH[i].addEventListener("mouseout", function(e) {
            mouseDownX = 0;
        });

        elsH[i].addEventListener("touchstart", function(e) {
            X = e.touches[0].clientX;
            mouseDownX = 1;
        });
        elsH[i].addEventListener("touchend", function(e) {
            mouseDownX = 0;
        });

        elsH[i].addEventListener("mousemove", function(e) {
            if (mouseDownX) {
                this.style.left = parseInt(this.style.left) + (event.clientX - X) + "px";
                X = event.clientX;
                this.nextElementSibling.style.clip = "rect(0px, " + (this.getBoundingClientRect().width / 2 + parseInt(this.style.left)) + "px, " + this.getBoundingClientRect().height + "px, 0px)";
            }
        });

        elsH[i].addEventListener("touchmove", function(e) {
            if (mouseDownX) {
                this.style.left = parseInt(this.style.left) + (e.touches[0].clientX - X) + "px";
                X = e.touches[0].clientX;
                this.nextElementSibling.style.clip = "rect(0px, " + (this.getBoundingClientRect().width / 2 + parseInt(this.style.left)) + "px, " + this.getBoundingClientRect().height + "px, 0px)";
            }
        });

    }


    window.addEventListener("resize", function(f) {
        var elsHre = document.querySelectorAll(".image-spliter .mover");
        var ii = elsHre.length;
        while (ii--) {
            var moverWidth = elsHre[ii].getBoundingClientRect().width;
            var imgLeft = elsHre[ii].nextElementSibling;
            var width = imgLeft.getBoundingClientRect().width;
            var height = imgLeft.getBoundingClientRect().height;
            elsHre[ii].style.left = width / 2 - moverWidth / 2 + 'px';
            imgLeft.style.clip = "rect(0px, " + width / 2 + "px, " + height + "px, 0px)";
        }
    });

})();

希望有帮助。