使用Javascript选择特定标记内的标记

时间:2011-02-14 10:59:40

标签: javascript css-selectors associative-array

我有两个问题,我正在尝试整理一个小的chrome用户脚本。 目标是从论坛中查找和汇总信息。 html的结构类似于以下内容:

<div class="wrapper">
 <div class="cfInnerWrapper">
  <div class"inner" title="user1">user1</div>
  <div class="cfMessage">
   <div class="message">  
    This is a message. <strong>the important information 1</strong>
   </div>
  </div>
 </div>
</div>
<div class="wrapper">
 <div class="cfInnerWrapper">
  <div class"inner" title="user2">user2</div>
  <div class="cfMessage">
   <div class="message">  
    This is a message. <strong>the important information 2</strong>
   </div>
  </div>
 </div>
</div>

我想只获得&lt; strong&gt;中的重要消息并将其连接到用户说出来。重要消息还应包含特定字符串,但这不是问题。我这样做是通过查找所有cfInnerWrapper然后逐个浏览它们来选择重要的消息用户对并将它们保存在一个数组中。

这是我的JS:

window.onload = function(){
 var find_str = /important/mi;
 var votes = new Array();
 var message = document.getElementsByClassName('cfInnerWrapper');
 for (m in message){
  var strong_element = message[m].getElementsByTagName('strong'); <---- Error
  if(strong_element){
   var strong_content = strong_element[0].innerHTML;
   if(strong_content.match(find_str)){
    var message_user = message[m].getElementsByClassName('inner')[0].getAttribute('title');
    votes[message_user] = strong_content;
   }
  }
  alert(votes['user1']); <--- Works
 }
 alert(votes['user1']); <--- Doesn't work
}

好的,所以这实际上有效。但我的浏览器,即Chrome显示它出现错误。 有没有更好的方法从特定标签中选择标签?

下一个问题是由于某种原因,保存的数组似乎没有保存在for循环之外。 当我在for-loop中提醒投票内容时,我可以访问该信息。当我尝试从循环外部进行操作时,它根本不起作用。我不明白为什么。

1 个答案:

答案 0 :(得分:1)

  • 首先,您在数组或类似数组(在本例中为NodeList)对象上使用for (item in collection)构造,这是导致错误的主要原因。

    这不是正确的方法,当你迭代到length属性时会给你错误,这是一个数字,而不是一个元素。

    相反,您需要使用for循环或将其转换为数组,然后将forEach转换为数组。

  • 您正在将votes存储在数组中,但是您正在使用它作为关联数组,您应该将它们存储在Object中。

    请注意,您可以使用[]创建新数组,使用{}创建新对象。我之所以提到这是因为您使用了new Array()

  • 使用querySelectorquerySelectorAll会缩短您的代码!您正在创建Chrome用户脚本,Chrome已经支持它。

所以这里是一个更易读,更有效的改进代码。 jsFiddle

var messages = document.querySelectorAll('.cfInnerWrapper'),
    votes = {},
    pattern = /important/i;

// for each message
for (var i = 0; i < messages.length; i ++) {

    var message = messages[i],
        user = message.querySelector('.inner[title]'),
        strong = message.querySelector('strong');

    // check that the elements exist
    if (user && strong) {

        var userName = user.getAttribute('title'),
            content = strong.innerHTML;

        // check if it matches the pattern
        if (pattern.test(content)) {
            votes[userName] = content;
        }

    }

}