代码之家  ›  专栏  ›  技术社区  ›  Marko

多个jqueryui滑块的组合总计

  •  9
  • Marko  · 技术社区  · 14 年前

    我正在尝试实现一个页面,其中有4个jqueryui滑块,我想使它使所有4个滑块的总和永远不会超过400。

    另外,滑块以10为增量。

    所有想法;欢迎提出建议,我已经建立了一个 jsFiddle

    4 回复  |  直到 14 年前
        1
  •  14
  •   Yi Jiang    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/

        2
  •  12
  •   Tony    11 年前

    做了一个更新版本的上述答案显示百分率为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);
                });
            }
        });
    });
    
        3
  •  7
  •   Recognizer    8 年前

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

    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;
                }
            }
        });
    });
    
        4
  •  0
  •   Edward Goodnow    10 年前

    这些答案中没有一个对以任何有效的方式改变滑块之间的关系是最不有效的…大多数答案在计算中遗漏了一个或多个或不尊重整体限制,我需要一些东西来允许用户在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>
    
        5
  •  0
  •   Joe Mester    4 年前

    这个线程是一个伟大的出发点,我努力建设这个,希望它能帮助别人。 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;
    
    }());
    
        6
  •  0
  •   Sk Mourya    4 年前

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

    $(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>