0

I have to create such a slider on the site I design. Given JavaScript code, how can I design it in a clickable way? i want to make like drag and drop thing And can be used on all sites, especially small sizes such as mobile and tablet. This JavaScript code only organizes the float mode and is ineffective if clicked except in small sizes. How can we do this?

Thank you in advance for your cooperation.

class BeforeAfter {
    constructor(enteryObject) {

        const beforeAfterContainer = document.querySelector(enteryObject.id);
        const before = beforeAfterContainer.querySelector('.bal-before');
        const beforeText = beforeAfterContainer.querySelector('.bal-beforePosition');
        const afterText = beforeAfterContainer.querySelector('.bal-afterPosition');
        const handle = beforeAfterContainer.querySelector('.bal-handle');
        var widthChange = 0;

        beforeAfterContainer.querySelector('.bal-before-inset').setAttribute("style", "width: " + beforeAfterContainer.offsetWidth + "px;")
        window.onresize = function () {
            beforeAfterContainer.querySelector('.bal-before-inset').setAttribute("style", "width: " + beforeAfterContainer.offsetWidth + "px;")
        }
        before.setAttribute('style', "width: 50%;");
        handle.setAttribute('style', "left: 50%;");

        //touch screen event listener
        beforeAfterContainer.addEventListener("touchstart", (e) => {

            beforeAfterContainer.addEventListener("touchmove", (e2) => {
                let containerWidth = beforeAfterContainer.offsetWidth;
                let currentPoint = e2.changedTouches[0].clientX;

                let startOfDiv = beforeAfterContainer.offsetLeft;

                let modifiedCurrentPoint = currentPoint - startOfDiv;

                if (modifiedCurrentPoint > 10 && modifiedCurrentPoint < beforeAfterContainer.offsetWidth - 10) {
                    let newWidth = modifiedCurrentPoint * 100 / containerWidth;

                    before.setAttribute('style', "width:" + newWidth + "%;");
                    afterText.setAttribute('style', "z-index: 1;");
                    handle.setAttribute('style', "left:" + newWidth + "%;");
                }
            });
        });

        //mouse move event listener
        beforeAfterContainer.addEventListener('mousemove', (e) => {
            let containerWidth = beforeAfterContainer.offsetWidth;
            widthChange = e.offsetX;
            let newWidth = widthChange * 100 / containerWidth;

            if (e.offsetX > 10 && e.offsetX < beforeAfterContainer.offsetWidth - 10) {
                before.setAttribute('style', "width:" + newWidth + "%;");
                afterText.setAttribute('style', "z-index:" + "1;");
                handle.setAttribute('style', "left:" + newWidth + "%;");
            }
        })

    }
}
new BeforeAfter({
    id: '#one'
});
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.top-title {
    text-align: center;
    font-family: Arial, Helvetica, sans-serif;
    margin: 1rem 0.5rem;
}

.top-title span {
    font-style: italic;
    font-size: 1.5rem;
}

@media all and (max-width: 479px) {
    .mainSection {
        display: flex;
        flex-direction: column;
        flex-wrap: nowrap;
        justify-content: space-around;
        align-items: stretch;
        align-content: stretch;
        width: 100%;
        height: 700px;
        padding: 10px;
    }
    .bal-container {
        margin: 10px 0;
    }
}

@media all and (max-width: 599px) {
    .mainSection {
        display: flex;
        flex-direction: column;
        flex-wrap: nowrap;
        justify-content: space-around;
        align-items: stretch;
        align-content: stretch;
        width: 100%;
        height: 800px;
        padding: 10px;
    }
    .bal-container {
        margin: 10px 0;
    }
}

@media all and (min-width: 480px) and (max-width: 768px) {
    .mainSection {
        display: flex;
        flex-direction: column;
        flex-wrap: nowrap;
        justify-content: space-around;
        align-items: stretch;
        align-content: stretch;
        width: 100%;
        height: 1000px;
        padding: 10px;
    }
    .bal-container {
        margin: 10px 0;
    }
}

@media all and (min-width: 768px) and (max-width: 959px) {
    .mainSection {
        display: flex;
        flex-direction: column;
        flex-wrap: nowrap;
        justify-content: space-around;
        align-items: stretch;
        align-content: stretch;
        width: 100%;
        height: 1100px;
        padding: 10px;
    }
    .bal-container {
        margin: 10px 0;
    }
}

@media all and (min-width: 960px) and (max-width: 1199px) {
    .mainSection {
        display: flex;
        flex-direction: row;
        flex-wrap: nowrap;
        justify-content: space-around;
        align-items: stretch;
        align-content: stretch;
        width: 100%;
        height: 500px;
        padding: 10px;
    }
    .bal-container {
        margin: 0 10px;
    }
}

