简体   繁体   中英

Selecting a tag within a specific tag with Javascript

I have two problems with a small userscript for chrome that I'm trying to put together. The goal is to find and put together information from a forum. The structure of the html is similar to the following:

<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>

I want to get only the important message within the <strong> and connect it to the user saying it. The important message should also contain a specific string, but that not an issue here. I do this by finding all cfInnerWrapper and then go through them one by one to select the important message-user-pair and saves them in an array.

This is my 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
}

Ok, so this actually works. But my browsers ie Chrome says its an error where I show it. Is there a better way to select a tag from within the specific tag?

The next problem is that the saved array doesn't seem to be saved outside the for-loop for some reason. When I alert the content of vote within the for-loop I can access the information. When I try to do it from outside the loop it doesn't work at all. I don't understand why.

  • First, you are using for (item in collection) construct over an array or an array-like (in this case NodeList) object, which is the main cause of your error.

    This is not the right way to do, and will give you error when you it iterates to the length property, which is a number, not an element.

    Instead, you need to use the for loop or convert it to an array and then forEach on it.

  • You are storing votes inside an Array, but you are using it like an associative array, you should store them in an Object instead.

    Note that you can use [] to create a new Array and {} to create a new Object. I mentioned this because you used new Array() .

  • Using querySelector and querySelectorAll makes your code a bit shorter! You are creating a Chrome userscript and Chrome already supports it.

So here is an improved code which is more readable and works. 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;
        }

    }

}

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