Reputation: 1831
A part of an HTML page consisting of links is given below:
<ul>
<li><a href="myPersonalProject.html">myPersonalProject (a local html file)</a></li>
<li><a href="cv.pdf">my CV (a local PDF file)</a></li>
<li><a href="archive/2014.zip">archive (a local ZIP file)</a></li>
<li><a href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf">ECMAScript Language Specification (an external PDF)</a></li>
<li><a href="../pdfs/christmas/">Christmas cards (a local directory with pdf in the pathname - but NOT a pdf file)</a></li>
<li><a href="https://noppa.tkk.fi/">Noppa (an external link)</a></li>
</ul>
I need to select the links whose targets end with anything (.*), and which do NOT end with (.pdf) and similarly do NOT end with (.html), and apply a CSS class to it. I need to use jQuery for this. I tried to do it with filter, but made a mess of it, as I have just started learning jQuery:
$("a[href$='.*']").filter(function(){
$("a[href$!='.pdf']").filter(function(){
$("a[href$!='.html']").addClass("download");
});
});
I know it's completely wrong, but I can't figure out how to do it. I googled around, but the function() inside filter() is not really clear. Can someone help, please?
Upvotes: 0
Views: 663
Reputation: 253506
While you say you "need to do this with jQuery," I wanted to offer a plain JavaScript alternative (for yourself or others, in future):
// calls Array.prototype.forEach(), using the array-like NodeList
// returned by document.querySelectorAll(), iterating over that NodeList
[].forEach.call(document.querySelectorAll('li a'), function (aElem) {
// 'aElem' is the current array-element (the <a>)
// if the aElem.href property does not (note the '!') end with
// either 'pdf' or 'html' (RegExp.prototype.test() returns
// a Boolean)
if (!(/(pdf|html)$/).test(aElem.href)) {
// we add the 'download' class to the element:
aElem.classList.add('download');
}
});
Alternatively:
[].forEach.call(document.querySelectorAll('li a'), function (aElem) {
// if the final part of the href (following the final '.' character)
// is not found in the array (and thus an index of -1):
if (['pdf','html'].indexOf(aElem.href.split('.').pop()) === -1) {
aElem.classList.add('download');
}
});
References:
Array.prototype.forEach()
.Array.prototype.indexOf()
.Array.prototype.pop()
.Element.classList
.Function.prototype.call()
.RegExp.prototype.test()
.String.prototype.split()
.Upvotes: 1
Reputation: 16440
i'm late to the party, minor changes to DemoUser's answer
which takes care of # anchor in the URL
$('a')
.filter(function() {
// take care of anchor # in download URL
return !this.href.match(/\.(pdf|html)(#.*)?$/gi);
})
.addClass("download"); //if matched, "download" class is added
Upvotes: 0
Reputation: 318372
You can combine a regex with some simple tests to filter the anchors
$('a').filter(function() {
var m = this.href.match(/\.(.{3,4})$/), e = m ? m.shift() : null;
return e && e.indexOf('/') == -1 && e.match(/(pdf|html)/) == null;
}).addClass('download');
Upvotes: 2
Reputation: 81
You could also do the following:
$("a").each(function( index ) {
var href = $(this).attr('href');
if(!((href.toLowerCase().indexOf(".pdf") >= 0) || (href.toLowerCase().indexOf(".html") >= 0))){
$(this).addClass("download");
}
});
Upvotes: 0
Reputation: 1022
$("a[href]").filter(function (i) {
var href = $(this).attr("href");
return (href.indexOf(".pdf") == -1 && href.indexOf(".html") == -1);
})
.addClass("download");
Upvotes: 1
Reputation: 100205
you could use filter() as,
$('a')
.filter(function() {
//use your required regex to check for link
return this.href.match(/[^.]*?\.(?!pdf|html)/gi);
})
.addClass("download"); //if matched, "download" class is added
Upvotes: 1
Reputation: 782785
jQuery attribute selectors don't allow wildcards or regexp. But you don't need to use filter to remove the .pdf
, you can use a :not
selector:
$("a:not([href$=.pdf]):not([href$=.html])").addClass("download");
And when you use .filter()
, the function is just supposed to return a boolean (indicating whether that element should be included or not in the result), it shouldn't operate on the elements themselves -- you do that on the value returned by .filter
, e.g.
$(selector).filter(function() {
return ...;
}).addClass("download");
Upvotes: 1