Javascript sorting DIVs based on class
I am trying to sort the following static HTML product listing based on the div that contains the price. In this case the divs all have a class of price-bold. Is there a way to sort the list of products using javascript to sort lowest to highest an开发者_Go百科d highest to lowest with a button/text on-click command? Your help and expertise is greatly appreciated. Thank you, Dan
<div id="gallerypaginate2" class="paginationstyle"></div>
<div id="contents">
<table width="100%" class="vertical" id="contents-table">
<tr class="pagination-row">
<td width="25%" class="horizontal-seperator vertical-seperator">
<a href="mica136-3s.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2126916" width="125" height="71" border="0" hspace="0" vspace="0" alt="3-Shade Billiard Light - Oversized" title="3-Shade Billiard Light - Oversized" /></a>
<div class="name"><a href="mica136-3s.html" title="3-Shade Billiard Light - Oversized">3-Shade Billiard Light - Oversized</a></div>
<div class="price-bold">$2,088.00</div>
</td>
<td width="25%" class="horizontal-seperator vertical-seperator">
<a href="micaf101-01-abbey.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2132333" width="125" height="118" border="0" hspace="0" vspace="0" alt="Abbey Craftsman Fan and Mica Light Kit" title="Abbey Craftsman Fan and Mica Light Kit" /></a>
<div class="name"><a href="micaf101-01-abbey.html" title="Abbey Craftsman Fan and Mica Light Kit">Abbey Craftsman Fan and Mica Light Kit</a></div>
<div class="price-bold">$711.00</div>
</td>
<td width="25%" class="horizontal-seperator vertical-seperator">
<a href="mica007.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2150148" width="103" height="125" border="0" hspace="0" vspace="0" alt="Beanpot Table Lamp" title="Beanpot Table Lamp" /></a>
<div class="name"><a href="mica007.html" title="Beanpot Table Lamp">Beanpot Table Lamp</a></div>
<div class="price-bold">$442.00</div>
</td>
<td width="25%" class="horizontal-seperator">
<a href="mica012.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2162401" width="125" height="71" border="0" hspace="0" vspace="0" alt="Buffet Table Lamp" title="Buffet Table Lamp" /></a>
<div class="name"><a href="mica012.html" title="Buffet Table Lamp">Buffet Table Lamp</a></div>
<div class="price-bold">$370.00</div>
</td>
</tr>
<tr class="pagination-row">
<td width="25%" class="horizontal-seperator vertical-seperator">
<a href="mica051.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2169261" width="125" height="71" border="0" hspace="0" vspace="0" alt="Bungalow Floor Lamp" title="Bungalow Floor Lamp" /></a>
<div class="name"><a href="mica051.html" title="Bungalow Floor Lamp">Bungalow Floor Lamp</a></div>
<div class="price-bold">$1,370.00</div>
</td>
<td width="25%" class="horizontal-seperator vertical-seperator">
<a href="mica119c.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2177066" width="125" height="71" border="0" hspace="0" vspace="0" alt="Carmel Wall Sconce" title="Carmel Wall Sconce" /></a>
<div class="name"><a href="mica119c.html" title="Carmel Wall Sconce">Carmel Wall Sconce</a></div>
<div class="price-bold">$505.00</div>
</td>
<td width="25%" class="horizontal-seperator vertical-seperator">
<a href="micaf101-bw.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2182877" width="125" height="71" border="0" hspace="0" vspace="0" alt="Ceiling Fan with Bell White Light Kit" title="Ceiling Fan with Bell White Light Kit" /></a>
<div class="name"><a href="micaf101-bw.html" title="Ceiling Fan with Bell White Light Kit">Ceiling Fan with Bell White Light Kit</a></div>
<div class="price-bold">$524.00</div>
</td>
<td width="25%" class="horizontal-seperator">
<a href="micaf101-c.html"><img src="http://ep.yimg.com/ca/I/yhst-129288146819219_2148_2192940" width="125" height="71" border="0" hspace="0" vspace="0" alt="Ceiling Fan with Coppersmith Mica Light Kit" title="Ceiling Fan with Coppersmith Mica Light Kit" /></a>
<div class="name"><a href="micaf101-c.html" title="Ceiling Fan with Coppersmith Mica Light Kit">Ceiling Fan with Coppersmith Mica Light Kit</a></div>
<div class="price-bold">$695.00</div>
</td>
</tr></table>
</div>
<div id="gallerypaginate" class="paginationstyle"><a href="#" rel="previous">Prev</a> <span class="flatview"></span> <a href="#" rel="next">Next</a></div>
Knowing that the length of my solution would probably scare you off, I decided to make a pure JS solution as a challenge.
Here it is, in all of its weighty glory:
addListeners();
function addListeners()
{
var toggle = toggleTableSort;
var node = document.getElementById("sortTables");
node.onclick = toggle();
}
function toggleTableSort()
{
var status = 0;
return function()
{
var table = getTable();
var tableData = table['data'];
var rows = table['rows'];
if(status === 0)
{
status = 1;
sortTableData(tableData, rows, "descending");
}else if(status === 1)
{
status = 0;
sortTableData(tableData, rows, "ascending");
}
}
}
function getTable()
{
var container = document.getElementById("contents-table");
var tbody = getElementNodes(container, "TBODY", 1, {})[0];
var rows = getElementNodes(tbody, "TR", 0, {"class": "pagination-row"});
var tableData = grabTableData(rows);
return {"data": tableData, "rows": rows};
}
function getElementNodes(parent, tag, num, attributes)
{
var nodes = parent.childNodes;
var temp = [];
tag = tag.toUpperCase();
if(num === 0)
{
num = nodes.length;
}
for(var i=0;i<nodes.length;i++)
{
var node = nodes[i];
if(temp.length <= num)
{
if(node.nodeType === 1 && node.tagName === tag)
{
var attributeCheck = true;
for(var attribute in attributes)
{
if(attributes.hasOwnProperty(attribute))
{
var newAttribute;
if(attribute === "class" && !node.getAttribute(attribute))
{
newAttribute = "className";
}
if(newAttribute)
{
if(node.getAttribute(newAttribute) !== attributes[attribute])
{
attributeCheck = false;
break;
}
}else if(!newAttribute)
{
if(node.getAttribute(attribute) !== attributes[attribute])
{
attributeCheck = false;
break;
}
}
}
}
if(attributeCheck)
{
temp.push(node);
}
}
}else if(temp.length > num)
{
break;
}
}
return temp;
}
function grabTableData(rows)
{
var data = [];
for(var i=0;i<rows.length;i++)
{
var row = rows[i];
var tableData = getElementNodes(row, "TD", 0, {"width": "25%"});
data = data.concat(tableData);
}
return data;
}
function sortTableData(tableData, rows, order)
{
var prices = getPrices(tableData);
var temp = trimPrices(prices);
order = order.toLowerCase();
switch(order)
{
case "descending":
temp = sortParallelData(tableData, temp, order, {"data": tableData, "rows": rows}, orderTables);
break;
case "ascending":
temp = sortParallelData(tableData, temp, order, {"data": tableData, "rows": rows}, orderTables);
break;
}
}
function orderTables(tableData, tableCells)
{
var rows = tableData['rows'];
var data = tableData['data'];
for(var i=0;i<rows.length;i++)
{
var items = tableCells.slice(i * 4, (i * 4) + 4);
var cells = data.slice(i * 4, (i * 4) + 4);
for(var j=0;j<rows[i].childNodes.length;j++)
{
var node = rows[i].childNodes[j];
rows[i].removeChild(node);
}
for(var k=0;k<items.length;k++)
{
var item = items[k];
var cell = cells[k];
rows[i].appendChild(item);
}
}
}
function getPrices(tableData)
{
var prices = [];
for(var i=0;i<tableData.length;i++)
{
var data = tableData[i];
var node = getElementNodes(data, "DIV", 1, {"class": "price-bold"})[0];
var text;
var whitespace;
if(node.innerText)
{
text = node.innerText;
}else if(node.textContent)
{
text = node.textContent;
}
whitespace = text.match(/\s+/);
text = text.replace(whitespace, "");
prices.push(text);
}
return prices;
}
function trimPrices(prices)
{
var temp = [];
for(var i=0;i<prices.length;i++)
{
var price = prices[i];
temp.push(price.replace("$", "").replace(",", ""));
}
return temp;
}
function sortParallelData(first, second, order, data, callback)
{
var matches = 0;
var parallel = first;
var cached = second;
var left, right, temp;
order = order.toLowerCase();
switch(order)
{
case "descending":
for(var i=0;i<cached.length;i++)
{
left = parseInt(cached[i], 10);
right = parseInt(cached[i+1], 10);
temp = parallel[i+1];
if(right > left)
{
cached[i+1] = left;
parallel[i+1] = parallel[i];
parallel[i] = temp;
cached[i] = right;
matches++;
}
}
break;
case "ascending":
for(var i=0;i<cached.length;i++)
{
left = parseInt(cached[i], 10);
right = parseInt(cached[i+1], 10);
temp = parallel[i+1];
if(left > right)
{
cached[i+1] = left;
parallel[i+1] = parallel[i];
parallel[i] = temp
cached[i] = right;
matches++;
}
}
break;
}
if(matches > 0)
{
sortParallelData(first, second, order, data, callback);
}else
{
callback(data, parallel);
}
}
http://jsfiddle.net/t6ysg/8/
Two assumptions were made, that being your table has a tbody
tag containing your contents, and that you would always have 4 td
elements per table row.
Tested as working in: Firefox 4, Chrome 4, Opera 11, Safari 4, IE 8 + Quirks, and IE 7 + Quirks.
You can simply call .sort()
on the <td/>
and in the sort find the price and do your comparison.
function SortItems(compare) {
var elm = $("#contents-table td");
elm.sort(function(a, b) {
var priceAText = $(a).find(".price-bold").text().replace(/[^\d]/g, "");
var priceA = parseFloat(priceAText);
var priceBText = $(b).find(".price-bold").text().replace(/[^\d]/g, "");
var priceB = parseFloat(priceBText);
return compare(priceA, priceB);
});
//put them back in the table in the sorted order.
$("#contents-table tr:first").append(elm.slice(0, 4));
$("#contents-table tr:last").append(elm.slice(4, 8));
}
$("#high").toggle(function(){
$(this).text("Sort Low");
SortItems(function(a, b){ return a< b;});
}, function(){
$(this).text("Sort High");
SortItems(function(a, b){ return a> b;});
});
working jsfiddle example
fiddle with some simple fadeOut animation.
精彩评论