多个jQuery-UI滑块的总和

时间:2010-08-15 05:49:27

标签: jquery jquery-ui slider range

我正在尝试实现一个有4个jQuery-UI滑块的页面,我想要这样做,所以4个滑块的总和将永远不会超过400个。

我不介意这是实现的方式,它可以从0开始,一旦你更改1个滑块,剩余的可用总数减少或设置滑块超过最大值,减少另一个的值滑块。

P.S。滑块的增量为10。

所有想法&欢迎提出建议,如果您想测试,我已经设置了jsFiddle

6 个答案:

答案 0 :(得分:13)

好吧,你去吧:

var sliders = $("#sliders .slider");

sliders.each(function() {
    var value = parseInt($(this).text(), 10),
        availableTotal = 400;

    $(this).empty().slider({
        value: 0,
        min: 0,
        max: 400,
        range: "max",
        step: 10,
        slide: function(event, ui) {
            // Update display to current value
            $(this).siblings().text(ui.value);

            // Get current total
            var total = 0;

            sliders.not(this).each(function() {
                total += $(this).slider("option", "value");
            });

            // Need to do this because apparently jQ UI
            // does not update value until this event completes
            total += ui.value;

            var max = availableTotal - total;

            // Update each slider
            sliders.not(this).each(function() {
                var t = $(this),
                    value = t.slider("option", "value");

                t.slider("option", "max", max + value)
                    .siblings().text(value + '/' + (max + value));
                t.slider('value', value);
            });
        }
    });
});

以下是一个简单的演示:http://jsfiddle.net/yijiang/Y5ZLL/4/

答案 1 :(得分:10)

制作上述答案的更新版本,以显示100%的百分比。因此,当您向上调整一个滑块时,另外两个滑块会减少,使每个滑块的百分比加起来达到100%。还可以轻松设置初始值

JSfiddle

var sliders = $("#sliders .slider");
var availableTotal = 100;

sliders.each(function() {
    var init_value = parseInt($(this).text());

    $(this).siblings('.value').text(init_value);

    $(this).empty().slider({
        value: init_value,
        min: 0,
        max: availableTotal,
        range: "max",
        step: 2,
        animate: 0,
        slide: function(event, ui) {

            // Update display to current value
            $(this).siblings('.value').text(ui.value);

            // Get current total
            var total = 0;

            sliders.not(this).each(function() {
                total += $(this).slider("option", "value");
            });

            // Need to do this because apparently jQ UI
            // does not update value until this event completes
            total += ui.value;

            var delta = availableTotal - total;

            // Update each slider
            sliders.not(this).each(function() {
                var t = $(this),
                    value = t.slider("option", "value");

                var new_value = value + (delta/2);

                if (new_value < 0 || ui.value == 100) 
                    new_value = 0;
                if (new_value > 100) 
                    new_value = 100;

                t.siblings('.value').text(new_value);
                t.slider('value', new_value);
            });
        }
    });
});

答案 2 :(得分:5)

我发现当其他滑块(你正在移动的滑块以外的滑块)移动时,它会分散注意力。我已经修改了易江小提琴,现在只需要在你达到400时就停止它。如果你想让滑块更高,你首先必须降低其中一个,就像第一个一样,但它保持滑块相对于总体。

这意味着当你有一个25%的滑块和50%的另一个滑块时,它们看起来分别是25和50。

JSfiddle

var sliders = $("#sliders .slider");

sliders.each(function() {
    var value = parseInt($(this).text(), 10),
        availableTotal = 400;

    $(this).empty().slider({
        value: 0,
        min: 0,
        max: 400,
        range: "max",
        step: 10,
        animate: 100,
        slide: function(event, ui) {

            // Get current total
            var total = 0;    

            sliders.not(this).each(function() {
                total += $(this).slider("option", "value");
            });    


            var max = availableTotal - total;            

            if (max - ui.value >= 0) {
                // Need to do this because apparently jQ UI
                // does not update value until this event completes
                total += ui.value;
                console.log(max-ui.value);
                $(this).siblings().text(ui.value);
            } else {
                return false;
            }
        }
    });
});

