Reputation: 7344
I'm trying to ignore any links in a part of HTML, and get anything that does not have a link to do my function.
What I have so far is:
$(document).ready(function() {
// search through paragraphs
$("p").each(function() {
// if there is not a link
if (!$(this).find('a').hasClass('external-link')) {
// do my function
}
})
})
My problem I am having, is that if there is a link in a line, but also something I want to capture in the same line it does not work, as it ignores the entire line.
Here is link to a working JSFiddle, which hopefully will let you see what I am trying to do.
Thank you in advance
Edit:
I may have worded the question slightly confusingly.
An example of what I am trying to achieve is:
<p>Link to ignore: <a href="http://www.bbc.co.uk" class="external-link" rel="nofollow">news</a>
Link to create: news </p>
My code would search through the <p>
tags for "news", and then create a link to the website. However, I do not want to create a link on top of an existing link. My current code, would ignore everything within the <p>
tags, because there is a link there already.
Upvotes: 4
Views: 150
Reputation: 34406
I took a different approach and extended jQuery's function prototype -
$.fn.extend({
replace: function (options) {
var defaults = {
search: ''
};
options = $.extend(defaults, options);
return this.each(function () {
var string = $(this).html();
//var regex = /(search)/g;
var regex = /(^|\s)news/;
//var regex = new RegExp("(^|\s)" + options.search);
console.log(regex);
var replace_text = string.replace(regex, '<a href = "https://www.bbc.co.uk/$1">$&</a>');
$(this).html(replace_text);
});
}
});
$('p').replace({search: 'news'});
$('p').replace();
Changing the regex slightly to account for a space (instead of a greater than bracket) at the beginning of 'news' allows a single neat call to the extended function. Also updated to make the function more useful, allowing the user to pass arguments to the function. Still not perfect - a work in progress.
Upvotes: 1
Reputation: 318162
Here's one way to ignore the anchors so you don't create new anchors inside existing anchors.
This targets the textNodes only
$(document).ready(function () {
$("p").contents().each(function(_, node) {
if ( node.nodeType && node.nodeType === 3 ) {
var regex = /(news)/g;
var value = node.nodeValue.replace(regex, '<a href="https://www.bbc.co.uk/$1">$$&</a>');
if (value.match(regex)) {
var wrap = document.createElement('span');
wrap.innerHTML = value
node.parentNode.insertBefore(wrap, node);
node.parentNode.removeChild(node);
}
}
});
});
To keep the dollarsign, you have to do $$
as the dollarsign has special meaning in a regular expression.
Upvotes: 2
Reputation: 10572
You could do this by looking at the childnodes of each p
and grabbing the ones that do not have a class of external-link
:
var otherText = [];
$("p").each(function(){
console.log(this.childNodes);
var kids = this.childNodes;
for(var i = 0; i < kids.length; i++)
{
if(!($(kids[i]).hasClass("external-link")))
{
otherText.push(kids[i]); //or do what you want with the node here
}
}
});
console.log("other Text", otherText);
Upvotes: 0