Could anyone help me with a function for JavaScript which searches the source code and compares all of the links on the site with the specific link I am looking for.
For example: I am executing the JavaScript on www.youtube.com and I am looking for one specific YouTube link.
It could look like this (which of course doesn't work):
if(document.body.indexOf("http://www.youtube.com/SPECIFICURL")!== -1){
console.log("Url found");
}else{
console.log("Url not found");
}
How can I accomplish this?
Try querySelectorAll() with CSS3 selectors:
document.querySelectorAll('a[href*="http://www.youtube.com/SPECIFICURL"]')
Fiddle
This selector says find all links with an href attribute that contains a specific string. Lets break this down a little bit:
a - this is the element type, e.g. "link"
href - this is the element attribute
*= - this essentially means contains. There are different type of equality checks that can be used: starts with, contains word, ends with, etc. The jQuery selectors documentation is quite good.
"..." - everything in quotes after the equal sign is the substring the query is looking for.
function find_link_by_href(address)
links = document.getElementsByTagName("a");
for(var i = 0; i < links.length; i++) {
if( links[i].href === address ) {
console.log("Url found");
return;
}
}
You can call it like this:
find_link_by_href("http://www.youtube.com/SPECIFICURL");
Use Array.prototype.some to see if at least one element in document.links has the href you're looking for.
var has_link = [].some.call(document.links, function(link) {
return link.href === 'http://www.youtube.com/SPECIFICURL';
});
You can patch it in old browsers using the patch found at MDN Array#some
You can use document.links to get the anchors, then just loop through grabbing the href, like this:
var arr = [], l = document.links;
for(var i=0; i<l.length; i++) {
arr.push(l[i].href);
}
//arr is now an array of all the href attributes from the anchors in the page
See here.
Then loop through the array to check for your specific link.
Related
I need to change the href of link in a box. I can only use native javaScript. Somehow I have problems traversing through the elements in order to match the correct <a> tag.
Since all the a tags inside this container are identical except for their href value, I need to use this value to get a match.
So far I have tried with this:
var box = document.getElementsByClassName('ic-Login-confirmation__content');
var terms = box.querySelectorAll('a');
if (typeof(box) != 'undefined' && box != null) {
for (var i = 0; i < terms.length; i++) {
if (terms[i].href.toLowerCase() == 'http://www.myweb.net/2/') {
terms[i].setAttribute('href', 'http://newlink.com');
}
}
}
However, I keep getting "Uncaught TypeError: box.querySelectorAll is not a function". What do I need to do in order to make this work?
Jsfiddle here.
The beauty of querySelectorAll is you dont need to traverse like that - just use
var terms = document.querySelectorAll('.ic-Login-confirmation__content a');
And then iterate those. Updated fiddle: https://jsfiddle.net/4y6k8g4g/2/
In fact, this whole thing can be much simpler
var terms = document.querySelectorAll('.ic-Login-confirmation__content a[href="http://www.myweb.net/2/"]');
if(terms.length){
terms[0].setAttribute('href', 'http://newlink.com');
}
Live example: https://jsfiddle.net/4y6k8g4g/4/
Try This:
var box = document.getElementsByClassName('ic-Login-confirmation__content')[0];
Since you are using getElementsByClassName ,it will return an array of elements.
The getElementsByClassName method returns returns a collection of all elements in the document with the specified class name, as a NodeList object.
You need to specify it as follows for this instance:
document.getElementsByClassName('ic-Login-confirmation__content')[0]
This will ensure that you are accessing the correct node in your HTML. If you console.log the box variable in your example you will see an array returned.
you can select by href attr with querySelector,
try this:
document.querySelector('a[href="http://www.myweb.net/2/"]')
instead of defining the exact href attribute you can simplify it even more :
document.querySelector('a[href?="myweb.net/2/"]'
matches only elments with href attribute that end with "myweb.net/2/"
Here's my doubt. I get the line(regular expression) which gets every href of my html, but I need to get the ones which are out of my domain. I think there are something specific that can help me to do that, or some particular tip.
Here is my regular expression:
var re=/(?:<a *(?:(?!href)(?:\w)+="(?:[^"]+)")* *)href="([^"]+)"/g;
I'm using node.js. So what im doing is run it(someFile.js). The little .js just receive myHtmlpage.html and try to get every href out of that domain.
//edit
The idea is try to change that regex, I know it can be a little bit silly, but I need to use regex
You can do this easily with an attribute selector using querySelectorAll and a parameter NOT matching your domain.
var elements = document.querySelectorAll("a[href]:not([href='yourdomain'])");
You shouldn't regex html.
I'd personally suggest avoiding Regular Expressions to parse HTML (an irregular language), and instead using JavaScript:
/* uses Array.prototype.filter on the NodeList returned
by document.querySelectorAll, retains only those elements
that match the supplied filter expression:
*/
var els = [].filter.call(document.querySelectorAll('a'), function(a){
/* assesses whether the href of the a elements link to a different
domain than the current domain; if so that element is retained
and forms part of the resulting array:
*/
return a.href.indexOf(document.location.host) == -1;
// using Array.prototype.forEach to iterate over the created array:
}).forEach(function(a){
/* adds the classname 'outofdomain' to the classList,
obviously amend this to do whatever you prefer:
*/
a.classList.add('outofdomain');
});
console.log(els);
JS Fiddle demo.
And for those browsers that dislike the above approach (IE8 and lower):
// get all the 'a' elements:
var aElems = document.getElementsByTagName('a'),
// get the current domain's hostname:
host = document.location.hostname,
// create an array to push the matched elements:
outofdomain = [];
// iterating over the 'a' elements found earlier:
for (var i = 0, len = aElems.length; i < len; i++){
// if the hostname is not found in the href
if (aElems[i].href.indexOf(host) == -1){
// we add it into the array:
outofdomain.push(aElems[i]);
// set the class-name:
aElems[i].className = 'outofdomain';
}
}
console.log(outofdomain);
JS Fiddle demo.
References:
Array.prototype.filter().
Array.prototype.forEach().
document.querySelectorAll().
Element.classList API.
I want to get all the <a> tags from an Html page with this JavaScript method:
function() {
var links = document.getElementsByTagName('a');
var i=0;
for (var link in links){i++;}
return i;
}
And i noticed it's won't return the correct number of a tags.
Any idea what can by the problem?
Any idea if there is any other way to get all the href in an Html ?
Edit
I tried this method on this html : http://mp3skull.com/mp3/nirvana.html .
And i get this result:"1". but there are more results in the page.
You don't need a loop here. You can read length property.
function getACount() {
return document.getElementsByTagName('a').length;
}
You don't have to loop over all of them just to count them. HTMLCollections (the type of Object that is returned by getElementsByTagName has a .length property:
$countAnchors = function () {
return document.getElementsByTagName('a').length;
}
Using getElementsByTagName("a") will return all anchor tags, not only the anchor tags that are links. An anchor tags needs a value for the href property to be a link.
You might be better off with the links property, that returns the links in the page:
var linkCount = document.links.length;
Note that this also includes area tags that has a href attribute, but I assume that you don't have any of those.
UPDATE Also gets href
You could do this
var linkCount = document.body.querySelectorAll('a').length,
hrefs= document.body.querySelectorAll('a[href]');
EDIT See the comment below, thanks to ttepasse
I would cast them to an array which you then slice up, etc.
var array = [];
var links = document.getElementsByTagName("a");
for(var i=0; i<links.length; i++) {
array.push(links[i].href);
}
var hrefs = array.length;
The JavaScript code in the question works as such or, rather, could be used to create a working solution (it’s now just an anonymous function declaration). It could be replaced by simpler code that just uses document.getElementsByTagName('a').length as others have remarked.
The problem however is how you use it: where it is placed, and when it is executed. If you run the code at a point where only one a element has been parsed, the result is 1. It needs to be executed when all a elements have been parsed. A simple way to ensure this is to put the code at the end of the document body. I tested by taking a local copy of the page mentioned and added the following right before the other script elements at the end of document body:
<script>
var f = function() {
var links = document.getElementsByTagName('a');
var i=0;
for (var link in links){i++;}
return i;
};
alert('a elements: ' + f());
</script>
The results are not consistent, even on repeated load of the page on the same browser, but this is probably caused by some dynamics on the page, making the number of a elements actually vary.
What you forget here was the length property. I think that code would be:
var count = 0;
for (var i = 0; i < links.length; i++) {
count++;
}
return count;
Or it would be:
for each (var link in links) {
i++;
}
length is used to determine or count the total number of the element which are the result.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for (For Loop)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for_each...in (Foreach Loop)
I'm trying to use Anarchy Media Player on my site but had to change code a bit because my media files/urls are not in standard format. It pulls the video files now but javascript is finding ALL links and tries to add player to it. I even added id "video" to video link but still finds all links on the page and adds player to it.
How can I separate those links to get player added to them only?
Here is the part of the javascript that looks for the links:
var all = document.getElementsByTagName('a');
for (var i = 0, o; o = all[i]; i++) {
if(o.idName="video" && o.className!="amplink") {
// Add player code...
}
}
Thank you for your help.
Not sure why you're not just doing this:
var all = document.getElementsByTagName('a');
for (var i = 0, len = all.length; i<len; i++) {
if(all[i].idName=="video" && all[i].className!="amplink") {
// Add player code...
}
}
That should work for you. Note that I stored the value of the array length so you don't have to look it up every iteration. Minimal, but does increase performance slightly.
You were also setting idName to video when you did idName="video" in your if statement, not comparing (that will always return true, which was your problem). Use the double equals operator (==) or the triple equals operator (===) to compare values.
Are you sure you don't mean if (o.className == "amplink")?
Besides that what you have is fine (except for the o.idName="video" bit which always returns true): http://jsfiddle.net/VpMVe/
you can get elements using querySelectorAll, but it's not supported in older browsers (that would be older then IE8, FF3.5, Opera 10, Chrome 4 and Safari 3.1). It's similar to targetting elements using CSS selectors (and jQuery). here's a demo getting all links with class video to turn red.
function get(selector) {
return document.querySelectorAll(selector)
}
(function() {
//get all <a> with class "video"
var video = get('a.video');
//for each, turn them red
for (var i = 0; i < video.length; i++) {
video[i].style.color = 'red';
//in your case, do whatever you want for each target here
}
}())
There is no idName attribute. It's just o.id. And there can only be one id, so that's likely to cause some issues. Also you're assigning it, rather than comparing for equality which always evaluates to true. If you have more than one class, e.g. class="amplink someOtherClass" != amplink will evaluate to true. Better to do a match on the className. Like this:&& !o.className.match(/ampLink/)
Make a video on another class and do matches instead.
I am not experienced in Javascript. After the page finishes loading, I need to iterate thru all URLs a given page and perform some cleanings.
How do I do that?
Something like
for i = 0 to (number of URLS on the page) {
doSomething (URL(i));
}
thanks
If you want to link through all anchors, use document.links, like this:
for(var i = 0, l=document.links.length; i<l; i++) {
doSomething(document.links[i].href);
}
This is a collection already maintained by the browser (for prefetching under the covers mostly, but other reasons as well)...no need for a document.getElementsByTagName() here. Note: this also gets <area> elements, as long as they have a href attribute...also a valid form of navigation.
I'd always recommend having jQuery around for times like this as it makes it far easier.
For example on page load:
$(document).ready(function(){
$('a').each(function(index) {
alert(index + ': ' + $(this).text());
});
});
Use this function:
var anchors = document.getElementsByTagName("a");
for (anchor in anchors){
doSomething(anchor):
}
Or just plain Javascript with a bit of readability:
var myURL = document.getElementsByTagName('a');
for(var i=0; i<myURL.length; i++)
console.log(myURL[i].getAttribute('href'));