问题:
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'>