javascripthtmlcssslideronmouseup

Vanilla JS before/after slider has issues removing/adding overlay when onmouseup is triggered?


I'm new to Javascript and I've been trying to create this before/after slider found here - https://codepen.io/HarryWilson/pen/jOPzbGz.

 document.body.addEventListener('mouseup',function(){
  active = false;
  overlay = false; 
  document.querySelector('.scroller').classList.remove('scrolling');
  overlayOffDuringSlide();
  // this is the area of code which is causing the final problem
});

Above is the area of JS code I have identified as the problem area. Everything in the slider is working as it should apart from the fact that when you click on either of the images, the overlay disappears. I've identified that the problem is being caused by the 'mouseup' section of the Javascript and have tried adding extra variables or changing around my if statement so that it stays on while anyone is over or clicking on the image.

Please also see this codepen - https://codepen.io/HarryWilson/pen/LYVmeZp

   document.body.addEventListener('mouseup',function(){
   active = false;
   overlay = false; 
   // THis is the problem area 
   // Maybe check some kinda condition for the overlay being on and if it is, keep it on ... 
   document.querySelector('.scroller').classList.remove('scrolling');
     if (document.querySelector(".overlay").style.display = "block"){
      overlayOn();
     }
     else {
      overlayOffDuringSlide();
     }
    });

Here I have created two of these side by side. The above code is how I have tried a workaround (which works for the image clicking issue, but creates a new issue when you mouseup on the scroller. The first slider (on the left) shows the desired effect when clicking on the image, however the scroller has a click issue. Every fix I have come up with leaves the slider with one issue - either the scroller brings back the overlay onmouseup or the image removes it onmouseup. I would like the slider to always display the overlay when you are on the images (even when clicking) and then for the overlay to disappear when you are on the scroller (even when clicking). Would someone be able to offer up a suggestion for this as I seem to only be able to fix one and break the other?


Solution

  • If I understood this statement correctly: "I would like the slider to always display the overlay when you are on the images (even when clicking) and then for the overlay to disappear when you are on the scroller (even when clicking)."

    This can be achieved with a little change in the HTML and moving all overlay display control to the CSS. This makes the JS code way simpler, check it out:

    https://codepen.io/rafaelcastrocouto/pen/GRJXPeq

    var scrolling = false;
    
    var scroller = document.querySelector(".scroller");
    var overlay = document.querySelector(".overlay");
    var wrapper = document.querySelector(".wrapper");
    var after = document.querySelector(".after");
    
    scroller.addEventListener("mousedown", scrollStart);
    
    addEventListener("mousemove", scrollMove);
    addEventListener("mouseup", scrollEnd);
    addEventListener("mouseleave", scrollEnd);
    
    
    function scrollStart() {
      scrolling = true;
    }
    
    function scrollMove(e) {
      if (scrolling) {
        var x = e.pageX - wrapper.getBoundingClientRect().left;
        var transform = Math.max(0, Math.min(x, wrapper.offsetWidth));
        after.style.width = transform + "px";
        scroller.style.left = transform - 30 + "px";
      }
    }
    
    function scrollEnd() {
      scrolling = false;
    }
    body {
      display: grid;
      place-content: center;
    }
    
    .wrapper {
      position: relative;
      background-color: #202020;
      overflow: hidden;
      opacity: 100%;
      user-select: none;
      width: 900px;
      height: 600px;
    }
    
    .before,
    .after {
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
      background-repeat: no-repeat;
      background-size: cover;
      background-position: center;
      overflow: hidden;
    }
    .before {
      width: 100%;
    }
    .after {
      width: calc(50% + 5px);
    }
    
    .content-image {
      height: 100%;
    }
    
    .overlay {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      opacity: 0;
      transition: opacity 0.4s;
      pointer-events: none;
      background: rgba(255, 255, 255, 0.6);
    }
    .wrapper:hover .overlay {
      opacity: 1;
    }
    .wrapper:hover .ui:hover .overlay {
      opacity: 0;
    }
    
    .hover-before,
    .hover-after {
      position: absolute;
      top: 30%;
      padding: 16px;
      background-color: rgba(0, 0, 0, 0.5);
      color: white;
      font-weight: bold;
      font-size: 40px;
    }
    .hover-before {
      left: 0;
      border-radius: 0 3px 3px 0;
    }
    .hover-after {
      right: 0;
      border-radius: 3px 0 0 3px;
    }
    
    .scroller {
      width: 50px;
      height: 50px;
      position: absolute;
      left: calc(50% - 25px);
      top: 50%;
      transform: translateY(-50%);
      border-radius: 50%;
      background-color: transparent;
      cursor: pointer;
      border: 6px solid #fff;
    }
    
    .scroller:before,
    .scroller:after {
      background: #fff;
      content: " ";
      display: block;
      width: 7px;
      height: 100vmax;
      position: absolute;
      left: calc(50% - 3.5px);
    }
    .scroller:before {
      top: 100%;
    }
    .scroller:after {
      bottom: 100%;
    }
    <div class="wrapper">
      <div class="before">
        <img class="content-image" src="https://www.dropbox.com/s/wu9u6l53z3q6zpa/date.jpg?raw=1" draggable="false" />
      </div>
      <div class="after">
        <img class="content-image" src="https://www.dropbox.com/s/6i60hcgrz7yatl5/nexus-6-2770-001.jpg?raw=1" draggable="false" />
      </div>
      <div class="ui">
        <div class="overlay">
          <div class="hover-before">Before</div>
          <div class="hover-after">After</div>
        </div>
        <div class="scroller">
          <svg class="scroller__thumb" xmlns="http://www.w3.org/2000/svg" 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>
    </div>

    If I missed something just comment it out and I'll fix asap!