How to fire a “change” event when the user releases the range slider, even if the value hasn't changed

问题: var control = $('#control'); var zone = 2; const SNAP_TARGET = 1; const SNAP_DISTANCE = 0.1; const LEEWAY = 0.01; function getSliderInfo() { const sl...

问题:

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'>

I made a slider with the extra feature of allowing the user to easily set it to the exact center. Try it and see how it stops it right in the middle, but you can slide it anywhere if you continue dragging it past the stop zone or drag it the other way.

If the user drags the slider knob to the midpoint and releases their mouse, the "stickiness" should be removed so it doesn't start out "stuck" when they begin to drag it again.

The problem is, if the user slides it away from the midpoint where it started and then slides it back to the midpoint, the change event won't fire because the final value didn't actually change.

I tried using mouseup/pointerup instead of change but there's a case where it doesn't work. You can click and hold down on the slider knob, then move your cursor vertically outside the slider's area, and release the mouse. The mouseup/pointerup event doesn't fire since you released the button when your cursor was outside of the input.

How to fire a change event when the user releases the range slider, even if the value hasn't changed?


回答1:

Try this.Set a variable to true in mousedown of control and check it in mouseup event of 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'>


回答2:

replace change by click :-

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'>

  • 发表于 2019-02-14 18:25
  • 阅读 ( 177 )
  • 分类:网络文章

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除