【问题标题】:Javascript: Ordinal suffix for numbers with specific CSS classJavascript:具有特定 CSS 类的数字的序号后缀
【发布时间】:2013-04-04 11:33:33
【问题描述】:

我正在尝试在带有序号后缀的特定表格中显示数字。该表始终显示来自 XML 文件的三个数字。数字显示排名,例如它们可能是第 6、第 120、第 131。输出是一个如下所示的表格:

<table>
    <tr>
        <td class='ordinal'>6</td>
        <td class='ordinal'>120</td>
        <td class='ordinal'>131</td>
    </tr>
</table>

理想情况下,我想使用 javascript,我在 stackoverflow 上找到了一些非常好的解决方案,例如 this one。但是,我正在努力将该函数应用于表中的所有数字,而不是单独输入每个数字。我尝试使用 CSS 类,以便我的函数如下所示:

<script type="text/javascript">
$(function(){
    $(".ordinal").each(function(){
        var j = i % 10;
        if (j == 1 && i != 11) {
            return i + "st";
        }
        if (j == 2 && i != 12) {
            return i + "nd";
        }
        if (j == 3 && i != 13) {
            return i + "rd";
        }
        return i + "th";
        });
})
</script>

但它不起作用,可能是因为我在某个地方搞砸了代码。也许这里有人可以帮助我并告诉我哪里出错了?

非常感谢您的帮助!

