Reputation: 181
I have the following table. I would like to check, whether certain rows and columns (col) exist or not. Before I was working with ids and that was fast enough, but now I use the DOM directly with index() in jQuery and no ids. But it is definitely slower! Here is my table:
**************************************************
* line * col * col * col * col * col * *
* line * col * col * *
* line * col * col * col * col * col * col * col *
* line * col * col * col * *
* line * col * col * col * col * col * *
* line * col * col * col * col * col * *
* ... * ... * ... * ... * ... * ... * ... * ... *
**************************************************
In the table you can see the class names of the table cells. The tags have a class called "row". The col count can vary. I need a script to check / access these rows and columns. I have the following script:
function isRow( r ) {
var row = $( ".row" ).eq(r);
return ( typeof row != "undefined" ? true : false );
}
function getRow( r ) {
var row = $( ".row" ).eq(r);
return ( typeof row == "undefined" ? null : row );
}
function isCell( r, c ) {
var col = $( ".row" ).eq(r).children(".col").get(c);
return ( typeof col == "undefined" ? true : false );
}
function getCell( r, c ) {
var col = $( ".row" ).eq(r).children(".col").eq(c);
return ( typeof col == "undefined" ? null : col );
}
What am I doing wrong? Is there a faster way to access the DOM elements? There is probably a better selector, but I don't know how to rewrite my code.
Any idea?
Bernhard
Upvotes: 2
Views: 77
Reputation: 10976
If performance is that much of an issue you are better off with a plain JS for/ while loop, and as much variable caching as possible, eg:
// returns an array with a data obj about each cell, with following format:
// { row: x, col: y } + any properties added by the function passed as param
// @param {element} table - The table element you want to loop
// @param {function} fn - The function to execute on each cell, with parameter (cell)
function loopTableCells(table, fn) {
var rows = table.children, // note: native children prop is faster than jQuery
len = table.children.length, cell, cellArr = [], cellCount, cellData;
for (var i = 0; i < len; i++) {
cell = rows[i].firstChild;
cellCount = 0;
if (cell) { // in case the row has no children, do nothing
do { // it has at least one child, so do at least once
cellData = fn(cell);
cellData.row = i; // store the table row index
cellData.col = cellCount;
cellArr.push(cellData);
cellCount++;
cell = rows[i].nextSibling;
} while (rows[i].nextSibling);
}
}
return cellArr;
}
You could then use this function like so:
function getCellData(cell) { // store any cell property you want in obj
var obj = {};
obj.hasChildren = (cell.firstElementChild ? true : false);
obj.hasText = (cell.textContent ? true : false);
obj.element = cell;
if (cell.id) obj.id = cell.id;
if (cell.className) obj.class = cell.className;
return obj;
}
var tableData = loopTableCells($('#myTable'), getCellData);
Now you have a flat array of table cells, you can simply iterate over them, for example the (pointless) function beneath removes all table cells which have an uneven index in the table row. :)
$.each(tableData, function(i, val) {
if (val.col/2 !== parseInt(val.col/2))
$(val.element).remove();
}
Upvotes: 1