How can I dynamically create anchor elements in any text with a URL?
eg.
Turn this
<p>go to http://google.com</p>
into this
<p>go to <a href="http://google.com">link</a></p>
How can I dynamically create anchor elements in any text with a URL?
eg.
Turn this
<p>go to http://google.com</p>
into this
<p>go to <a href="http://google.com">link</a></p>
You could do it yourself with regexp, but it is much easier to use 3rd party module (especially when you want to do it on text that already contains some HTML), like autolinker:
https://github.com/gregjacobs/Autolinker.js/
var linkedText = Autolinker.link(textToAutolink);
Getting the regex from this answer you may loop on paragraphs and change the url, if any:
$('p').each(function(idx, ele) {
var retVal = getUrl(ele.textContent);
if (retVal) {
this.textContent = this.textContent.replace(retVal, '');
$('<a/>', {href: retVal, html: retVal}).appendTo($(this));
}
})
function getUrl(t) {
var expression = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi;
var regex = new RegExp(expression);
var result = t.match(regex);
if (result) {
return result[0];
} else {
return '';
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>go to http://google.com</p>
<p>go to hhhhh</p>
$.prototype.anchor = function() {
if (this[0].textContent) {
this.html(this[0].textContent.replace(/((https?:\/\/)?((\w){1,63}\.)?(\w){1,253}\.(\w){2,63}([\w:=-_\/]+)?)/gi, '<a>$1</a>'))
.find('a').each(function() { this.href = this.textContent; });
}
return this;
};
//call .anchor() on any jQuery object to parse it
$('p').each(function() { $(this).anchor(); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>go to http://stackoverflow.com/questions</p>
<p>dont go here</p>
<p>google.com is meh</p>
<p>go to http://www.google.com or https://www.google.com</p>
<p>not a phishing link www.google.com!</p>
<p>violets are foo.bar, roses are Lorem.ipsum:42/dolor?sit=amet</p>
The regex:
/((https?:\/\/)?((\w){1,63}\.)?(\w){1,253}\.(\w){2,63}([\w:=-_\/]+)?)/gi
/(
- / starts a regular expression. ( opens the first group so we can capture the entire URL
(https?:\/\/)?
- optionally match the protocol
((\w){1,63}\.)?
- optionally match a hostname
(\w){1,253}\.(\w){2,63}
- match the domain followed by a . followed by a top level domain
([\w:=-_\/]+)?
- optionally match any other path or parameters
)/gi
- ) closes the first grouping, / closes the regex, g searches for all instances, i ignores text case
The non-regex:
$.prototype.anchor = fucntion()
- add .anchor() method to jQuery
if (this[0].textContent)
- prevents errors if used on a non-text object
this.html()
- you could also use this[0].innerHTML = ... , but that isn't chainable
this[0].textContent.replace(..., '<a>$1</a>')
- if a URL is matched, wrap it in anchor tags. If it's not matched, the text is left unchanged
.find('a')
- find any anchors that we may have just added
this.href = this.textContent
- make the anchor and actual hyperlink
return this
- maintains chainability