Order/Sort text and numbers works in Firefox and C

2019-09-09 09:46发布

问题:

I wrote a jQuery script to sort the results by year which works fine in most browsers. In the case safari browsers the results are listed like this:

2006 ALL 2007 2008 2009 etc.

Of course the list should apear like this.

ALL 2006 2007 2008 2009 etc.

I don't understand why the results vary.

var li = $('#filter .milo-filter');
li.sort(function(a, b) {
    if(parseInt($(a).text()) > parseInt($(b).text()))
        return 1;
    else return -1;
});
$('#filter').empty().html(li);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="milo-portfolio-filters clearfix">
  <ul data-option-key="filter" id="filter"> 
    <li class="milo-filter">
      <a class="selected " title="All" data-option-value="*" href="#">All</a>
    </li>
    <li class="milo-filter">
      <a title="2015" data-option-value=".2015" href="#">2015</a>
    </li>
    <li class="milo-filter">
      <a title="2011" data-option-value=".2011" href="#">2011</a>
    </li>
    <li class="milo-filter">
      <a title="2006" data-option-value=".2006" href="#">2006</a>
    </li>
    <li class="milo-filter">
      <a title="2007" data-option-value=".2007" href="#">2007</a>
    </li>
    <li class="milo-filter">
      <a title="2008" data-option-value=".2008" href="#">2008</a>
    </li>
    <li class="milo-filter">
      <a title="2013" data-option-value=".2013" href="#">2013</a>
    </li>
    <li class="milo-filter">
      <a title="2010" data-option-value=".2010" href="#">2010</a>
    </li>
    <li class="milo-filter">
      <a title="2009" data-option-value=".2009" href="#">2009</a>
    </li>
    <li class="milo-filter">
      <a title="2014" data-option-value=".2014" href="#">2014</a>
    </li>
    <li class="milo-filter">
      <a title="2012" data-option-value=".2012" href="#">2012</a>
    </li>
  </ul>
</div>

Here is a Codepen for better understanding. http://codepen.io/scooma/pen/yJKxPJ

回答1:

When there is no absolute equality status between two members the browser is not required to give them in the order that you think it should (since you don't really know the exact order the browser send the members of your array to the sort function).

As for the problem in your code, if you will check parseInt("All") < parseInt(2015) and parseInt("All") > parseInt(2015) you will see that both return false.

Here is an example with the exact same code, but the returned value is different in chrome and firefox (due to the exact "problem"):

a = [1, 2, 3, 41, 42]
a.sort(function(a, b) {
  if (a == 41) {
    a = 4;
  }
  if (b == 41) {
    b = 4;
  }
  if (a == 42) {
    a = 4;
  }
  if (b == 42) {
    b = 4;
  }
  
  if (a > b) {
    return 1;
  }
  return -1;
})
console.log(a)

Return value in Chrome: [1, 2, 3, 41, 42 ]
Return value in Safari: [1, 2, 3, 42, 41 ]

The solution

The solution for that is to check if the value you have is a text, and depends on that to return the relevant value (1/-1):

var li = $('#filter .milo-filter');
li.sort(function(a, b) {
    if(isNaN(parseInt($(a).text()))) {
      // If we can't parse the first element as a number, it is probably text, and it should appear first
       return -1;
    }
    if(isNaN(parseInt($(b).text()))) {
      // If we can't parse the second element as a number, it is probably text, and it should appear last
       return 1;
    }
    if (parseInt($(a).text()) > parseInt($(b).text())) {
        return 1;
    }
    return -1;
});

$('#filter').empty().html(li);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="milo-portfolio-filters clearfix">
            <ul data-option-key="filter" id="filter"> 
                  <li class="milo-filter">
                    <a class="selected " title="All" data-option-value="*" href="#">All</a>
                </li>
             
                            <li class="milo-filter">
                    <a title="2015" data-option-value=".2015" href="#">2015</a>
                </li>
                            <li class="milo-filter">
                    <a title="2011" data-option-value=".2011" href="#">2011</a>
                </li>
                            <li class="milo-filter">
                    <a title="2006" data-option-value=".2006" href="#">2006</a>
                </li>
                            <li class="milo-filter">
                    <a title="2007" data-option-value=".2007" href="#">2007</a>
                </li>
                            <li class="milo-filter">
                    <a title="2008" data-option-value=".2008" href="#">2008</a>
                </li>
                            <li class="milo-filter">
                    <a title="2013" data-option-value=".2013" href="#">2013</a>
                </li>
                            <li class="milo-filter">
                    <a title="2010" data-option-value=".2010" href="#">2010</a>
                </li>
                            <li class="milo-filter">
                    <a title="2009" data-option-value=".2009" href="#">2009</a>
                </li>
                            <li class="milo-filter">
                    <a title="2014" data-option-value=".2014" href="#">2014</a>
                </li>
                            <li class="milo-filter">
                    <a title="2012" data-option-value=".2012" href="#">2012</a>
                </li>
                        </ul>
        </div>