How do you create a link out of circular text with JavaScript and CSS?
Tags: javascript,jquery,html,css,hyperlink
Problem :
I am using jQuery and CircleType.js to have text show in a circular pattern. My question is how can I make the text in the circle a hyperlink? The circletype.js automatically removes any a
elements that are used, and since this method puts a span tag around each letter, I am not sure how you could use circletype.js with a link.
Is there another way to to wrap text in a circular shape with links without using circletype.js? I am still a newb at JavaScript, so if there is a way to create the links with JS, then any help getting on to the right path to write the script for this would be great. My code below (minus the css):
<body>
<div id="img-container">
<p id="link-circle">
LINK ♦ LINK ♦ LINK ♦ LINK ♦ LINK ♦
</p>
<a href="#">
<div id="switch">
<form action="">
<input type="radio" id="left-radio" name="Column Select" value="left"/>
<input type="radio" id="right-radio" name="Column Select" value="right"/>
</form>
<span id="dbl-chevron">»</span>
</div>
</a>
</div>
<script type="text/javascript">
$( document ).ready(function() {
$('#link-circle').circleType();
});
</script>
</body>
Here is an example:
Maybe even a way to overlay a div layer over the text to create links would work. But I am not sure which way to go with this. Thanks in advance for any help!
Solution :
After looking at the plugin's code and playing with it, I discovered that it was the required LetteringJS plugin that was removing any tags.
They call it on line 33: $(elem).lettering();
Then I came up with an idea.
What can we do?
- We can save the HTML of our element before it gets split up by LetteringJS.
- Then, let it do its work.
- After that, we can put our tags back around each letter that was contained in one.
Partial solution
Why "partial"?
My solution will only work on:
- non self-closing tags: no
<img/>
,<input/>
, etc. but I don't think that's likely to happen. - non nested tags: no
<b><a></a></b>
, but you can fake that with classes - see demo below.
How does it work?
We need to change CircleType's source code so that it does what we want. I've commented my code, but if you don't understand something, or find a mistake or an improvement to make, don't hesitate to tell me!
// trim spaces at the beginning and at the end
elem.innerHTML = elem.innerHTML.replace(/^\s+|\s+$/g, '');
// grab the HTML string
var temp = elem.innerHTML;
// replace any space that is not part of a tag with a non-breakable space ( )
elem.innerHTML = elem.innerHTML.replace(/<[^<>]+>|\s/g, function(s) {
return s[0] == '<' ? s : ' ';
});
// wrap each character in a span
$(elem).lettering();
var inTag = false, // are we between tags? (<i>here</i>)
isTag = false, // are we inside a tag? (<here></here>)
tagNum = -1, // how many opening tags have we met so far? (minus 1)
pos = 0, // character position (excluding tags)
dom = document.createElement('div'); // temporary dom
dom.innerHTML = temp; // clone our element in the temporary dom
var tags = dom.children; // children of the element
// for each of them, empty their content
for(var i=0, l=tags.length; i<l; i++){
tags[i].innerHTML = '';
}
// for each character in our HTML string
for(var i=0, l= temp.length; i<l; i++){
var c = temp[i];
// if it's a '<'
if(c == '<'){
// and if it's an opening tag
if(!inTag){
// increment the number of tags met
tagNum++;
// we're in a tag!
inTag = true;
}
else{
// otherwise we're in a closing tag
inTag = false;
}
// we're on a tag (<here>)
isTag = true;
}
// if it's a '>'
else if(c == '>'){
// we're not <here> anymore
isTag = false;
}
// if we're not <here>
else if(!isTag){
// if we're <b>here</b>
if(inTag){
// replace the span's content with our tag
elem.children[pos].innerHTML = tags[tagNum].outerHTML;
// put the letter back in
elem.children[pos].children[0].innerHTML = c;
}
// move forward in the spans
pos++;
}
}