views:

100

answers:

3

To continue along my elegant solution series I am trying to figure out how to do this in a better way.

I am cycling through all the a tags and trying to modify the href.

This code works but seems sloppy and would love to know how to do this more efficiently.

$('a').each(function(){
    x=$(this).attr('href').replace(/mls\_number/i,'interior=yes&mls_number');
    $(this).attr('href', x);
});
+9  A: 

You could use the .attr() function overload which allows you to modify an existing attribute value:

$('a').attr('href', function(index, attr) {
    return attr.replace(/mls\_number/i, 'interior=yes&mls_number');
});
Darin Dimitrov
an explanation would have been good, rather than just spoon feeding an answer.
Spudley
@Spudley: I don't think this is anywhere near a mysterious answer.
Matt Ball
@Spudley, that's the beauty of jQuery. The code should be pretty self-explanatory to anyone with a general jQuery culture.
Darin Dimitrov
@Spudley: ...or anyone who takes the time to read http://api.jquery.com/attr
Matt Ball
Trust me I would love to know how to figure this out, hence my elementary solution. I have a hard time converting my idea into a solution because there seems to be so many ways to execute.I tried your code which does not seem to work with my greasemonkey script. I am using Jquery 1.3.2
7null
@7null: you're using an out-of-date version of jQuery. The current version is 1.4.2.
Matt Ball
Understood but i cannot use 1.4 with greasemonkey.
7null
+1  A: 
$('a').each(function(i, e) { 
  e.href = e.href.replace(/mls\_number/i,'interior=yes&mls_number'); 
});

Or with just Mozilla JS extensions

Array.forEach(document.getElementsByTagName('a'), function(e) {
  e.href = e.href.replace(/mls\_number/i,'interior=yes&mls_number');
});
MooGoo
works perfect and makes sense
7null
+1  A: 

A POJ cached query with a count-down while loop will be the fastest way to do this:

var elms = Array.prototype.slice.apply(document.getElementsByTagName("a")), 
i = elms.length,
e, 
href;
while (i--) {
    e = elms[i];
    href = e.href.replace(/mls\_number/i,'interior=yes&mls_number');
    e.setAttribute("href", href);
}
AutoSponge
Erm, what is the point of converting the NodeList to an array? Especially if you are going for speed...
MooGoo
Because you can use a faster iterator, like a reverse while loop (the fastest loop in JavaScript) instead of a for loop on a DOMCollection object. Converting to an array isn't slow, iterating is slow. So we want to optimize that portion if possible.
AutoSponge
Why can't you use a reverse while loop on a NodeList? It is an array like object that can be accessed with bracket notation and numeric keys. Also, I think you severely overestimate the performance benefit of the reverse while loop, unless the page has around a million `<a>` tags. Really, a vast majority of the time here will be spent in `getElementsByTagName` recursing through the entire DOM looking for matching nodes. Any milliseconds picked up afterwards is negligible in comparison.
MooGoo
The document.getElementsByTagName("a") is a document query. It's live. It will recalculate every time you call it. It's fast, but not instant. By caching the list of values in an array, we don't ask the document over and over to tell us about the list of a tags.
AutoSponge
Well in that case any increased performance would be obtained mostly from the array conversion, not the reverse while loop. Either way, this seems like a bad case of premature optimization.
MooGoo
*shrug* I work on some very large DOMs and my users don't have the best hardware, so I tend to only write scalable code if I can.
AutoSponge