【问题标题】:How to fire a "change" event when the user releases the range slider, even if the value hasn't changed当用户释放范围滑块时如何触发“更改”事件,即使值没有改变
【发布时间】:2019-07-05 16:07:00
【问题描述】:

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 事件,即使值没有改变?

【问题讨论】:

    标签: javascript jquery html events dom-events


    【解决方案1】:

    点击替换更改:-

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

    【讨论】:

    • 如果您向下拖动光标并在输入范围之外松开鼠标,则不起作用。
    • OP 是正确的。如果将滑块拖到最后,释放它,然后再次单击滑块,将鼠标拖离滑块而不移动滑块,然后释放它,它不会触发单击或更改事件。
    • 问题已修复。我相信您的解决方案比公认的答案更好。此答案仅在与滑块交互时触发单个事件,并且不会在整个文档上创建 mouseup 侦听器。
    【解决方案2】:

    试试这个。在controlmousedown 中将变量设置为true 并在documentmouseup 事件中检查它

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

    【讨论】:

      猜你喜欢
      • 2013-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多