如何防止多个句柄在 jQuery UI 滑块中重叠?
How to keep multiple handles from overlapping in jQuery UI slider?
我想要一个 jQuery UI 带有两个手柄的滑块,可以设置它们的值彼此独立。
我还希望对它们进行样式设置,使一个手柄位于滑块的 "on top" 而另一个手柄位于下方。
问题是当两个句柄共享相同的值时,jQuery UI 认为其中一个句柄仍然是 "on top" 所以需要移动其中一个句柄在另一个可以调整之前。如果顶部手柄设置为一个值,然后将底部手柄移动到相同的值,则顶部手柄不能移动,直到底部手柄先移开。这个场景很难描述所以下面有一个fiddlelink。
有什么方法可以指定 jQuery UI 我正在单击的句柄是我想要主动移动的句柄吗?
JS Fiddle link 这里:
https://jsfiddle.net/rqpndLsL/
我的滑块是如何设置的:
$('.slider').slider({
min: 0,
max: 400,
step: 50,
values: [200, 200],
range: false,
})
我不确定这是否是最好的解决方法,但这个解决方案最终对我有用。我在这里回答,以防其他人遇到同样的问题。
查看 jQuery API,活动手柄似乎是根据某种距离计算的,而我想要的只是被点击的手柄。
我覆盖了 jQuery UI _mouseCapture 事件并将其自定义为对点击敏感。它还需要一些硬设置 CSS class 检测来确定哪个句柄是活动句柄。
通过这样做,我能够避免修改任何库文件,并且只更改了少量的原始功能。
// Create the slider.
var slider = $('.slider').slider({//OPTIONS HERE});
// Get the slider and replace the _mouseCapture function with a custom one.
slider.data('ui-slider')._mouseCapture = function(event) {
var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
that = this,
o = this.options;
if ( o.disabled ) {
return false;
}
this.elementSize = {
width: this.element.outerWidth(),
height: this.element.outerHeight()
};
this.elementOffset = this.element.offset();
// Get the element that the click was triggered on and set that to closestHandle. There was a bunch of distance calculation here previously - that has been removed.
currentHandle = $(event.toElement);
closestHandle = currentHandle;
// 'custom-handle-1' is a custom class I give to the left slider handle
// I know that my sliders will only have 2 values (so index will either be 0 or 1 always).
if (closestHandle.hasClass('custom-handle-1')) {
index = 0;
}
else {
index = 1;
}
allowed = this._start( event, index );
if ( allowed === false ) {
return false;
}
this._mouseSliding = true;
this._handleIndex = index;
this._addClass( closestHandle, null, "ui-state-active" );
closestHandle.trigger( "focus" );
offset = closestHandle.offset();
mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
top: event.pageY - offset.top -
( closestHandle.height() / 2 ) -
( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
};
if ( !this.handles.hasClass( "ui-state-hover" ) ) {
this._slide( event, index, normValue );
}
this._animateOff = true;
return true;
};
缺点是这可能与 jQuery UI 的未来版本不兼容,但这是未来的问题(目前是 1.12.1)。
我想要一个 jQuery UI 带有两个手柄的滑块,可以设置它们的值彼此独立。
我还希望对它们进行样式设置,使一个手柄位于滑块的 "on top" 而另一个手柄位于下方。
问题是当两个句柄共享相同的值时,jQuery UI 认为其中一个句柄仍然是 "on top" 所以需要移动其中一个句柄在另一个可以调整之前。如果顶部手柄设置为一个值,然后将底部手柄移动到相同的值,则顶部手柄不能移动,直到底部手柄先移开。这个场景很难描述所以下面有一个fiddlelink。
有什么方法可以指定 jQuery UI 我正在单击的句柄是我想要主动移动的句柄吗?
JS Fiddle link 这里: https://jsfiddle.net/rqpndLsL/
我的滑块是如何设置的:
$('.slider').slider({
min: 0,
max: 400,
step: 50,
values: [200, 200],
range: false,
})
我不确定这是否是最好的解决方法,但这个解决方案最终对我有用。我在这里回答,以防其他人遇到同样的问题。
查看 jQuery API,活动手柄似乎是根据某种距离计算的,而我想要的只是被点击的手柄。
我覆盖了 jQuery UI _mouseCapture 事件并将其自定义为对点击敏感。它还需要一些硬设置 CSS class 检测来确定哪个句柄是活动句柄。
通过这样做,我能够避免修改任何库文件,并且只更改了少量的原始功能。
// Create the slider.
var slider = $('.slider').slider({//OPTIONS HERE});
// Get the slider and replace the _mouseCapture function with a custom one.
slider.data('ui-slider')._mouseCapture = function(event) {
var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
that = this,
o = this.options;
if ( o.disabled ) {
return false;
}
this.elementSize = {
width: this.element.outerWidth(),
height: this.element.outerHeight()
};
this.elementOffset = this.element.offset();
// Get the element that the click was triggered on and set that to closestHandle. There was a bunch of distance calculation here previously - that has been removed.
currentHandle = $(event.toElement);
closestHandle = currentHandle;
// 'custom-handle-1' is a custom class I give to the left slider handle
// I know that my sliders will only have 2 values (so index will either be 0 or 1 always).
if (closestHandle.hasClass('custom-handle-1')) {
index = 0;
}
else {
index = 1;
}
allowed = this._start( event, index );
if ( allowed === false ) {
return false;
}
this._mouseSliding = true;
this._handleIndex = index;
this._addClass( closestHandle, null, "ui-state-active" );
closestHandle.trigger( "focus" );
offset = closestHandle.offset();
mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
top: event.pageY - offset.top -
( closestHandle.height() / 2 ) -
( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
};
if ( !this.handles.hasClass( "ui-state-hover" ) ) {
this._slide( event, index, normValue );
}
this._animateOff = true;
return true;
};
缺点是这可能与 jQuery UI 的未来版本不兼容,但这是未来的问题(目前是 1.12.1)。