简体   繁体   中英

JQuery count table rows

I know that counting the number of tags in a document can be done with something like the following

var tableCount = $('body table tr').length;

Now I presume that this only counts the number of tags. What I want to know is that I have the same number of closing tags . So if the code above shows there are 72 tags, I now want something to tell me that there are 72 closing tr tags.

Is this possible?

Thanks

Ideally, you would use a function like this:

function checkTable(tableElement) {

  // Get inner HTML
  var html = tableElement.innerHTML;

  // Count <tr>
  var count1 = html.match(/<tr/g).length;

  // Count </tr>
  var count2 = html.match(/<\/tr/g).length;

  // Equals?
  return count1 === count2;

}

However , due to browser's mumbo-jumbo , the mismatched tags get auto-corrected (ie auto-closed). Therefore it is impossible for a running page to validate itself. Here is a proof of concept: JS Bin .

Explanation: The second table has a typo (opening tag instead of a closing tag), but the function returns true in both cases. If one inspects the generated HTML (the one that is accessible through DOM), one can see that the browser auto-corrected the mismatched tags (there is an additional empty table row).


Luckily, there is another way. To obtain the pure (ie not modified by the browser) HTML code, you can make an AJAX request to the current page URL. Yes, you read correctly - the page loads itself again. But no worries, there is no recursion and possible stackoverflow here, since you do not process the fetched page.

The JS code for the following is:

var selfUrl = document.location.href;

function checkHTML(html) {

  // Count <tr>
  var count1 = html.match(/<tr/g).length;
  console.log(count1);

  // Count </tr>
  var count2 = html.match(/<\/tr/g).length; // </tr (do not remove this comment!)
  console.log(count2);

  // Equals?
  return count1 === count2;

}

$.get(selfUrl, function(html) {
  console.log(checkHTML(html));
});

But beware of one pitfall. If you include this code in the HTML itself (usually discouraged), then you must not remove that one comment. The reason is the following: one regex contains <tr , while the other has the forward slash escaped and does therefore not contain a </tr . And since you fetch the whole HTML code (including the JS code), the count is mismatched. To even this, I have added an additional </tr inside a comment.

Your question reminds me the idea of the SAX Parser, as the HTML code obviously is the kind of XML. SAX Parser is commonly looking at the start and end tags, as long as element attributes and content.

Some time ago, I have used the simple SAX Parser library from: http://ejohn.org/blog/pure-javascript-html-parser/ Available at: http://ejohn.org/files/htmlparser.js

Using this library you can do the following:

$(document).ready(function(){
    var htmlString = $('#myTable').html(),
        countStart = 0,
        countEnd = 0;

    HTMLParser(htmlString, {
        start: function(tag, attrs, unary) {
            countStart += 1; // you may add the if tag === 'tr' or else
            console.log("start: " + tag);
        },
        end: function(tag) {
            countEnd += 1; // you may add the if tag === 'tr' or else
            console.log("end: " + tag);
        },
        chars: function(text) {},
        comment: function(text) {}
    });
});

There are also modern Node-based approaches like: https://github.com/isaacs/sax-js/blob/master/examples/example.js which can be used for the same task.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM