Home > database >  How to make input sliders not overlap each other?
How to make input sliders not overlap each other?

Time:01-21

There is this code, in it I set the minimum indent between the sliders using rangeGap. Everything seems to work as it should, but they continue to run into each other. Maybe someone can tell me what is wrong.

I can't figure out if it's the positioning of the elements or if I need to change the logic in the js. It should work like this, but the thumbs should not move each other when colliding: https://codepen.io/BabylonJS/pen/gqzBWx

const progressBar = document.querySelector('.slider--progress');
const inputMin = document.querySelector('.input--min');
const inputMax = document.querySelector('.input--max');
const inputRange = [inputMin, inputMax];

const rangeGap = 50000;

inputRange.forEach(function (el) {
  el.addEventListener('input', function (e) {
    let minValue = parseInt(inputRange[0].value);
    let maxValue = parseInt(inputRange[1].value);

    if (maxValue - minValue < rangeGap) {
      if (e.target.className === 'input--min') {
        inputRange[0].value = maxValue - rangeGap;
      } else if (e.target.className === 'input--max') {
        inputRange[1].value = minValue   rangeGap;
      }
    } else {
      progressBar.style.left = (minValue / inputRange[0].max) * 100   '%';
      progressBar.style.right = 100 - (maxValue / inputRange[1].max) * 100   '%';
    }
  });
});
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  background: rgb(107, 216, 107);
}

.slider {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
  margin-top: 50px;
  height: 30px;
  width: 500px;
  padding: 15px 10px;
  border-radius: 10px;
  background: rgb(42, 138, 42);
}

.slider--body {
  background: rgb(250, 250, 250);
  height: 4px;
  width: 100%;
  position: relative;
  border-radius: 5px;
}

.slider--progress {
  position: absolute;
  left: 25%;
  right: 25%;
  background: rgb(107, 216, 107);
  height: 4px;
  border-radius: 10px;
}

.slider--inputs {
  position: relative;
}

.slider--inputs > input {
  pointer-events: none;
}

.slider--input {
  position: absolute;
  top: -2.4px;
  left: -3px;
  height: 5px;
  width: calc(100%   2px);
  background: none;
  -webkit-appearance: none;
}

.slider--input::-webkit-slider-thumb {
  width: 15px;
  height: 15px;
  background: rgb(107, 216, 107);
  border-radius: 50%;
  border: 1px solid rgb(42, 138, 42);
  pointer-events: auto;
  -webkit-appearance: none;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>Double-range slider</title>
  </head>
  <body>
    <div >
      <div >
        <div ></div>
        <div >
          <input type="range"  min="0" , max="999999" step="10" value="250000" />
          <input type="range"  min="0" , max="999999" step="10" value="750000" />
        </div>
      </div>
    </div>

    <script src="double-range-slider.js"></script>
  </body>
</html>

CodePudding user response:

Thanks for the help) Instead of className === 'class', I wrote classList.contains('class') and it worked!

const progressBar = document.querySelector('.slider--progress');
const inputRange = document.querySelectorAll('.slider--input');

let rangeGap = 50000;

inputRange.forEach(function (el) {
  el.addEventListener('input', function (e) {
    let minValue = parseInt(inputRange[0].value);
    let maxValue = parseInt(inputRange[1].value);
    if (maxValue - minValue < rangeGap) {
      if (e.target.classList.contains('input--min')) {
        inputRange[0].value = maxValue - rangeGap;
      } else if (e.target.classList.contains('input--max')) {
        inputRange[1].value = minValue   rangeGap;
      }
    } else {
      progressBar.style.left = (minValue / inputRange[0].max) * 100   '%';
      progressBar.style.right = 100 - (maxValue / inputRange[1].max) * 100   '%';
    }
  });
});
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  background: rgb(107, 216, 107);
}

.slider {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 0 auto;
  margin-top: 50px;
  height: 30px;
  width: 500px;
  padding: 15px 10px;
  border-radius: 10px;
  background: rgb(42, 138, 42);
}

.slider--body {
  background: rgb(250, 250, 250);
  height: 4px;
  width: 100%;
  position: relative;
  border-radius: 5px;
}

.slider--progress {
  position: absolute;
  left: 25%;
  right: 25%;
  background: rgb(107, 216, 107);
  height: 4px;
  border-radius: 10px;
}

.slider--inputs {
  position: relative;
}

.slider--inputs > input {
  pointer-events: none;
}

.slider--input {
  position: absolute;
  top: -2.4px;
  left: -3px;
  height: 5px;
  width: calc(100%   2px);
  background: none;
  -webkit-appearance: none;
}

.slider--input::-webkit-slider-thumb {
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid rgb(42, 138, 42);
  pointer-events: auto;
  -webkit-appearance: none;
  background: rgb(107, 216, 107);
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="style.css" />
    <title>Double-range slider</title>
  </head>
  <body>
    <div >
      <div >
        <div ></div>
        <div >
          <input type="range"  min="0" , max="999999" step="10" value="250000" />
          <input type="range"  min="0" , max="999999" step="10" value="750000" />
        </div>
      </div>
    </div>

    <script src="double-range-slider.js"></script>
  </body>
</html>

CodePudding user response:

e.target.className === 'input--min' will always return false. If you put e.target.className in a console log you will see "slider--input input--min".

Here's the correct way for your condition

  •  Tags:  
  • Related