Parsing Return Values ​​of a Class or Contains Selectors in jQuery

I've been researching this and trying almost every solution example that has been provided, but cannot handle jQuery return values $('a.someclass)

or in a $('a:contains("some text"))

meaningful way, like enumerating an array. .length

allows you to see how many items you have returned, and if you enter the console for the variable assigned above, you get a complete dump of what was collected, but the most I can do is get information about the first item only.

Let's say I have HTML code like this:

<a href="something" id="a1" class="a x">something.com</a>
<a href="anotherthing" id="a2" class="a x">anotherthing.com</a>

      

And I am trying to use jQuery in one of two ways:

//grabbing any link where class = 'a x'
var links = $("a.a.x");

      

or say:

//grabbing any link where the word "thing" appears
var links = $("a:contains('thing')");

      

I can check the returned information simply:

console.log(links);
console.log(links.length);

      

However, I haven't found a way to parse the data outside of the first element, trying to handle it like an array links[i]

throws an exception, and using links

itself only yields attributes attached to the first and not subsequent ones.

For example, something like this won't work:

if (links.length > 0) {
   for (var i = 0; i < links.length; i++) {
       console.log(links[i].attr('href'));
   };
};

      

For now, this will just work, but only for the first element:

console.log(links.attr('href'));

      

Can someone please improve my understanding of what is going on here and how to enumerate and handle the code across all returned items. Thank you in advance.


EDIT: 08/07/15


I wanted to thank EVERYONE for their help on this and take the time to provide me with examples that I will use as a reference. Also, I wanted to let you know that I was able to get the functionality I needed by including pretty much everything I was given to create robust and lean code. Now, if I can just get darn to .trigger('click')

function properly (more precisely, sequentially), then I'll be absolutely golden.

It looks like the code using is $("a.a.x")

not causing problems.

if (links.length > 0){
    links.each(function(index, domElement) {
        console.log("["+index+"] "+domElement.href);
        $(domElement).trigger('click');
    });
};

      

but the same exact code applied to items from links

assembled through $("a:contains('thing')")

does not create the desired behavior and does not give errors. Truly a head. I need to somehow resolve this as I won't always have one available class

or id

leaving with contains

only one option. I would a

hate to grab ALL tags on a page and then parse them individually, it seems inefficient and definitely inelegant.

+3


source to share


6 answers


The disconnect you are using is between the jQuery API and the native JavaScript API.

With jQuery, when you use a selector, internally it will mock the array. The array is essentially inside a jQuery object. An internal array is a collection of the actual matched elements on the page, and these elements will have their own JavaScript API functions available to them. The entire jQuery object as a whole will have the jQuery API.

This is how it looks in code and how it relates to your examples.

Your link selector in order "a.a.x"

. You have an anchor tag with class "a" and "x", and this is how you can select a set of tags that match those criteria. So you have

var links = $("a.a.x");

      

Remember that $

is just shorthand for jQuery

, which is a function. So you call that function and it returns (through some internal process) a jQuery instance. Thus, the links now refer to the jQuery instance. Internally, this instance (jQuery object) contains a variable with an array of elements mapped to the selector (argument) used when calling jQuery. This array can be accessed (as a result of jQuery's internal process exposing the elements) simply by using the index numbers.

You are accessing the array correctly (or at least no error) here:

for (var i = 0; i < links.length; i++) {
   console.log(links[i].attr('href'));
};

      



But there is a problem. Remember that jQuery's internal array supported elements? links[i]

the actual element is here and it displays the built-in JavaScript API. As a result, .attr

unavailable. The getter's own version for attributes is "getAttribute" and you can change your code above to

for (var i = 0; i < links.length; i++) {
   console.log(links[i].getAttribute('href'));
};

      

You can also create a jQuery object using links[i]

and then access the jQuery API.

for (var i = 0; i < links.length; i++) {
   console.log($(links[i]).attr('href'));
};

      

This is becoming overkill, as you hopefully see. By a similar construction, and since it links

is a jQuery object, you can access the jQuery API functions. This is why this code console.log(links.attr('href'));

will result in the href attribute. However, since it is a getter, jQuery will internally only return the first set result. To take an iterative approach, jQuery provides a function each

. It is very useful and widely used behind the scenes. For example, links.css('color','blue')

will internally use each

it to iterate over the entire set of links and change the text color to blue.

Your best bet here is to stick with using each

.

$("a.a.x").each(function(){
    //this will now be available as the native element similar to links[i]
    console.log(this.href);//href is natively available as well
    cosnole.log(this.getAttribute('href'));//also available here
    console.log($(this).attr('href'));//and here when constructing a jQuery object as well
});

      

+2


source


The way jQuery is written can be very different from how you write regular JavaScript. It is very rare that you want to access individual elements of your matches or explicitly skip them. Most of the time, you apply actions to all matches at once in batch mode, as most jQuery functions apply to all matched elements in a list, for example:

$("a.a.x").addClass("link"); //Adds the class link to both elements.
$("a.a.x").css("color", "green"); //Makes both links green.

      

Did I mention that you can chain these function calls?

$("a.a.x").addclass("link").css("color", "green"); //Same as above.

      

Sometimes you need to iterate over all the elements. Then you can use the function each

:

//Set the width to be equal to the height of all divs with the class square.
$("div.square").each(function() {
    //This function is called once per matched element.
    //The variable "this" contains a DOM object referencing the current element.
    side = $(this).height();
    $(this).width(side);
}

      

If you just want to access a single element, for example from an array, you can use eq

:



$("a.a.x").eq(1); //Gives you the second link.
$("a.a.x:eq(1)"); //Also available as selector.

      

Finally, if you want to access the underlying DOM object instead of the jQuery object, you can either use get

parentheses:

$("a.a.x").get(1); //Gives you the second link, as a DOM object
$("a.a.x")[1]; //Same as above.

      

Remember jQuery is here to free you from the tedious and boring parts of writing JavaScript. When you are used to doing things the vanilla way, you can create code like this:

//BAD CODE - DO NOT IMMITATE.
links = $("a.a.x");
for(i=0; i<links.length; i++) {
    link = links.eq(i);
    link.addClass("link");
}

      

This is terrible code as it can only be achieved in one line - the very first of all examples in this answer.

+1


source


Use every iterator . For example:

var links = $("a.a.x");

links.each(function(index, domElement) {
console.log(index);
$(domElement).css('background', 'red');
});

      

btw - there are also .map, .filter, .eq and many other methods for moving the collection.

0


source


If your jQuery selector is correct, you should be able to scroll through the content or use a call .each()

like

    var links = jQuery("a.a.x");
    links.each(function() {
        console.log(jQuery(this).attr('href'));
    });

      

0


source


Are you looking for something like this?

var links = $("a.a.x");

links.each(function(i) {
  console.log('item ' + i, links[i]);
});
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="something" id="a1" class="a x">something.com</a>
<a href="anotherthing" id="a2" class="a x">anotherthing.com</a>
      

Run codeHide result


0


source


In the following code, the [i] link object is not a JQuery object, but a DOM object, so you must be able to access the attribute like this:

var links = $("a.a.x");
if (links.length > 0) {
   for (var i = 0; i < links.length; i++) {
       console.log(links[i].href);
       $('#list').append('<li> href='+links[i].href +'</li>');
   };
};
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<a href="something" id="a1" class="a x">something.com</a>
<a href="anotherthing" id="a2" class="a x">anotherthing.com</a>

<div>
  <ul id='list'>
    </ul>
  </div>
      

Run codeHide result


0


source







All Articles