Как сохранить несколько дескрипторов от перекрытия в jQuery UI slider?

Я хочу иметь слайдер jQuery UI с двумя ручками, которые могут быть установлены с их значениями, независимыми друг от друга.

Я также хочу, чтобы они были стилизованы так, чтобы одна ручка была «сверху» слайдера, а другая-ниже.

Проблема заключается в том, что когда два дескриптора имеют одно и то же значение, jQuery UI думает, что один из дескрипторов все еще «сверху», поэтому один из дескрипторов должен быть перемещен, прежде чем другой может быть скорректирован. Если для верхнего дескриптора задано значение, то нижний дескриптор перемещается на то же значение, верхний дескриптор не может быть перемещен, пока нижний дескриптор не будет перемещен первым. Сценарий трудно описать, поэтому ниже есть ссылка fiddle.

Есть ли способ указать jQuery UI, что дескриптор, который я нажимаю, является тем, который я хочу активно перемещать?

JS Fiddle ссылка здесь:
https://jsfiddle.net/rqpndLsL/

Как настроить слайдер:

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

1 ответ

  1. Я не уверен, что это лучший способ, но это решение в конечном итоге работает на меня. Я отвечаю здесь на случай, если кто-то еще столкнется с той же проблемой.

    Глядя в API jQuery, похоже, что активный дескриптор вычисляется на основе некоторого расстояния, когда то, что я хотел, было просто дескриптором, который нажимается.

    Я отменил событие 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).