如何在jQuery UI滑块中保持多个句柄重叠?

时间:2016-11-09 15:59:55

标签: javascript jquery html jquery-ui jquery-ui-slider

我希望有一个带有两个句柄的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,
})

1 个答案:

答案 0 :(得分:0)

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

查看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)。