jQuery Slider,组合值 - 小增量有困难

时间:2010-10-17 02:18:28

标签: jquery-ui

我设计了一个jQuery Slider Control,它采用了一个“池”点,并允许它们在多个滑块之间分配。它工作得很好,除了我有一些非常小的溢出增量的问题。

基本上,可以根据鼠标移动进行大量调整,因此可以让某人在滑块中“花费”更多的时间。我不知道如何处理这个问题。以下是我的整个代码。

要测试它,使用此代码构建一个简单的HTML页面,并尝试将前两个滑块一直滑动到500,然后尝试滑动第三个。它不会滑动(预期的行为)。

然后,将第一个或第二个滑块向后滑动一点(减去),然后向前滑动第三个滑块。你偶尔可以超越预期的“花费”范围。

示例将需要jQuery UI,谷歌CDN的最新版本。

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.js"></script>

的Javascript

<style type="text/css">
    #eq > div {
        width:300px;
    }
    #eq > div .slider {
        width: 200px; float: left;
    }
    #eq > div > span {
        float: right;
    }
</style>

<script type="text/javascript">
    $(document).ready(function () {
        var spendable = 1000;
        var spent = 0;

        function spend(quantity) {
            spent += quantity;
            $('#attemptedToSpend').text(spent);
        }

        function change(previous, current) {
            var adjustment = (current - previous);
            $('#change').text(adjustment);
            return adjustment;
        }

        function calculateSpent() {
            var totalled = 0;

            $("#eq .slider").each(function () {
                totalled += parseInt($(this).parent('div:eq(0)').find('.spent').text());
            });

            $('#spent').text(totalled);
        }

        $("#eq .slider").each(function () {
            var current = 0;
            var previous = 0;
            var adjustment = 0;

            $(this).slider({
                range: "min",
                value: 0,
                min: 0,
                max: 500,
                step: 1,
                animate: true,
                orientation: "horizontal",
                start: function (event, ui) {
                },
                stop: function (event, ui) {
                },
                slide: function (event, ui) {
                    // set the current value to whatever is selected.
                    current = ui.value;

                    // determine the adjustment being made relative to the last
                    // adjustment, instead of just the slider's value.
                    adjustment = change(previous, current);

                    if (spent >= spendable) {
                        if (adjustment > 0)
                            return false;
                    }

                    // spend the points, if we are able to.
                    spend(adjustment);

                    // set the previous value
                    previous = current;

                    $(this).parent('div:eq(0)').find('.spent').text(current);

                    calculateSpent();

                }
            });
        });
    });
</script>

HTML

<p class="ui-state-default ui-corner-all" style="padding: 4px; margin-top: 4em;">
    <span style="float: left; margin: -2px 5px 0 0;"></span>Distribution
</p>
    <strong>Total Points Spendable: </strong><div id="spendable">1000</div>
    <strong>Total Points Spent (Attempted): </strong><div id="attemptedToSpend">0</div>
    <strong>Total Points Spent: </strong><div id="spent">0</div>
    <strong>Change: </strong><div id="change">0</div>
    <div id="status"></div>

<div id="eq">
    <div style="margin: 15px;" id="test1">Test1</div>
    <br />
    <div class="slider"></div><span class="spent">0</span>

    <div style="margin: 15px;" id="test2">Test2</div>
    <br />
    <div class="slider"></div><span class="spent">0</span>

    <div style="margin: 15px;" id="test3">Test3</div>
    <br />
    <div class="slider"></div><span class="spent">0</span>

    <div style="margin: 15px;" id="test4">Test4</div>
    <br />
    <div class="slider"></div><span class="spent">0</span>

    <div style="margin: 15px;" id="test5">Test5</div>
    <br />
    <div class="slider"></div><span class="spent">0</span>
</div>

1 个答案:

答案 0 :(得分:1)

我尝试保持你的脚本完整,但最终重写了它。现在它应该是坚实的。好消息:我只更改了JS,其他一切都完好无损,但我不再更新所有监控字段。

DEMO

$(
  function()
  {
    var
        maxValueSlider = 500,
        maxValueTotal = 1000,
        $sliders = $("#eq .slider"),
        valueSliders = [],
        $displaySpentTotal = $('#spent');

    function arraySum(arr)
    {
      var sum = 0, i;
      for(i in arr) sum += arr[i];
      return sum;
    }

    $sliders
      .each(
        function(i, slider)
        {
          var
            $slider = $(slider),
            $spent = $slider.next('.spent');
          valueSliders[i] = 0;
          $slider
            .slider(
              {
                range: 'min',
                value: 0,
                min: 0,
                max: maxValueSlider,
                step: 1,
                animate: true,
                orientation: "horizontal",
                slide:
                  function(event, ui)
                  {
                    var
                      sumRemainder = arraySum(valueSliders) - valueSliders[i],
                      adjustedValue = Math.min(maxValueTotal - sumRemainder, ui.value);
                    valueSliders[i] = adjustedValue;
                    // display the current total
                    $displaySpentTotal.text(sumRemainder + adjustedValue);
                    // display the current value
                    $spent.text(adjustedValue);
                    // set slider to adjusted value
                    $slider.slider('value', adjustedValue);

                    // stop sliding (return false) if value actually required adjustment
                    return adjustedValue == ui.value;
                  }
              }
            );
        }
      );
  }
);