【问题讨论】:

    标签: javascript jquery ordinals


    【解决方案1】:

    我自己的建议是:

    $(".ordinal").text(function (i, t) {
        i++;
        var str = i.toString().slice(-1),
            ord = '';
        switch (str) {
            case '1':
                ord = 'st';
                break;
            case '2':
                ord = 'nd';
                break;
            case '3':
                ord = 'rd';
                break;
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            case '0':
                ord = 'th';
                break;
        }
        return i + ord;
    });
    

    JS Fiddle demo.

    这有效地获取递增的数字(i++,以便从 1 而不是 0 开始),将其转换为字符串,然后查看该字符串的最后一个数字。这应该适用于任何数字,因为序数完全基于最后一个数字。

    您还可以扩展 Number 原型来实现此功能:

    Number.prototype.ordinate = function(){
        var num = this + 1,
            last = num.toString().slice(-1),
            ord = '';
        switch (last) {
            case '1':
                ord = 'st';
                break;
            case '2':
                ord = 'nd';
                break;
            case '3':
                ord = 'rd';
                break;
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            case '0':
                ord = 'th';
                break;
        }
        return num.toString() + ord;
    };
    
    $(".ordinal").text(function (i, t) {
        return i.ordinate();
    });
    

    JS Fiddle demo.

    编辑提供了一个轻微的选择:

    Number.prototype.ordinate = function(){
        var num = this,
            last = num.toString().slice(-1),
            ord = '';
        switch (last) {
            case '1':
                ord = 'st';
                break;
            case '2':
                ord = 'nd';
                break;
            case '3':
                ord = 'rd';
                break;
            default:
                ord = 'th';
                break;
        }
        return num.toString() + ord;
    };
    
    $(".ordinal").text(function (i,t) {
        return t.replace(/(\d+)/g, function(a){
            return parseInt(a, 10).ordinate();
        });
    });
    

    JS Fiddle demo.

    这实质上是遍历每个 .ordinal 元素,用添加了序号后缀的(相同)数字替换存在的数字。


    已编辑以解决以下 cmets 中提出的问题,即 111213 收到的序数后缀为 stnd 和 @ 987654342@(分别)。现在在所有情况下都将其更正为 th

    Number.prototype.ordinate = function(){
        var num = this,
            numStr = num.toString(),
            last = numStr.slice(-1),
            len = numStr.length,
            ord = '';
        switch (last) {
            case '1':
                ord = numStr.slice(-2) === '11' ? 'th' : 'st';
                break;
            case '2':
                ord = numStr.slice(-2) === '12' ? 'th' : 'nd';
                break;
            case '3':
                ord = numStr.slice(-2) === '13' ? 'th' : 'rd';
                break;
            default:
                ord = 'th';
                break;
        }
        return num.toString() + ord;
    };
    

    JS Fiddle demo.

    参考资料:

    【讨论】:

    • 这看起来很有趣,谢谢大卫,但它似乎没有将第 1、第 2、第 3 等附加到第 1 行、第 2 行、第 3 行等。我想要“ st"、"nd"、"rd" 附加到表格单元格中的数字。我无法让它工作,有没有办法做到这一点?
    • 是的,这正是我在 Chrome 25/Win XP 下发生的事情。您使用的是什么浏览器/平台失败了? (我无法使用 IE 进行测试,因为 IE
    • 天哪,我重读了我的评论,这很令人困惑,我深表歉意。这句话的意思应该是“它似乎附加……”。然而,关键是我不希望表格的单元格按顺序编号,而只是单元格内的数字显示为序数。这更有意义吗?我为我之前不清楚的评论道歉。我在 Chrome 26/Win 7 上测试过。
    • 太棒了,效果很好!!!现在只有最后一个小问题。有没有办法将 11-13(和 111-113 等)显示为第 11、第 12 和第 13,而不是像现在这样显示第 11、第 12、第 13。我厌倦了添加case '13',但这并没有成功。非常感谢您的帮助!
    • 好的,我认为现在已经解决了吗?
    【解决方案2】:
    function nth(n){
        if(isNaN(n) || n%1) return n;   
        var s= n%100;
        if(s>3 && s<21) return n+'th';
        switch(s%10){
            case 1: return n+'st';
            case 2: return n+'nd';
            case 3: return n+'rd';
            default: return n+'th';
        }
    }
    

    你可以照顾他们自己行中的青少年,其他整数遵循最后一位数字规则。

    【讨论】:

      【解决方案3】:

      我创建了两种方法,一种使用 Prototype,另一种作为插件:

      Number.prototype.between = function(n,m){ return this > n && this < m }
      Number.prototype.ORDINATE_INDEX = ["th","st","nd","rd"];
      Number.prototype.toOrdinate = function(){
          var
              nthMod = (this % 10),
              index =  nthMod > 3 || this.between(10,20) ? 0 : nthMod
          ;
      
          return this + this.ORDINATE_INDEX[index];
      };
      
      $(".ordinal").text(function (index, element) {
          return parseInt(element).toOrdinate();
      });
      

      这是一个 Jquery 插件:

      (function($){
          var numberTool = new (function(){
              var private = {};
      
              private.ORDINATE_INDEX = ["th","st","nd","rd"];
      
              private.parseOrdinary = function(number)
              {
                  var
                      nthMod = (number % 10),
                      index =  nthMod > 3 || private.between(number, 10,20) ? 0 : nthMod
                  ;
      
                  return number + private.ORDINATE_INDEX[index];
              }
      
              private.between = function(number, n,m){
                  return number > n && number < m
              }
      
              this.isNumeric = function(number)
              {
                  return !isNaN(parseFloat(number)) && isFinite(number);
              }
      
              this.toOrdinary = function(number)
              {
                  return this.isNumeric(number) ? private.parseOrdinary(number) : number;
              }
          });
      
      
          $.fn.toOrdinary = function(){
              return this.each(function(){
                  $element = $(this);
                  $element.text(numberTool.toOrdinary($element.text()));
              }); 
          };
      })(jQuery);
      
      $(".ordinal").toOrdinary();
      $(".ordinal").toOrdinary();
      $(".ordinal").toOrdinary();
      

      在 JSFIDDLE 上测试:

      原型版本示例:http://jsfiddle.net/f8vQr/6/

      JQuery 版本示例:http://jsfiddle.net/wCdKX/27/

      【讨论】:

        【解决方案4】:

        它不起作用,因为您将字符串返回到$.each,而不是实际使用它们。用法取决于您的 HTML,但这里是一个将 .ordinal 文本设置为值的示例。

        您还缺少事件处理程序上的i 参数,您可以递增i 以从1st 开始而不是0th

        jsFiddle

        $(".ordinal").each(function (i) {
            i++;
            var j = i % 10,
                str;
            if (j == 1 && i != 11) {
                str = i + "st";
            } else if (j == 2 && i != 12) {
                str = i + "nd";
            } else if (j == 3 && i != 13) {
                str = i + "rd";
            } else {
                str = i + "th";
            }
            $(this).text(str);
        });
        

        如果您的元素中已经有数字,那么最好不要依赖索引而是检查数字,然后将字符串附加到末尾。

        jsFiddle

        $(document).ready(function () {
            $(".ordinal").each(function (i) {
                var j = parseInt($('ordinal').text(), 10) % 10,
                    str;
                if (j == 1 && i != 11) {
                    str = "st";
                } else if (j == 2 && i != 12) {
                    str = "nd";
                } else if (j == 3 && i != 13) {
                    str = "rd";
                } else {
                    str = "th";
                }
                var elem = $(this)
                elem.text(elem.text() + str);
            });
        });
        

        【讨论】:

        • 太棒了,谢谢,成功了!但是,现在我遇到的问题是每个数字(例如 132)都返回为第 17 个,而不是第 132 个。我的数字上升到 200 多个。你知道这个错误的根源在哪里吗?
        • 对我来说很好jsfiddle.net/Tyriar/gWnUJ你错过了代码中的什么吗?
        • 啊,看到i++之前就问了这个问题,不好意思。但是,不,它返回的数字只是 1st、2nd、3rd,而不是 17th、132nd、146th。我正在通过 XML 文档输入数字,以防万一!?所以代码看起来像这样:&lt;table&gt; &lt;tr&gt;&lt;td class='ordinal'&gt;4&lt;/td&gt;&lt;/tr&gt; &lt;/table&gt; 并且应该返回 4th...
        • 更新了更适合包含数字的元素的解决方案。
        • 太棒了,谢谢!!!我只是在更新我原来的问题。现在,唯一的问题是 1 返回第 1 个。除了 11、12、13 之外,是否可以保留所有以 1、2 或 3 结尾的数字的 'st'、'nd' 和 'rd' 结尾?
        【解决方案5】:

        单行序数后缀

        var integerWithSuffix=originalInteger+(['st','nd','rd'][( originalInteger +'').match(/1?\d\b/)-1]||'th');
        

        原始数字和一个字符串的连接,该字符串表示从一个数组派生的序数,该数组由对该数字的正则表达式搜索的结果索引

        http://jsfiddle.net/thisishardcoded/DbSMB/

        【讨论】:

        • 你能多解释一下正则表达式,或者链接到你找到这个的源吗?!
        • 正则表达式将选择单个数字,如果给出单个数字,或者一组数字中的最后一个数字,1 将查看 1,123 将查看 3,以确定后缀。也许是开始1?不需要,因为 \d\b 将捕获单个数字或一组数字中的最后一个数字。
        【解决方案6】:

        根据大卫·托马斯的回答,我会做这样的事情:

        Number.prototype.ordinate = function(){
            var num = this,
                ones = num % 10, //gets the last digit
                tens = num % 100, //gets the last two digits
                ord = ["st","nd","rd"][ tens > 10 && tens < 20 ? null : ones-1 ] || 'th';
            return num.toString() + ord;
        };
        

        它完成了同样的事情。如果一个数字的最后 2 位数字在 11-19 范围内或最后一位数字在 4-0 之间,则默认为“th”,否则它将从基于数组的数组中提取“st”、“nd”或“rd”在那个地方。

        我非常喜欢创建原型函数的想法,但我肯定会将索引的增量留在原型函数之外,以使其更加通用:

        $(".ordinal").text(function (i, t) {
            return (++i).ordinate();
        });
        

        JS Fiddle Demo

        【讨论】:

          【解决方案7】:

          function ordsfx(a){return["th","st","nd","rd"][(a=~~(a&lt;0?-a:a)%100)&gt;10&amp;&amp;a&lt;14||(a%=10)&gt;3?0:a]}

          https://gist.github.com/furf/986113#file-annotated-js查看注释版本

          短小精悍且高效,正如实用函数应有的那样。适用于任何有符号/无符号整数/浮点数。 (尽管我无法想象需要对浮点数进行排序)

          【讨论】:

            【解决方案8】:

            这是我使用的,它适用于任何年、月、日(闰年):

            // panelyear, panelmonth and panelday are passed as parameters
            
            var PY01 = parseInt(panelyear); var PM01 = (parseInt(panelmonth) - 1); PD01 = parseInt(panelday);
            
            var now = new Date(PY01, PM01, PD01);
            var start = new Date(PY01, 0, 0);
            var diff = (now - start) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
            var oneDay = 1000 * 60 * 60 * 24;
            var day = Math.floor(diff / oneDay);
            
            function getNumberWithOrdinal(n) { var s = ["th","st","nd","rd"], v = n % 100; return n + (s[(v - 20) % 10] || s[v] || s[0]); }
            

            搭配使用

            <script> document.write(getNumberWithOrdinal(day)); </script>
            

            【讨论】:

              猜你喜欢
              • 2015-08-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-01-09
              • 2020-06-08
              • 1970-01-01
              • 2021-09-05
              • 2014-09-10
              相关资源
              最近更新 更多