我有这个dom:
<ul id="appsList">
<li><span>some value</span> <span>android</span></li>
<li><span>some value</span> <span>ios</span></li>
<li><span>some value</span> <span>facebook</span></li>
<li><span>some value</span> <span>android</span></li>
<li><span>some value</span> <span>ios</span></li>
<li><span>some value</span> <span>android</span></li>
<li><span>some value</span> <span>android</span></li>
</ul>
我希望按照我得到的数组对列表项进行排序:
数组可以是:[ios,android,facebook]
,其中任何其他组合都必须包含所有键,可以只是[ios]
。
我希望列表按数组排序,如果我有[ios,android,facebook]
,那么列表将按如下方式排序:
<ul id="appsList">
<li><span>some value</span> <span>ios</span></li>
<li><span>some value</span> <span>ios</span></li>
<li><span>some value</span> <span>android</span></li>
<li><span>some value</span> <span>android</span></li>
<li><span>some value</span> <span>android</span></li>
<li><span>some value</span> <span>android</span></li>
<li><span>some value</span> <span>facebook</span></li>
</ul>
答案 0 :(得分:4)
更新:
<强> Final Plunker 强>
例如:
.find("sort")
并使用.sort()
您必须调整var arr = ['ios','android','facebook'] ;
var $li = $('#appsList li').sort(function(a,b) {
var firstValue = $(a).find('.sort').text();
var secondValue = $(b).find('.sort').text();
var first = arr.indexOf(firstValue);
var second = arr.indexOf(secondValue);
var output = (second === -1 && first > -1) ? -1 :
(second > -1 && first === -1) ? 1 :
(second === -1 && first === -1) ? firstValue > secondValue :
(second > first ? 1 : -1);
return output;
});
$('#appsList').html($li);
函数
var arr = ['ios','android','facebook'] ;
var $li = $('#appsList li').clone().sort(function(a,b) {
var firstValue = $(a).find('.sort').text();
var secondValue = $(b).find('.sort').text();
var first = arr.indexOf(firstValue);
var second = arr.indexOf(secondValue);
var output = (second === -1 && first > -1) ? -1 :
(second > -1 && first === -1) ? 1 :
(second === -1 && first === -1) ? firstValue > secondValue :
(second > first ? 1 : -1);
return output;
});
$('#resultAppsList').html($li)
示例摘录。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
Before sort :
<ul id="appsList">
<li><span>some value</span> <span class="sort">android</span></li>
<li><span>some value</span> <span class="sort">ios</span></li>
<li><span>some value</span> <span class="sort">facebook</span></li>
<li><span>some value</span> <span class="sort">android</span></li>
<li><span>some value</span> <span class="sort">ios</span></li>
<li><span>some value</span> <span class="sort">android</span></li>
<li><span>some value</span> <span class="sort">android</span></li>
</ul>
After sort :
<ul id="resultAppsList">
</ul>
{{1}}
答案 1 :(得分:0)
当然,这在jQuery中是完全可能的,值得注意的是jQuery不能做本机DOM不能做的事情;因此,为了补充其他答案,我选择使用ES5提供非jQuery方法,以保持与旧浏览器的兼容性(虽然稍后会提供ES6替代方案):
// caching the '#appsList' element:
var list = document.getElementById('appsList'),
// working out which text-property is present in the browser
// (Chrome and Firefox, to the best of my knowledge, support
// both innerText and textContent; whereas IE < 9 supports
// only innerText):
textProp = 'textContent' in document ? 'textContent' : 'innerText',
// retrieving an Array of the (element) children of the list,
// using Array.prototype.slice() and Function.prototype.call()
// to turn the collection of child elements into an Array;
// we then sort the Array using Array.prototype.sort() and
// its anonymous function:
sorted = Array.prototype.slice.call(list.children, 0).sort(function(a, b) {
// here we find the first/only <span> element in the previous
// Array element ('a') and the first/only <span> in the current
// ('b') element and comparing its text:
return a.querySelector('span')[textProp] > b.querySelector('span')[textProp];
}),
// creating a documentFragment:
fragment = document.createDocumentFragment();
// iterating over the sorted Array of elements:
sorted.forEach(function(el) {
// appending a clone of the element ('el') to the
// fragment (in order to show the before/after together):
fragment.appendChild(el.cloneNode(true));
});
// retrieving the element to show the newly-sorted result:
document.getElementById('resultAppsList').appendChild(fragment);
var list = document.getElementById('appsList'),
textProp = 'textContent' in document ? 'textContent' : 'innerText',
sorted = Array.prototype.slice.call(list.children, 0).sort(function(a, b) {
return a.querySelector('span')[textProp] > b.querySelector('span')[textProp];
}),
fragment = document.createDocumentFragment();
sorted.forEach(function(el) {
fragment.appendChild(el.cloneNode(true));
});
document.getElementById('resultAppsList').appendChild(fragment);
ul {
list-style-type: none;
margin: 0 0 1em 0;
padding: 0;
display: inline-block;
width: 45vw;
box-sizing: border-box;
}
li {
width: 100%;
padding: 0;
margin: 0 0 0.2em 0;
}
span {
margin-left: 1em;
}
ul::before {
content: attr(data-state)': ';
margin-bottom: 0.2em;
display: block;
width: 60%;
border-bottom: 1px solid #000;
color: limegreen;
}
<ul id="appsList" data-state="Before">
<li>1<span>android</span>
</li>
<li>2<span>ios</span>
</li>
<li>3<span>facebook</span>
</li>
<li>4<span>android</span>
</li>
<li>5<span>ios</span>
</li>
<li>6<span>android</span>
</li>
<li>7<span>android</span>
</li>
</ul>
<ul id="resultAppsList" data-state="After">
</ul>
为了使现代浏览器更新一点,我们在这里有ES6更新(虽然我怀疑它可能甚至更多 ES6-ified):
// using the let statement to initialise variables:
let list = document.getElementById('appsList'),
textProp = 'textContent' in document ? 'textContent' : 'innerText',
// using Array.from() to convert the Array-like collection into an
// Array:
sorted = Array.from(list.children).sort(function(a, b) {
return a.querySelector('span')[textProp] > b.querySelector('span')[textProp];
}),
fragment = document.createDocumentFragment();
// using Arrow functions within the Array.prototype.forEach() call, since we're
// not using the 'this' keyword and it's pleasantly abbreviated:
sorted.forEach(el => fragment.appendChild(el.cloneNode(true)));
document.getElementById('resultAppsList').appendChild(fragment);
let list = document.getElementById('appsList'),
textProp = 'textContent' in document ? 'textContent' : 'innerText',
sorted = Array.from(list.children).sort(function(a, b) {
return a.querySelector('span')[textProp] > b.querySelector('span')[textProp];
}),
fragment = document.createDocumentFragment();
sorted.forEach(el => fragment.appendChild(el.cloneNode(true)));
document.getElementById('resultAppsList').appendChild(fragment);
ul {
list-style-type: none;
margin: 0 0 1em 0;
padding: 0;
display: inline-block;
width: 45vw;
box-sizing: border-box;
}
li {
width: 100%;
padding: 0;
margin: 0 0 0.2em 0;
}
span {
margin-left: 1em;
}
ul::before {
content: attr(data-state)': ';
margin-bottom: 0.2em;
display: block;
width: 60%;
border-bottom: 1px solid #000;
color: limegreen;
}
<ul id="appsList" data-state="Before">
<li>1<span>android</span>
</li>
<li>2<span>ios</span>
</li>
<li>3<span>facebook</span>
</li>
<li>4<span>android</span>
</li>
<li>5<span>ios</span>
</li>
<li>6<span>android</span>
</li>
<li>7<span>android</span>
</li>
</ul>
<ul id="resultAppsList" data-state="After">
</ul>
参考文献:
Array.from()
。Array.prototype.forEach()
。Array.prototype.slice()
。Array.prototype.sort()
。assessment ? ifTrue : ifFalse
)。Document.createDocumentFragment()
。Document.getElementById()
。Document.querySelector()
。Function.prototype.call()
。let
statement。Node.appendChild()
。Node.cloneNode()
。Node.textContent
。var
statement。