具有最大值和最小值的 jQuery 计数器

Posted

技术标签:

【中文标题】具有最大值和最小值的 jQuery 计数器【英文标题】:jQuery Counter with Max and Min Value 【发布时间】:2014-12-20 18:38:02 【问题描述】:

我正在构建一个计数器,当我按下鼠标时,它应该递增到 maxValue 并且递减不超过 0。我还可以选择将计数器重置为其初始值:0。此外,如果 maxValue 是一个偶数,它应该计数到那个数字。但是,如果 maxValue 是一个奇数,它应该计数到 number-1。

计数器似乎工作正常。但有时它往往会停留在两个值之间。我很确定当我在其中一个按钮上按下鼠标然后立即在另一个按钮上按下鼠标时会发生这种情况。有没有办法防止这种情况发生?我还想知道我的代码是否正确,是否有更简单的方法(可能有循环)?

这里是我的代码:

$(document).ready(function()
var maxValue = 3;
var count = 0;
// intervals used to regulate how fast the value will change on mousedown
var upInterval;
var downInterval;

$('#counter').html("<p>" + parseInt(count) + "</p>");

$('#up').mousedown(function()
 // if the maxValue is an even number
 if(maxValue % 2 == 0) 
    upInterval = setInterval(function()
        if(count < maxValue) 
            count++;
            $('#counter').html("<p>" + parseInt(count) + "</p>");
        
    ,180);
  
// if it's an odd number, subtract one
 else 
    upInterval = setInterval(function()
        if(count < maxValue-1) 
            count++;
            $('#counter').html("<p>" + parseInt(count) + "</p>");
        
    ,180);
 
).mouseup(function() 
    clearInterval(upInterval);       
); 

$('#down').mousedown(function()
    downInterval = setInterval(function()
        if(count > 0) 
            count--;
            $('#counter').html("<p>" + parseInt(count) + "</p>");
        
    ,180);
).mouseup(function() 
    clearInterval(downInterval);    
);

    $('#reset').click(function()
        count = 0;
        $('#counter').html("<p>" + parseInt(count) + "</p>");
    );

);

请记住,间隔是为了调节当我按下鼠标时数字应该以多快的速度变化,并阻止它增加或减少。

这是fiddle

谢谢!

【问题讨论】:

为什么不简单地增加 even 个数字 (2)? 如果它是偶数,我需要它增加所有数字直到 maxValue,奇数也一样,除了 maxValue 应该被解释为少一。例如:如果 maxValue = 13,那么它将最多计数 12 (1,2,3,4...12)。如果我理解正确,那么它只会按偶数计算,所以 (2,4,6...) 这不是我想要的。 哦,我明白了。秒来建立一个例子。 在偶数的情况下,您将在存储/返回时除以 2。 嗯不 - 他没有。请注意函数上方的变量 【参考方案1】:

jsBin demo (advanced use-case)

在上面的演示中,我创建了一个可以处理多个元素的用例。它还具有更好的用户体验,因为它使用 setTimeout(而不是间隔),只要您按住它就会逐渐提高计数速度。

jsBin demo

$(document).ready(function()

  var $counter = $("#counter p"), // Get the 'p' element
      max = 10,
      c   = 0,
      up  = true, // boolean // This will keep track of the clicked up/dn button
      itv; 

  function incDec()
    c = up ? ++c : --c; // value of `up` is true? increment, else: decrement
    c = Math.min(Math.max(c, 0), max); // dididababaduuuu!
    $counter.text(c);                  // Set current `c` into element
  

  $('#up, #down').on("mousedown", function(e)   
    up = this.id==="up";           // set to true if button in "up"; else: false
    incDec();                      // Trigger on sligle click
    clearInterval(itv);            // Clear some ongoing intervals
    itv=setInterval(incDec, 180);  // Do every 180 untill..
  ).on("mouseup mouseleave", function()        //      ..mouseup or mouseleave
    clearInterval(itv); 
  );


  $('#reset').click(function()
    c = 0;              // Reset to 0
    $counter.text(c);   // Show that "0"           
  ).click();           // Trigger a reset click on DOM ready

);

【讨论】:

关于代码本身的一件事:我建议将up 作为参数传递给函数incDec。在这种情况下,“全局”变量的风格不好,这是肯定的。 This example 是它最终的结果。 @Regent 好吧,在这种情况下不是这样。首先,您可以将整个代码包装在 IIFE 中。其次,要使代码可重用于更多计数器(在插件的情况下),您首先不会使用#...! :) 我已经尝试了mouseleavemouseout,但是出了点问题。我现在不能重复。计数器进行时的唯一方法(不在元素中,如果它可以称为“out”)是当您选择所有文本并将其移入页面时。但我怀疑这真的是需要解决的问题。 使用incDec(this.id==="up");function incDec(up) 是可重用和安全的(你不能调用函数而不是为up设置值。嗯,在JS你可以,但它会被视为@987654333 @ 在这种情况下)。 @Regent 我显然不明白你在说什么。这种情况下的代码是防弹的(显然它可以被优化......),但正如您所看到的,没有一个问题。 up 定义为 true。因此,它永远不会是 undefined, null 或其他。 (无论如何感谢您分享您的担忧)【参考方案2】:

我只能重现您描述的“卡住”,如果“mouseup”没有发生在元素本身上(例如,当您按下鼠标时将光标移出)。 所以这为我解决了它:

$('#up').mousedown(function()
    $(window).mouseup(function() 
        clearInterval(upInterval);       
    );

  // if the maxValue is an even number
  ....
);
// and so on

【讨论】:

在另一个事件处理程序中添加事件处理程序几乎总是非常糟糕的主意。

以上是关于具有最大值和最小值的 jQuery 计数器的主要内容,如果未能解决你的问题,请参考以下文章

计数排序与桶排序python实现

在 SQL 中选择具有一个最大值但另一个最小值的项目 [关闭]

16 位双精度值的最大值(和最小值)是多少?

只有数字、点和最小值的正则表达式

具有最小值/最大值的平均值和阴影的线图

计数排序