答案 3 :(得分:0)

这些答案中没有一个对于以任何有效的方式改变滑块之间的关系是最有效的...大多数人在计算中留下一个或多个或者不尊重总体限制,我需要一些东西允许用户在HTML5游戏中挑选他们的筹码所以如果其他人有类似的问题,我想出了这个...如果你不需要把它绑在更改投注筹码之类的东西上那么就拿出来停止选项或更改它以满足您的需求

    <div id="chip_holder" style="float:right;margin-right:20px;">
    <ul id="sliders">
    <?php
    $chips = array("1" => array("blue", "1 Point", "1"), "5" => array("red", "5 Points", "5"), "10" => array("gold", "10 Points", "10"));

        $t = 0;
        $value_per_row = floor($my_points / count($chips));
          $totalc = 0;
        foreach($chips as $key => $value){
        $value = floor($value_per_row / $value[2]);
        $totalc = $totalc + $value_per_row;
        ?>
        <li style="display:inline-block;">
              <input type="number" style="display:none;" id="hidden_value_<?php echo $key; ?>" value="<?php echo floor($value);  ?>" min="0" max="<?php echo $my_points; ?>" step="<?php echo $chips[$key][2]; ?>" />
              <span id="slide_<?php echo $key; ?>" title="<?php echo $key; ?>" class="chip_slider" alt="<?php echo $key / $my_points; ?>"></span>
              <span id="chip_label_<?php echo $key; ?>" title="<?php echo $key; ?>" class="chip_label"><?php echo $value; ?></span>
        </li>
    <?php
        $t++;
        }
        if($totalc < $my_points){
        $min = min(array_keys($chips));
        $remainder = floor(($my_points - $totalc) / $chips[$min][2]);
    ?>
        <script>

            $('#hidden_value_<?php echo $min; ?>').val(parseInt($('#hidden_value_<?php echo $min; ?>').val()) + parseInt(<?php echo $remainder; ?>));
            $('#chip_label_<?php echo $min; ?>').text(parseInt($('#hidden_value_<?php echo $min; ?>').val()));
        </script>
        <?php } ?>
            <li id="checkout_button" onclick="javascript: checkout_now();"><?php echo CASHOUT; ?></li>

        </ul>
         <ul id="chips_stay_put">
         <?php
            $t = 0;
            foreach($chips as $key => $value){
            ?>
              <li class="chip_holder" style="width:70px;">
                  <span id="chip_holder_<?php echo $key; ?>" class="<?php echo $value[0]; ?>" alt="<?php echo $key; ?>"></span>
             </li>
                <?php
            $t++;
            }
        ?>
        </ul>
        </div>
<script>
 function drop_chips(id, chips){

$('.chip_label').each(function(){

        id =$(this).attr('id');
         idx =$('#' + id).attr('title');
    chips = parseInt($('#chip_label_' + idx).text());
    cls = $('#chip_holder_' + idx).attr('class');

    $('#chip_holder_' + idx).html('');

    m = minMaxTitle($('.chip.' + cls));

    if(m>0){
        start = 0;
    }else{
        start = m;
    }
    htmlH = '';

        while(m<=chips){
        start= start + m;
            zIndex = parseInt(start) + parseInt(100);

            htmlH += '<span id="chip_' + idx + '_' + m + '" class="chip ' + cls + '" style="position:absolute;top:-'+ (m * 3) + 'px;z-index:' + zIndex + ';" alt="' + cls + '" title="' +m+ '">' + idx +  '</span>';

            m++;

    }

    $('#chip_holder_' + idx).html(htmlH);


        $('.chip').draggable({
          drag: function( event, ui ) {
              var snapTolerance = $(this).draggable('option', 'snapTolerance');
              var topRemainder = ui.position.top % 20;
              var leftRemainder = ui.position.left % 20;

              if (topRemainder <= snapTolerance) {
              ui.position.top = ui.position.top - topRemainder;
              }

              if (leftRemainder <= snapTolerance) {
              ui.position.left = ui.position.left - leftRemainder;
              }
          } ,

          revert : function(event, ui) {
                // on older version of jQuery use "draggable"
                  // $(this).data("draggable")
                  // on 2.x versions of jQuery use "ui-draggable"
                  // $(this).data("ui-draggable")
                  $(this).data("uiDraggable").originalPosition = {
                  top : 0,
                  left : 0
                  };
                  // return boolean
                  return !event;
                  // that evaluate like this:
                  // return event !== false ? false : true;
              }

        });
    });

}
var sliders = $("#sliders .chip_slider");