@media all and (min-width: 1199px) {
    .mainSection {
        display: flex;
        flex-direction: row;
        flex-wrap: nowrap;
        justify-content: space-around;
        align-items: stretch;
        align-content: stretch;
        width: 100%;
        height: 500px;
        padding: 10px;
    }
    .bal-container {
        margin: 0 10px;
    }
}


/* Before After Container */

.bal-container {
    position: relative;
    width: 100%;
    height: 100%;
    cursor: grab;
    overflow: hidden;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.bal-after {
    display: block;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.bal-before {
    display: block;
    position: absolute;
    top: 0;
    /* right: 0; */
    bottom: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 15;
    overflow: hidden;
}

.bal-before-inset {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
}

.bal-after img,
.bal-before img {
    object-fit: cover;
    position: absolute;
    width: 100%;
    height: 100%;
    object-position: 50% 50%;
    top: 0;
    bottom: 0;
    left: 0;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    user-select: none;
}

.bal-beforePosition {
    background: #121212;
    color: #fff;
    left: 0;
    pointer-events: none;
    border-radius: 0.2rem;
    padding: 2px 10px;
}

.bal-afterPosition {
    background: #121212;
    color: #fff;
    right: 0;
    pointer-events: none;
    border-radius: 0.2rem;
    padding: 2px 10px;
}

.beforeLabel {
    position: absolute;
    bottom: 0;
    margin: 1rem;
    font-size: 1em;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    user-select: none;
}

.afterLabel {
    position: absolute;
    bottom: 0;
    margin: 1rem;
    font-size: 1em;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    user-select: none;
}


/* handle and arrow */

.bal-handle {
    height: 41px;
    width: 41px;
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -20px;
    margin-top: -21px;
    border: 2px solid #fff;
    border-radius: 1000px;
    z-index: 20;
    pointer-events: none;
    box-shadow: 0 0 10px rgb(12, 12, 12);
}

.handle-left-arrow,
.handle-right-arrow {
    width: 0;
    height: 0;
    border: 6px inset transparent;
    position: absolute;
    top: 50%;
    margin-top: -6px;
}

.handle-left-arrow {
    border-right: 6px solid #fff;
    left: 50%;
    margin-left: -17px;
}

.handle-right-arrow {
    border-left: 6px solid #fff;
    right: 50%;
    margin-right: -17px;
}

.bal-handle::before {
    bottom: 50%;
    margin-bottom: 20px;
    box-shadow: 0 0 10px rgb(12, 12, 12);
}

.bal-handle::after {
    top: 50%;
    margin-top: 20.5px;
    box-shadow: 0 0 5px rgb(12, 12, 12);
}

.bal-handle::before,
.bal-handle::after {
    content: " ";
    display: block;
    width: 2px;
    background: #fff;
    height: 9999px;
    position: absolute;
    left: 50%;
    margin-left: -1.5px;
}
<div class="mainSection">
  <div id="one" class="bal-container">
     <div class="bal-before">
        <div class="bal-before-inset">
           <img src="https://farm2.staticflickr.com/1638/26145024230_06acd55d1b_b.jpg">
           <div class="bal-afterPosition afterLabel">
              before
           </div>
       </div>
     </div>

   <div class="bal-after">
       <img src="https://farm2.staticflickr.com/1663/25814974803_d4c55ff708_b.jpg">
       <div class="bal-afterPosition afterLabel">
          After
       </div>
   </div>
                                            
   <div class="bal-handle">
      <span class=" handle-left-arrow"></span>
      <span class="handle-right-arrow"></span>
   </div>     
 </div>
</div>

2
  • when you say click You mean you want to make like drag and drop thing? Commented Mar 16, 2022 at 13:33
  • hello my friend. yes, Exactly Commented Mar 16, 2022 at 14:00

2 Answers 2

1

I've added a toggle click action to the whole element to turn dragging on and off.

Click the picture to enable the slider.

class BeforeAfter {
  constructor(enteryObject) {

    const beforeAfterContainer = document.querySelector(enteryObject.id);
    const before = beforeAfterContainer.querySelector('.bal-before');
    const beforeText = beforeAfterContainer.querySelector('.bal-beforePosition');
    const afterText = beforeAfterContainer.querySelector('.bal-afterPosition');
    const handle = beforeAfterContainer.querySelector('.bal-handle');
    var widthChange = 0;

    beforeAfterContainer.querySelector('.bal-before-inset').setAttribute("style", "width: " + beforeAfterContainer.offsetWidth + "px;")
    window.onresize = function() {
      beforeAfterContainer.querySelector('.bal-before-inset').setAttribute("style", "width: " + beforeAfterContainer.offsetWidth + "px;")
    }
    before.setAttribute('style', "width: 50%;");
    handle.setAttribute('style', "left: 50%;");

    //touch screen event listener
    beforeAfterContainer.addEventListener("touchstart", (e) => {

      beforeAfterContainer.addEventListener("touchmove", (e2) => {
        let containerWidth = beforeAfterContainer.offsetWidth;
        let currentPoint = e2.changedTouches[0].clientX;

        let startOfDiv = beforeAfterContainer.offsetLeft;

        let modifiedCurrentPoint = currentPoint - startOfDiv;

        if (modifiedCurrentPoint > 10 && modifiedCurrentPoint < beforeAfterContainer.offsetWidth - 10) {
          let newWidth = modifiedCurrentPoint * 100 / containerWidth;

          before.setAttribute('style', "width:" + newWidth + "%;");
          afterText.setAttribute('style', "z-index: 1;");
          handle.setAttribute('style', "left:" + newWidth + "%;");
        }
      });
    });

    //toggle active state
    beforeAfterContainer.addEventListener('click', (e) => {
      beforeAfterContainer.classList.toggle("active");
    });

    //mouse move event listener
    beforeAfterContainer.addEventListener('mousemove', (e) => {
      if (beforeAfterContainer.classList.contains("active")) {
        let containerWidth = beforeAfterContainer.offsetWidth;
        widthChange = e.offsetX;
        let newWidth = widthChange * 100 / containerWidth;

        if (e.offsetX > 10 && e.offsetX < beforeAfterContainer.offsetWidth - 10) {
          before.setAttribute('style', "width:" + newWidth + "%;");
          afterText.setAttribute('style', "z-index:" + "1;");
          handle.setAttribute('style', "left:" + newWidth + "%;");
        }
      }
    });

  }
}
new BeforeAfter({
  id: '#one'
});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.top-title {
  text-align: center;
  font-family: Arial, Helvetica, sans-serif;
  margin: 1rem 0.5rem;
}

.top-title span {
  font-style: italic;
  font-size: 1.5rem;
}

@media all and (max-width: 479px) {
  .mainSection {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: space-around;
    align-items: stretch;
    align-content: stretch;
    width: 100%;
    height: 700px;
    padding: 10px;
  }
  .bal-container {
    margin: 10px 0;
  }
}

@media all and (max-width: 599px) {
  .mainSection {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: space-around;
    align-items: stretch;
    align-content: stretch;
    width: 100%;
    height: 800px;
    padding: 10px;
  }
  .bal-container {
    margin: 10px 0;
  }
}

@media all and (min-width: 480px) and (max-width: 768px) {
  .mainSection {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: space-around;
    align-items: stretch;
    align-content: stretch;
    width: 100%;
    height: 1000px;
    padding: 10px;
  }
  .bal-container {
    margin: 10px 0;
  }
}

@media all and (min-width: 768px) and (max-width: 959px) {
  .mainSection {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    justify-content: space-around;
    align-items: stretch;
    align-content: stretch;
    width: 100%;
    height: 1100px;
    padding: 10px;
  }
  .bal-container {
    margin: 10px 0;
  }
}

@media all and (min-width: 960px) and (max-width: 1199px) {
  .mainSection {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: space-around;
    align-items: stretch;
    align-content: stretch;
    width: 100%;
    height: 500px;
    padding: 10px;
  }
  .bal-container {
    margin: 0 10px;
  }
}

@media all and (min-width: 1199px) {
  .mainSection {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: space-around;
    align-items: stretch;
    align-content: stretch;
    width: 100%;
    height: 500px;
    padding: 10px;
  }
  .bal-container {
    margin: 0 10px;
  }
}


/* Before After Container */

.bal-container {
  position: relative;
  width: 100%;
  height: 100%;
  cursor: grab;
  overflow: hidden;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.bal-after {
  display: block;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.bal-before {
  display: block;
  position: absolute;
  top: 0;
  /* right: 0; */
  bottom: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 15;
  overflow: hidden;
}

.bal-before-inset {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
}

.bal-after img,
.bal-before img {
  object-fit: cover;
  position: absolute;
  width: 100%;
  height: 100%;
  object-position: 50% 50%;
  top: 0;
  bottom: 0;
  left: 0;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
}

.bal-beforePosition {
  background: #121212;
  color: #fff;
  left: 0;
  pointer-events: none;
  border-radius: 0.2rem;
  padding: 2px 10px;
}

.bal-afterPosition {
  background: #121212;
  color: #fff;
  right: 0;
  pointer-events: none;
  border-radius: 0.2rem;
  padding: 2px 10px;
}

.beforeLabel {
  position: absolute;
  bottom: 0;
  margin: 1rem;
  font-size: 1em;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
}

.afterLabel {
  position: absolute;
  bottom: 0;
  margin: 1rem;
  font-size: 1em;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
}


/* handle and arrow */

.bal-handle {
  height: 41px;
  width: 41px;
  position: absolute;
  left: 50%;
  top: 50%;
  margin-left: -20px;
  margin-top: -21px;
  border: 2px solid #fff;
  border-radius: 1000px;
  z-index: 20;
  pointer-events: none;
  box-shadow: 0 0 10px rgb(12, 12, 12);
}

.handle-left-arrow,
.handle-right-arrow {
  width: 0;
  height: 0;
  border: 6px inset transparent;
  position: absolute;
  top: 50%;
  margin-top: -6px;
}

.handle-left-arrow {
  border-right: 6px solid #fff;
  left: 50%;
  margin-left: -17px;
}

.handle-right-arrow {
  border-left: 6px solid #fff;
  right: 50%;
  margin-right: -17px;
}

.bal-handle::before {
  bottom: 50%;
  margin-bottom: 20px;
  box-shadow: 0 0 10px rgb(12, 12, 12);
}

.bal-handle::after {
  top: 50%;
  margin-top: 20.5px;
  box-shadow: 0 0 5px rgb(12, 12, 12);
}

.bal-handle::before,
.bal-handle::after {
  content: " ";
  display: block;
  width: 2px;
  background: #fff;
  height: 9999px;
  position: absolute;
  left: 50%;
  margin-left: -1.5px;
}
<div class="mainSection">
  <div id="one" class="bal-container">
    <div class="bal-before">
      <div class="bal-before-inset">
        <img src="https://farm2.staticflickr.com/1638/26145024230_06acd55d1b_b.jpg">
        <div class="bal-afterPosition afterLabel">
          before
        </div>
      </div>
    </div>

    <div class="bal-after">
      <img src="https://farm2.staticflickr.com/1663/25814974803_d4c55ff708_b.jpg">
      <div class="bal-afterPosition afterLabel">
        After
      </div>
    </div>

    <div class="bal-handle">
      <span class=" handle-left-arrow"></span>
      <span class="handle-right-arrow"></span>
    </div>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

1 Comment

hello my friend. Thank you for your answer. Can you guide me to make something like dragging and dropping?
0

This code works by dragging and dropping with mousedown and mouseup events.

window.onload = function(){
    class BeforeAfter {
        constructor(enteryObject) {
      
          const beforeAfterContainer = document.querySelector(enteryObject.id);
          const before = beforeAfterContainer.querySelector('.bal-before');
          const beforeText = beforeAfterContainer.querySelector('.bal-beforePosition');
          const afterText = beforeAfterContainer.querySelector('.bal-afterPosition');
          const handle = beforeAfterContainer.querySelector('.bal-handle');
          var widthChange = 0;
      
          beforeAfterContainer.querySelector('.bal-before-inset').setAttribute("style", "width: " + beforeAfterContainer.offsetWidth + "px;")
          window.onresize = function() {
            beforeAfterContainer.querySelector('.bal-before-inset').setAttribute("style", "width: " + beforeAfterContainer.offsetWidth + "px;")
          }
          before.setAttribute('style', "width: 50%;");
          handle.setAttribute('style', "left: 50%;");
      
//touch screen event listener
beforeAfterContainer.addEventListener("touchstart", (e) => {
  beforeAfterContainer.addEventListener("touchmove", (e2) => {let containerWidth = beforeAfterContainer.offsetWidth;
    let currentPoint = e2.changedTouches[0].clientX;
    let startOfDiv = beforeAfterContainer.offsetLeft;
    let modifiedCurrentPoint = currentPoint - startOfDiv;
    if (modifiedCurrentPoint > 10 && modifiedCurrentPoint < beforeAfterContainer.offsetWidth - 10) {
       let newWidth = modifiedCurrentPoint * 100 / containerWidth;
       before.setAttribute('style', "width:" + newWidth + "%;");
       afterText.setAttribute('style', "z-index: 1;");
       handle.setAttribute('style', "left:" + newWidth + "%;");
              }
            });
          });
      
//toggle active state
beforeAfterContainer.addEventListener('mousedown', (e) => {
  beforeAfterContainer.classList.add("active");
});

//toggle de-active state
beforeAfterContainer.addEventListener('mouseup', (e) => {
 beforeAfterContainer.classList.remove("active");
});

//mouse move event listener
beforeAfterContainer.addEventListener('mousemove', (e) => {
  if (beforeAfterContainer.classList.contains("active")) {
      let containerWidth =beforeAfterContainer.offsetWidth;
      widthChange = e.offsetX;
      let newWidth = widthChange * 100 / containerWidth;
      if (e.offsetX > 10 && e.offsetX < beforeAfterContainer.offsetWidth - 10) {
        before.setAttribute('style', "width:" + newWidth + "%;");
       afterText.setAttribute('style', "z-index:" + "1;");
       handle.setAttribute('style', "left:" + newWidth + "%;");
              }
            }
          });
      
        }
      }
new BeforeAfter({
  id: '#one'
});
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.