Как вызвать событие «change», когда пользователь отпускает ползунок диапазона, даже если значение не изменилось - PullRequest
0 голосов
/ 12 февраля 2019

var control = $('#control');

var zone = 2;
const SNAP_TARGET = 1;
const SNAP_DISTANCE = 0.1;
const LEEWAY = 0.01;

function getSliderInfo() {
  const sliderVal = parseFloat(control.val());
  return [sliderVal, sliderVal - SNAP_TARGET];
}

control.on('input', function () {
  const [position, difference] = getSliderInfo();
  let offset = -difference;
  if (difference < 0 && zone === 3) {
    if (difference <= -SNAP_DISTANCE) {
      zone = 1;
    }
  }
  else if (difference > 0 && zone === 1) {
    if (difference >= SNAP_DISTANCE) {
      zone = 3;
    }
  }
  else {
    offset = 0;
    if (zone === 2) {
      if (Math.abs(difference) > LEEWAY) {
        zone = difference < 0 ? 1 : 3;
      }
      else {
        control.val(1);
      }
    }
  }
  control.val(position + offset);
});

control.on('change', function () {
  const difference = getSliderInfo()[1];
  if (Math.abs(difference) <= LEEWAY) {
    control.val(1);
    zone = 2;
  }
  console.log('change event occured');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id='control' type='range' min='0' max='2' value='1' step='any'>

Я сделал слайдер с дополнительной функцией, позволяющей пользователю легко установить точный центр.Попробуйте и посмотрите, как он останавливается прямо посередине, но вы можете сдвинуть его куда угодно, если продолжите перетаскивать его за пределы зоны остановки или перетаскивать его другим способом.

Если пользователь перетаскивает регулятор ползунка вВ средней точке и отпускает свою мышь, «липкость» должна быть удалена, чтобы она не начинала «застревать», когда они снова начинают ее перетаскивать.

Проблема в том, что если пользователь сдвинет его от средней точки, в которой он начался, а затем вернет его обратно к средней точке, событие change не сработает, поскольку окончательное значение фактически не изменилось.

Я пытался использовать mouseup / pointerup вместо change, но есть случай, когда он не работает.Вы можете нажать и удерживать регулятор слайдера, затем переместить курсор вертикально за пределы области слайдера и отпустить мышь.Событие mouseup / pointerup не срабатывает, поскольку вы отпустили кнопку, когда курсор находился за пределами ввода.

Как вызвать событие change, когда пользователь отпускает ползунок диапазона, дажеесли значение не изменилось?

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Попробуйте это. Установите переменную true в mousedown из control и отметьте ее в mouseup событии document

var control = $('#control');
let mousedown = false;
var zone = 2;
const SNAP_TARGET = 1;
const SNAP_DISTANCE = 0.1;
const LEEWAY = 0.01;

function getSliderInfo() {
  const sliderVal = parseFloat(control.val());
  return [sliderVal, sliderVal - SNAP_TARGET];
}
//control.on('click',function(){console.log("changed")})
control.on('input', function () {
  const [position, difference] = getSliderInfo();
  let offset = -difference;
  if (difference < 0 && zone === 3) {
    if (difference <= -SNAP_DISTANCE) {
      zone = 1;
    }
  }
  else if (difference > 0 && zone === 1) {
    if (difference >= SNAP_DISTANCE) {
      zone = 3;
    }
  }
  else {
    offset = 0;
    if (zone === 2) {
      if (Math.abs(difference) > LEEWAY) {
        zone = difference < 0 ? 1 : 3;
      }
      else {
        control.val(1);
      }
    }
  }
  control.val(position + offset);
});
$(document).on('mouseup',function(){
  if(mousedown){
     change();
     mousedown = false;
  }
})

control.on('mousedown',() => mousedown = true);
function change() {
  const difference = getSliderInfo()[1];
  if (Math.abs(difference) <= LEEWAY) {
    control.val(1);
    zone = 2;
  }
  console.log('change event occured');
}
control.on('change', change);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id='control' type='range' min='0' max='2' value='1' step='any'>
0 голосов
/ 12 февраля 2019

заменить изменения, нажав: -

var control = $('#control');

var zone = 2;
const SNAP_TARGET = 1;
const SNAP_DISTANCE = 0.1;
const LEEWAY = 0.01;

function getSliderInfo() {
  const sliderVal = parseFloat(control.val());
  return [sliderVal, sliderVal - SNAP_TARGET];
}

control.on('input', function () {
  const [position, difference] = getSliderInfo();
  let offset = -difference;
  if (difference < 0 && zone === 3) {
    if (difference <= -SNAP_DISTANCE) {
      zone = 1;
    }
  }
  else if (difference > 0 && zone === 1) {
    if (difference >= SNAP_DISTANCE) {
      zone = 3;
    }
  }
  else {
    offset = 0;
    if (zone === 2) {
      if (Math.abs(difference) > LEEWAY) {
        zone = difference < 0 ? 1 : 3;
      }
      else {
        control.val(1);
      }
    }
  }
  control.val(position + offset);
});

control.on('mouseup', function () {
  const difference = getSliderInfo()[1];
  if (Math.abs(difference) <= LEEWAY) {
    control.val(1);
    zone = 2;
  }
  console.log('change event occured');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id='control' type='range' min='0' max='2' value='1' step='any'>
...