2015-06-09 60 views
0

我知道计数文档中的标签的数量可以用的东西做类似下面的JQuery的伯爵表行

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

现在我相信,这只能算作标签的数量。我想知道的是,我拥有相同数量的结束标签。所以如果上面的代码显示有72个标签,我现在想告诉我有72个关闭tr标签。

这可能吗?

感谢

+0

为了什么目的,如果你不介意我的问题? – Luke

+0

您可以读取表格的innerHTML,然后使用正则表达式来计算开始和结束'tr'标签。但是如果HTML结构不合适(即缺少结束标签),没有人知道会发生什么。 – alesc

+0

结束标签?如果你写有效的代码,你的.length是真的,如果你将tr匹配成对标记 – daremachine

回答

2

理想情况下,你可以使用这样的功能:

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; 

} 

然而,由于浏览器的天书,不匹配的标签得到自动修正(即自动关闭)。因此,对于正在运行的页面来验证自己,它是不可能。这是一个概念证明:JS Bin

说明:第二个表格有拼写错误(打开标记而不是结束标记),但在两种情况下该函数都返回true。如果检查生成的HTML(可通过DOM访问的HTML),可以看到浏览器自动更正了不匹配的标签(还有一个空的表格行)。


幸运的是,还有另外一种方法。要获得纯浏览器(即未由浏览器修改)的HTML代码,可以向当前页面URL发出AJAX请求。是的,你阅读正确 - 页面再次加载。但不用担心,这里没有递归和可能的堆栈溢出,因为您不处理抓取的页面。

以下JS代码是:

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)); 
}); 

但一个陷阱要小心处理。如果你在HTML中包含这个代码(通常不鼓励),那么你不能删除那个评论。原因如下:一个正则表达式包含<tr,而另一个正斜杠转义并因此不包含</tr。而且,由于您获取了整个HTML代码(包括JS代码),因此计数不匹配。即使如此,我在评论中增加了一个额外的</tr

2

您的问题让我想起了SAX Parser的想法,因为HTML代码显然是XML的一种。只要元素属性和内容一样,SAX解析器通常会查看开始和结束标记。

前一段时间,我用从简单SAX解析器库:http://ejohn.org/blog/pure-javascript-html-parser/ 请访问:http://ejohn.org/files/htmlparser.js

使用这个库,你可以做到以下几点:

$(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) {} 
    }); 
}); 

也有现代的节点 - 例如:https://github.com/isaacs/sax-js/blob/master/examples/example.js这可以用于相同的任务。

+0

解析器是可以的,但这不适用于实时页面,因为您通过'.html()'看到的HTML与在文档源中找到的HTML不同。查看我的答案了解更多详情。 (我也提供了这个场景的概念验证) – alesc

+0

感谢@alesc,但在我的回答中,我没有考虑可能发生的所有问题,以及我使用的库可能并未涵盖所有可能的标记解析问题。也许如果我们连接我们的想法,这将是一个完美的答案:) –

+0

你的代码是确定的,图书馆也可以。问题是浏览器会自动关闭不匹配的标签。因此,当你调用'.html()'时,你不会得到可以在源代码中找到的* real * HTML。这就是为什么我通过在页面URL上发出AJAX请求来解决这个问题。 – alesc