sliders.each(function() {
    var slider_id;
    var value = parseInt($(this).text(), 10),
        availableTotal = parseInt($('#my_points_hidden').val());

    $(this).empty().slider({
        value: parseInt($('#' + $(this).attr('id')).prev('input').val()),
        min: 0,
        max: parseInt($('#' + $(this).attr('id')).prev('input').attr('max')),
        range:parseInt($('#' + $(this).attr('id')).prev('input').attr('max')),
        orientation:"vertical",
        step: 1,
        animate: 100,
        stop: function( event, ui ) { drop_chips() },
        slide: function(event, ui) {

         // Update display to current value
            $(this).siblings('.value').text(ui.value);

            // Get current total
            var total = 0;

        var slider_id = $(this).attr('title');

            sliders.not(this).each(function() {
                total += $(this).slider("option", "value");
            });

            // Need to do this because apparently jQ UI
            // does not update value until this event completes
            total += ui.value;

            var delta = availableTotal - total;

            // Update each slider
            sliders.not(this).each(function() {
                var t = $(this),
                    value = t.slider("option", "value");

                var new_value = value + (delta/2);

                if (new_value < 0 || ui.value == 100) 
                    new_value = 0;
                if (new_value > 100) 
                    new_value = 100;

                t.siblings('.value').text(new_value);
                t.slider('value', new_value);
                id = $(this).attr('id');

                title = $('#' + id).attr('title');
                initial_slider = total - new_value;
                console.log(slider_id);
        $('#chip_label_' + slider_id).text(parseInt(parseInt(ui.value) / parseInt($('#hidden_value_' + slider_id).attr('step'))));
                $('#chip_label_' + title).text(parseInt(parseInt(new_value) / parseInt($('#hidden_value_' + title).attr('step'))));
              });

        }

    });
});

</script>

答案 4 :(得分:0)

该线程是我努力构建此线程的一个很好的起点,希望它能对其他人有所帮助。 https://codepen.io/jmester13/pen/jOEyNEe

$(document).ready(function() {
  slider = new Slider();
});

var Slider = (function() {

  var Slider = function() {

    this.initialise();
  }

  Slider.prototype = {

    initialise: function() {
      this.vars();
      this.setup();
      this.slideEvent();
    },

    vars: function() {
      // vars
      _this = this;
      this.container = $('.sliders');
      this.slider = $('.slider');
      this.slide = $('.slide');
      this.controls = $('.control');
      this.value = $('.value');
      this.totalPercentage = 100;
    },

    setup: function() {
      // set equal width depending on how many sliders there are when initalised 
      var counter = 0;
      this.slide.each(function() {
        counter++;
      });

      var initWidth = this.totalPercentage / counter;

     this.slide.width(initWidth + '%');
     this.slide.attr('data-percent', initWidth + '%');
     this.value.text(initWidth + '%');
    },

    getPercentWidth: function(target) {
      // get percentage of current width
      target.attr('data-percent', (100 * parseFloat(target.css('width')) / parseFloat(target.parent().css('width'))));
    },

    slideEvent: function() {
      // listen for mouse down on the controls
      this.controls.on('mousedown', function(event) {
        this.slideDrag(event);
      }.bind(this));
    },

    slideDrag: function(event) {
      event.preventDefault();

      this.target = $(event.target);
      this.prevMousePos = 0;

      this.target.parent().addClass('active');
      // listen mousemove and mouseup events on the document: only if the mousedown happend on one of the controls 
      $(document).on('mousemove', this.slideMove);
      $(document).on('mouseup', this.slideEnd);
    },

    slideMove: function() {
      _this.mousePos = event.pageX; 
      _this.amount = [];

      // get info on widths, offsets and positions
      var offset = _this.slider.offset().left;
      var sliderWidth = _this.slider.width();
      var posX = Math.min(Math.max(0, _this.mousePos - offset), sliderWidth);   

      // checks direction
      if (_this.mousePos < _this.prevMousePos)  {
        _this.direction = 'left';
      } else {
        _this.direction = 'right';
      }

      //console.log(_this.direction);

      // update mouse position
      _this.prevMousePos = _this.mousePos;



      // set new width of the active slider
      _this.target.parent().width(posX / sliderWidth * 100 + '%');
      _this.calcPercent();
    },

    calcPercent: function() {
      var totalWidth = 0;
      var sliderLength = 0;
      var leftoverAmount = 0;

      // loop through each slide
      _this.slide.each(function() {

        sliderLength++;
        _this.getPercentWidth($(this));

        if ($(this).hasClass('active')) {
          // set active percentage
          _this.active = parseFloat($(this).attr('data-percent')).toFixed(0);

        } else {

          // add non active widths into an array

          _this.amount.push(parseFloat($(this).attr('data-percent')).toFixed(0));
        }

       //totalWidth += parseFloat($(this).attr('data-percent'));

      });

      // find out the leftover amount
      leftoverAmount = _this.totalPercentage - _this.active;
      _this.nonActiveAmount = 0;
      $.each(_this.amount, function() {

       _this.nonActiveAmount += parseFloat(this) ;
      });

      var x = leftoverAmount / 100;
      var y = _this.nonActiveAmount / 100;
      var z = _this.active;


      _this.slide.each(function() {

        if (!$(this).hasClass('active') || !$(this).hasClass('locked')) {
           console.log($(this));

          var v = x * (parseFloat($(this).attr('data-percent')) / y);
          $(this).width(v + '%');

        $(this).find('.value').text(Math.round(v) + '%');

        }
      });

    },

    slideEnd: function() {
      // kill the events on mouse up.
      _this.target.parent().removeClass('active');
      $(this).off('mousemove', slider.slideMove);
      $(this).off('mouseup', slider.slideEnd);
    },
  }

  return Slider;

}());

答案 5 :(得分:0)

对我来说是一次很好的经历。希望对其他人也有帮助。

$(document).ready(function(){
    var sliders = $(".slider");
    var available = 100;
    sliders.slider({
      value: 0,
      min: 0,
      max: available,
      range: "max",
      step: 1,
      animate: 0,
      slide: function(event, ui){
        var total = 0;
        var arr = new Array();
        sliders.not(this).each(function() {
          var t = $(this);
          arr.push(t);
          total += t.slider("option", "value");
        });
        total += ui.value;							
        var delta = available - total;
        if(delta<0){
          return false;
        }
        $(this).parent('.slidecontainer').find('.setval').text(ui.value);
        $.each(arr, function(idx, ele){
          let v = ele.slider("option", "value");
          let vm = v + delta;
          $(ele).parent('.slidecontainer').find('.max').text(vm);
        });
      }
    });                    
  });
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<div class="col-lg-8">
  <div class="slidecontainer">
    <div class="slider"></div>
    <p class="value">Value:<span class="setval"></span> 
    Max: <span class="max"></span>
    </p>
  </div>
</div>	
<div class="col-lg-8">
  <div class="slidecontainer">
    <div class="slider"></div>
    <p class="value">Value:<span class="setval"></span> 
    Max: <span class="max"></span>
    </p>
  </div>
</div>