如何防止多个句柄在 jQuery UI 滑块中重叠?

Posted

技术标签:

【中文标题】如何防止多个句柄在 jQuery UI 滑块中重叠?【英文标题】:How to keep multiple handles from overlapping in jQuery UI slider? 【发布时间】:2017-03-23 12:13:42 【问题描述】:

我想要一个带有两个句柄的 jQuery UI 滑块,可以将它们的值设置为彼此独立。

我还希望它们被设计成一个手柄在滑块的“顶部”,而另一个手柄在下面。

问题是当两个句柄共享相同的值时,jQuery UI 认为其中一个句柄仍然“在顶部”,因此需要移动其中一个句柄才能调整另一个句柄。如果顶部手柄设置为一个值,则底部手柄移动到相同的值,直到底部手柄先移开,顶部手柄才能移动。这个场景很难描述,所以下面有一个小提琴链接。

有什么方法可以向 jQuery UI 指定我正在单击的句柄是我想要主动移动的句柄吗?

JS Fiddle 链接在这里: https://jsfiddle.net/rqpndLsL/

我的滑块是如何设置的:

$('.slider').slider(
    min: 0,
  max: 400,
  step: 50,
  values: [200, 200],
  range: false,
)

【问题讨论】:

实际问题是min & max 值,底部处理程序无法移动的原因是逻辑上 Max 不能小于 Min 值 最小值和最大值用于设置滑块本身的范围 - 任一手柄可以达到多高或多低。我删除了这些值,但问题仍然存在。 查看Fiddle 还是不行。如果您将顶部手柄拖到底部手柄的顶部,然后尝试移动底部手柄,它会移动顶部手柄。当两个句柄具有相同的值时会发生这种情况。在您的示例中很难使两个句柄具有相同的值,因为步长设置为 1,但如果将其更改为 500 之类的值,则更容易看到问题。 嗯好的 ... 现在添加了一个新标签 - “jquery-ui-slider”。希望通过专家的意见接触到合适的人。 【参考方案1】:

我不确定这是否是最好的方法,但这个解决方案最终对我有用。我在这里回答,以防其他人遇到同样的问题。

查看 jQuery API,看起来活动句柄是根据某种距离计算的,而我想要的只是被点击的句柄。

我覆盖了 jQuery UI _mouseCapture 事件并将其自定义为对点击敏感。它还需要一些硬设置的 CSS 类检测来确定哪个句柄是活动句柄。

通过这样做,我能够避免修改任何库文件,并且只更改了少量原始函数。

// 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 Slider,这可能像你提到的那样不好。但公平地说,我想对于这个问题,你不得不采取非常规的方式,因为图书馆没有提供它。至少你找到了一个很好的解决方案。干杯

以上是关于如何防止多个句柄在 jQuery UI 滑块中重叠?的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 Jquery UI 滑块句柄

如何在 jQuery Ui 滑块中添加自定义增量和减量计数器

如何在 jQuery UI 中创建多范围时间滑块

如何在运行中向 jQuery 滑块添加多个句柄

如何限制 jQuery UI 滑块的范围?

如何阻止jquery UI滑块滑动到排水沟之外?