jqueryjquery-uijquery-slider

jQuery Sliders Moving at the same time - out of sync by one step


I have the following code:-

jQuery

jQuery('.slider').each(function() {
    var $el = jQuery(this);
    $el.slider({
        range: "max",
        min: $el.data('min'),
        max: $el.data('max'),
        value: $el.data('value'),
        step: $el.data('step'),
        slide: function(event, ui) {
            var percent = (100 / (jQuery(this).data('max') - jQuery(this).data('min'))) * jQuery(this).slider('value');

            jQuery('.slider').not(this).each(function() {
                jQuery(this).slider(
                    'value', 
                    ((jQuery(this).data('max') - jQuery(this).data('min')) / 100) * percent
                );
            });
            jQuery('.slider').each(function() {
                var thisTarget = jQuery(this).data('target');
                var thisValue = jQuery(this).slider('option','value');

                console.log(thisTarget,thisValue);

                jQuery(thisTarget+' span').html(thisValue);
            });

        },
    });
});

HTML

<div class="slider" data-min="3800" data-max="30000" data-value="3848" data-step="500" data-target=".calc-deposit"></div>
<div class="slider" data-min="15400" data-max="120000" data-value="15393" data-step="2000" data-target=".calc-loan"></div>
<div class="slider" data-min="57000" data-max="450000" data-value="57724" data-step="7500" data-target=".calc-mortgage"></div>

<div class="calc-deposit calc-center">£<span></span></div>
<div class="calc-loan calc-center">£<span></span></div>
<div class="calc-mortgage calc-center">£<span></span></div>

Here is the JSFIDDLE

It's all working as expected but as you drag the sliders, the other sliders seem to be either a step ahead or a step behind depending which way you are dragging the slider.

Any ideas why this is happening?


Solution

  • Just delay the callback of slide event, e.g:

    jQuery('.slider').each(function() {
      var $el = jQuery(this);
      $el.slider({
        range: "max",
        min: $el.data('min'),
        max: $el.data('max'),
        value: $el.data('value'),
        step: $el.data('step'),
        slide: function(event, ui) {
          clearTimeout(this.timeout);
          this.timeout = setTimeout(updateSliders.bind(this, event, ui))
        }
      });
    });
    
    function updateSliders(event, ui) {
      var percent = (100 / (jQuery(this).data('max') - jQuery(this).data('min'))) * jQuery(this).slider('value');
    
      jQuery('.slider').not(this).each(function() {
        jQuery(this).slider(
          'value',
          ((jQuery(this).data('max') - jQuery(this).data('min')) / 100) * percent
        );
      });
      jQuery('.slider').each(function() {
        var thisTarget = jQuery(this).data('target');
        var thisValue = jQuery(this).slider('option', 'value');
    
        console.log(thisTarget, thisValue);
    
        jQuery(thisTarget + ' span').html(thisValue);
      });
    }
    

    Updated jsFiddle