Getting text selection with javascript, then modify text - javascript

I have a text on an HTML page. If the user selects a word, I can retrieve the selected word and know exactly what he or she selected. However, I now want to also modify this word on the screen and make it bold. But I do not know how I would do this, since I only know the word clicked, but do not see an easy way to find the word in the HTML and modify it. I could of course search for it, but there is the risk of a word appearing multiple times.
A different way I thought about would be to give each word a unique idea and have something like this:
<span id="1">The</span>
<span id="2">fox</span>
<span id="3">jumps</span>
<span id="4">over</span>
<span id="5">the</span>
<span id="6">fence</span>
But I do not like this solution. This, too, seems overly complicated, does it not? Any suggestions how else I could access the exact words selected?

You can dynamically create a span surrounding the selected word:
const p = document.querySelector('p');
p.addEventListener('mouseup', () => {
const range = document.getSelection().getRangeAt(0);
do {
const charBefore = range.startContainer.textContent[range.startOffset - 1];
if (charBefore.match(/\s/)) break;
range.setStart(range.startContainer, range.startOffset - 1);
} while (range.startOffset !== 0);
do {
const charAfter = range.endContainer.textContent[range.endOffset];
if (charAfter.match(/\s/)) break;
range.setEnd(range.endContainer, range.endOffset + 1);
} while (range.endOffset !== range.endContainer.textContent.length);
const span = document.createElement('span');
span.style.fontWeight = 'bold';
range.surroundContents(span);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>The fox jumps over the fence.</p>

No need of jQuery, also no need of IDs for each <span>.
The idea is to add a class to the span once it is clicked and later you can retrieve all elements with that bolded class.
Here is a solution with pure Javascript:
// comments inline
var spans = document.getElementsByTagName('span'); // get all <span> elements
for(var i=0, l = spans.length; i<l; i++){
spans[i].addEventListener('click', function(){ // add 'click' event listener to all spans
this.classList.toggle('strong'); // add class 'strong' when clicked and remove it when clicked again
});
}
.strong {
font-weight: bold;
}
<span>The</span>
<span>fox</span>
<span>jumps</span>
<span>over</span>
<span>the</span>
<span>fence</span>
Read up: Element.getElementsByTagName() - Web APIs | MDN

$("p").mouseup(function() {
var selection = getSelected().toString();
$(this).html(function(){
return $(this).text().replace(selection, '<strong>' + selection +'</strong>');
});
});
var getSelected = function(){
var t = '';
if(window.getSelection) {
t = window.getSelection();
} else if(document.getSelection) {
t = document.getSelection();
} else if(document.selection) {
t = document.selection.createRange().text;
}
return t;
}
strong{ font-weight: bold; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>The fox jumps over the fence.</p>

Related

getSelection add html, but prevent nesting of html

I have a content editable field, in which I can enter and html format som text (select text and click a button to add <span class="word"></span> around it).
I use the following function:
function highlightSelection() {
if (window.getSelection) {
let sel = window.getSelection();
if (sel.rangeCount > 0) {
if(sel.anchorNode.parentElement.classList.value) {
let range = sel.getRangeAt(0).cloneRange();
let newParent = document.createElement('span');
newParent.classList.add("word");
range.surroundContents(newParent);
sel.removeAllRanges();
sel.addRange(range);
} else {
console.log("Already in span!");
// end span - start new.
}
}
}
}
But in the case where I have:
Hello my
<span class="word">name is</span>
Benny
AND I select "is" and click my button I need to prevent the html from nesting, so instead of
Hello my
<span class="word">name <span class="word">is</span></span> Benny
I need:
Hello my
<span class="word">name</span>
<span class="word">is</span>
Benny
I try to check the parent class, to see if it is set, but how do I prevent nested html - close span tag at caret start position, add and at the end of caret position add so the html will not nest?
It should also take into account if there are elements after selection which are included in the span:
So:
Hello my
<span class="word">name is Benny</span>
selecting IS again and clicking my button gives:
Hello my
<span class="word">name</span>
<span class="word">is</span>
<span class="word">Benny</span>
Any help is appreciated!
Thanks in advance.
One way would be to do this in multiple pass.
First you wrap your content, almost blindly like you are currently doing.
Then, you check if in this content there were some .word content. If so, you extract its content inside the new wrapper you just created.
Then, you check if your new wrapper is itself in a .word container.
If so, you get the content that was before the selection and wrap it in its own new wrapper. You do the same with the content after the selection.
At this stage we may have three .word containers inside the initial one. We thus have to extract the content of the initial one, and remove it. Our three wrappers are now independent.
function highlightSelection() {
if (window.getSelection) {
const sel = window.getSelection();
if (sel.rangeCount > 0) {
const range = sel.getRangeAt(0).cloneRange();
if (range.collapsed) { // nothing to do
return;
}
// first pass, wrap (almost) carelessly
wrapRangeInWordSpan(range);
// second pass, find the nested .word
// and wrap the content before and after it in their own spans
const inner = document.querySelector(".word .word");
if (!inner) {
// there is a case I couldn't identify correctly
// when selecting two .word start to end, where the empty spans stick around
// we remove them here
range.startContainer.parentNode.querySelectorAll(".word:empty")
.forEach((node) => node.remove());
return;
}
const parent = inner.closest(".word:not(:scope)");
const extractingRange = document.createRange();
// wrap the content before
extractingRange.selectNode(parent);
extractingRange.setEndBefore(inner);
wrapRangeInWordSpan(extractingRange);
// wrap the content after
extractingRange.selectNode(parent);
extractingRange.setStartAfter(inner);
wrapRangeInWordSpan(extractingRange);
// finally, extract all the contents from parent
// to its own parent and remove it, now that it's empty
moveContentBefore(parent)
}
}
}
document.querySelector("button").onclick = highlightSelection;
function wrapRangeInWordSpan(range) {
if (
!range.toString().length && // empty text content
!range.cloneContents().querySelector("img") // and not an <img>
) {
return; // empty range, do nothing (collapsed may not work)
}
const content = range.extractContents();
const newParent = document.createElement('span');
newParent.classList.add("word");
newParent.appendChild(content);
range.insertNode(newParent);
// if our content was wrapping .word spans,
// move their content in the new parent
// and remove them now that they're empty
newParent.querySelectorAll(".word").forEach(moveContentBefore);
}
function moveContentBefore(parent) {
const iterator = document.createNodeIterator(parent);
let currentNode;
// walk through all nodes
while ((currentNode = iterator.nextNode())) {
// move them to the grand-parent
parent.before(currentNode);
}
// remove the now empty parent
parent.remove();
}
.word {
display: inline-block;
border: 1px solid red;
}
[contenteditable] {
white-space: pre; /* leading spaces will get ignored once highlighted */
}
<button>highlight</button>
<div contenteditable
>Hello my <span class="word">name is</span> Benny</div>
But beware, this is just a rough proof of concept, I didn't do any heavy testings and there may very well be odd cases where it will just fail (content-editable is a nightmare).
Also, this doesn't handle cases where one would copy-paste or drag & drop HTML content.
I modified your code to a working approach:
document.getElementById('btn').addEventListener('click', () => {
if (window.getSelection) {
var sel = window.getSelection(),
range = sel.getRangeAt(0).cloneRange();
sel.anchorNode.parentElement.className != 'word' ?
addSpan(range) : console.log('Already tagged');
}
});
const addSpan = (range) => {
var newParent = document.createElement('span');
newParent.classList.add("word");
range.surroundContents(newParent);
}
.word{color:orange}button{margin:10px 0}
<div id="text">lorem ipsum Benny</div>
<button id="btn">Add span tag to selection</button>

How would I find the innerHTML index of text highlighted from textContent?

I am trying to program a simple text editor for fun.
I am stuck on this problem.
I want to add bold or italics to highlighted text on a button click.
I figure the best way to do this is get the index of the selected text and then add the bold tag / italic tag around the tag in the innerHTML.
However, I can not seem to get the position / index of the selected tag to carry over to the innerHTML. Obviosuly, the innerHTML code is offset by the tags.
Is there an easier way to do this?
I though finding the index of the highlighted text was the way to go. Okay. Unforunately, indexOf will only find the first occurance.
var word_document = document.getElementById('word-document');
/* This code is for our bold button */
var bold_button = document.getElementById('bold-button')
bold_button.addEventListener('click', (event) => {
/* Test to see if text is highlighted */
let text = window.getSelection().toString();
console.log("Selected Text: " + text);
if (text.length > 0) {
// Find the position of the highlighted text in the word document.
let position = word_document.innerHTML.indexOf(text); // Not a good way of doing it
console.log("Pos: ", position);
// Replace the highlighted text from the document with the bold text
word_document.innerHTML.replace(text, "<b>" + text + "</b>");
}
/* If text is not highlighted, add a bold tag */
else {
// Add bold tag to bottom of document
word_document.focus();
word_document.innerHTML += "<b></b>";
word_document.selectionEnd = word_document.innerHTML.length - 6;
}
});
/* This code is for our italic button */
var italic_button = document.getElementById('italics-button');
italic_button.addEventListener('click', function() {
let text = window.getSelection().toString();
// Same issue
});
<button id="bold-button">B</button>
<button id="italics-button">I</button>
<textarea id="word-document">Starting Text</textarea>
I suppose a possible way would be to iterate over the textContent and find if any text prior to the selected text matches it, and then set a variable to skip over that many matches. Is there an easier way to do this. Ideally, I would like to create a bold tag, or italic tag and append it to the textarea in a more proper fashion. I support traversing the DOM is probably a better way. Any ideas on how this might be more easily tackled?
Thanks
I use Plain / Vanilla Javascript.
Edit: Fixed code. Adding JsFiddle here
You can try this :
<html>
<header>
</header>
<body>
<button id="bold-button" onClick="makeBold()">B</button>
<div id="word-document" contenteditable>Starting Text</div>
<script>
function makeBold() {
var inputText = document.getElementById("word-document");
var innerHTML = inputText.innerHTML;
text = window.getSelection().toString();
var index = innerHTML.indexOf(text);
if (index >= 0) {
innerHTML = innerHTML.substring(0,index) + "<span style='font-weight: bold;'>" + innerHTML.substring(index,index+text.length) + "</span>" + innerHTML.substring(index + text.length);
inputText.innerHTML = innerHTML;
}
}
</script>
</html>
the idea here is to use a fake textArea: div with content editable.
I hope it helps u,
Good Luck!
simple dummy solution. this don't work for nested tags.
I highly recommended to read this tutorial
function action({tag, classes}, event){
const text = document.getElementById("word-document");
const selection = window.getSelection();
const range = selection.getRangeAt(0);
const before = text.innerHTML.substr(0, range.startOffset);
const after = text.innerHTML.substr(range.endOffset);
const selected = text.innerHTML.substr(range.startOffset,range.endOffset - range.startOffset );
const warpped = `<${tag} ${classes ? "class=" + classes : ""}>${selected}</${tag}>`
text.innerHTML = before + warpped + after;
}
#word-document {
border: 1px solid black;
padding: 10px;
}
.underline{
text-decoration-line: underline;
}
<button onclick="action({tag: 'b'})">B</button>
<button onclick="action({tag: 'i'})">I</button>
<button onclick="action({tag: 'span', classes:'underline'})">Under score</button>
<div id="word-document" contenteditable>Starting Text</div>

Add html tags around highligted text in contenteditable div

I have a contenteditable div and i would like to add some html tags around highlighted text, after user select the text and click the button..
Here is the sample code. It has some javascript codes but i couldnt make it work as desired. And i played with a lot actually.
https://codepen.io/anon/pen/ybzzXZ
P.S. I'm going to add , or like html tags after when we solve the how to add html tags around it.
Some of that js codes which i found in stackoverflow.
function getSelectionText() {
var text = "";
if (window.getSelection) {
text = window.getSelection().text;
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
}
return text;
}
and the other one is
function replaceSelectionWithHtml(html) {
var range;
if (window.getSelection && window.getSelection().getRangeAt) {
range = window.getSelection().getRangeAt(0);
range.deleteContents();
var div = document.createElement("div");
div.innerHTML = html;
var frag = document.createDocumentFragment(), child;
while ( (child = div.firstChild) ) {
frag.appendChild(child);
}
range.insertNode(frag);
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
range.pasteHTML(html);
}
}
There are several challenges with the problem you present.
First off you need to gather the selected text value. You have posted some examples of that - that is fairly well documented elsewhere so I will leave that up to you to isolate that issue.
Next you need to highlight the selected text. Often to highlight something in HTML we wrap that text that we wish to highlight in a simple element such as a span, then give that span some class - for example often this is used to give a background color to some text. <span style='background-color:yellow'>some text</span> - not so difficult to understand that portion.
The challenge with this then is to combine your "discovered text" with the highlight. Pretty easy to wrap that text as in the span example provided earlier. One issue however is that if that text is previously within some other HTML elements, we need to ensure that the text choice in the discovery is for example not contained within another element AND if so, handle that issue. Let's illustrate that with this span: Howdy <span style='background-color:yellow'>some text</span> Some more.
Now for this example suppose we wish to highlight the text "Howdy some" - a portion of that text is previously within a span with our desired markup, thus we must first extract that, remove that "highlight" and henceforth highlight the new text "choice" of "Howdy some".
To provide an illustration of that. Type the words "This I want" into the text box and see how it gets highlighted.
This is not exactly your problem however it provides the "highlight" which you could potentially combine with your selector. I have NOT fully vetted this for bugs such as typing in HTML in to "highlight".
/* highlight words */
function findStringLimit(searchChar, searchCharIndex, searchedString) {
return searchedString.substring(0, searchedString.lastIndexOf(searchChar, searchCharIndex));
};
function highlightWords(wordsy, text) { /* eliminate a bug with parenthesis */
wordsy = wordsy.replace("(", "");
wordsy = wordsy.replace(")", ""); /* escape other characters for bug */
text = text.replace(";", "");
text = text.replace("'", "'");
text = text.replace("<", "<");
text = text.replace(">", ">");
text = text.replace("<span", "<span");
text = text.replace('autoCompleteWord">', 'autoCompleteWord">');
text = text.replace("</span", "</span");
text = text.replace('span>', 'span>');
var re = '(' + wordsy + ')(?![^<]*(?:<\/span class=\"autoCompleteWord\"|>))';
var regExp = new RegExp(re, 'ig');
var sTag = '<span class="autoCompleteWord">';
var eTag = "</span>";
return text.replace(regExp, sTag + '$&' + eTag);
};
function parseAndHighlight(wordstring, htmlString) {
var htmlStringUn = htmlString;
var found = htmlStringUn.toLowerCase().indexOf(wordstring.toLowerCase(), 0);
if (found >= 0) {
htmlStringUn = highlightWords(wordstring, htmlStringUn);
}
else {
//split and parse the beast
var words = wordstring.split(/\W+/);
var allPhrases = [];
allPhrases.push(wordstring);
var i = 0;
i = words.length;
while (i--) {
allPhrases.push(findStringLimit(" ", allPhrases[(words.length - i) - 1].length, allPhrases[(words.length - i) - 1]));
};
i = allPhrases.length;
while (i--) {
if (allPhrases[i] != "") words = words.concat(allPhrases[i]);
};
i = words.length;
while (i--) {
htmlStringUn = highlightWords(words[i], htmlStringUn);
};
};
return htmlStringUn;
}
$(document).on('change', '#myInput', function() {
var myValue = $('#myInput').val(); //get what was typed
$('#found').text(myValue);
myValue = myValue.replace(/^\s+|\s+$/g, ""); //strip whitespace on ends
$('#found').text(myValue + ':stripped:');
var showText = $('#origshower').text();
var newShowString = parseAndHighlight(myValue, showText); //my original highlighter
$('#shower').html(newShowString);
});
#holder{border:red solid 2px; padding: 5px;}
#myInput{width:200px; background-color: aqua;}
span.autoCompleteWord /* this is the word(s) found */
{
font-weight: bold;
background-color: yellow;
}
#shower{border:lime 2px solid;}
<script
src="https://code.jquery.com/jquery-1.12.4.min.js"
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
crossorigin="anonymous"></script>
<div id='holder'>
<input id='myInput' type='text' cols='60' rows='2' />Enter Text to match
</div>
<div id='origshower'>This is the span thistle with the whistle that I want matched is this neat</div>
<div id='shower'>none</div>
<div id='found'>enter</div>
You can just call executeCommand with formatBlock. You can find more information here:
https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

Need To Convert Text To UpperCase and Lowercase When Clicked

I know nothing about JavaScript, and I'm sure this is an easy thing to do, but I've been bashing my brain for the past three hours trying to figure it out.
What I want is to have some text, say Test.com, that when clicked will transform all the letters to uppercase (TEST.COM). If the user clicks again, the text will go to all lowercase(text.com). On the third click the text goes back to the original form (Test.com).
Is this possible?
var count = 1;
$('.text').click(function() {
$(this).toggleClass('uppercase', count === 2);
$(this).toggleClass('lowercase', count === 3);
if (count === 3) {
count = 0
}
count++;
});
.uppercase {
text-transform: uppercase;
}
.lowercase {
text-transform: lowercase;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="text">CamelCase 1 </span>
Here's the long-winded vanilla JS version:
// grab the element containing the text
var div = document.querySelector('#test');
// grab the text
var text = div.innerHTML;
// save a copy of the text
var originalText = div.innerHTML;
// set `toggle` to O for original
// L = lowercase, U = uppercase
var toggle = 'O';
// add an click listener to the element containing the text
div.addEventListener('click', function () {
// toggle between the states updating the text
// of the element with each new click
switch (toggle) {
case 'O':
div.innerHTML = text.toUpperCase();
toggle = 'U';
break;
case 'U':
div.innerHTML = text.toLowerCase();
toggle = 'L';
break;
case 'L':
div.innerHTML = originalText;
toggle = 'O';
break;
}
}, false)
DEMO
And if you wanted to get this working for multiple instances of text on the page, something like this would work. Ideally you'd want to use event propagation for this, but since the layout of your page might change in the future it's probably not worth the risk:
;(function () {
// grab all the elements
var divs = document.querySelectorAll('.test');
// status is used to keep track of where in the cycle each text item is
var status = {};
for (var i = 0, l = divs.length; i < l; i++) {
var div = divs[i];
var key = div.innerHTML.toLowerCase();
// update the status object with the initial text values
status[key] = {
status: 'O',
originalText: div.innerHTML
};
// add the listener like last time
// except this time we monitor the status object for
// for each text instance
div.addEventListener('click', function () {
var text = this.innerHTML.toLowerCase();
var key = status[text].originalText.toLowerCase();
var toggle = status[key].status;
var originalText = status[key].originalText;
switch (toggle) {
case 'O':
this.innerHTML = originalText.toUpperCase();
status[key].status = 'U';
break;
case 'U':
this.innerHTML = originalText.toLowerCase();
status[key].status = 'L';
break;
case 'L':
this.innerHTML = status[key].originalText;
status[key].status = 'O';
break;
}
}, false);
}
}());
DEMO
Define 2 CSS classes.
.ucase {text-transform:uppercase;}
.lcase {text-transform:lowercase;}
Use a combination of jQuery .hasClass() .removeClass() and .addClass() to switch the cases.
Remove all classes from the text to return to original state.
jQuery(document).ready(function() {
jQuery(".textitem").click(function() {
$t = jQuery(this);
if($t.hasClass("ucase")) {
$t.removeClass("ucase").addClass("lcase");
} else if($t.hasClass("lcase")) {
$t.removeClass("lcase");
} else {
$t.addClass("ucase");
}
});
});
Fiddle: https://jsfiddle.net/ptj1ke8y/
Perhaps not the most elegant solution, but you can count the clicks (modulus 3), and adjust the text according to the number and cycle through your 3 cases.
var i = 0;
var cl = $('#text').text();
$('#text').click(function() {
var str = $(this).text();
if (i % 3 == 0) {
$('#text').html(str.toUpperCase());
}
if (i % 3 == 1) {
$('#text').html(str.toLowerCase());
}
if (i % 3 == 2) {
$('#text').html(cl);
}
i++
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="text">Text</div>
You can use .toUpperCase() and .toLowerCase() JavaScript methods to change the case of any text.
Since you're using jQuery then you can use the .text() jQuery method to get and set the text content of any DOM node.
You need to store somewhere the original value of your text so that you can get it after the third click, and the jQuery .data() method would be good for this because that way you can easily have few elements on one page that behaves this way.
You can write something like this to make all elements with class "test" behave in a way that you have described:
$('.test').click(function () {
var $this = $(this),
data = $this.data('clicker');
if (!data || !data.text) {
data = {
text: [
$this.text(),
$this.text().toUpperCase(),
$this.text().toLowerCase()
],
step: 0
};
}
data.step = (data.step + 1) % 3;
$this.text(data.text[data.step]);
$this.data('clicker', data);
});
See: DEMO for an example of how it works with 3 elements simultaneously.
First use click() to event handler to the "click" and then use .hasClass(), removeClass() and addClass() to do and use css text-transform
HTML file
<div id="trigger">click me to transform</div>
CSS File
.uppercase { text-transform: uppercase; }
.lowercase { text-transform:lowercase; }
Javascript file
$( document ).ready(function() {
$( "#trigger" ).click(function() {
if($( "#trigger" ).hasClass( "uppercase" )) {
$(this).removeClass('uppercase').addClass('lowercase');
}
else {
$(this).removeClass('lowercase').addClass('uppercase');
}
});
});
Try to play the Sandbox
I think this is what you want (button caption changes to tell what is it going to do and changes the text):
<form name="form1" method="post">
<input name="instring" id="instring" type="text" value="this is the text string" size="30">
<input type="button" id="button" name="Convert" value="Make Uppercase >>" onClick="makeUppercase();">
<input name="outstring" type="text" id="outstring" value="" size="30">
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
function makeUppercase(){
if( $('#button').val()=="Make Uppercase >>"){
$('#button').attr("value","Make Lowercase >>");
$('#outstring').attr('value', $('#instring').attr('value').toUpperCase());
} else if($('#button').val()=="Make Lowercase >>") {
$('#button').attr("value","Make Original >>");
$('#outstring').attr('value', $('#instring').attr('value').toLowerCase());
} else{
$('#button').attr("value","Make Uppercase >>");
$('#outstring').attr('value', $('#instring').attr('value'));
}
}
</script>

Determining a character of a sentence when clicked on

On a random break I found myself wondering if it would be possible to use jQuery to determine a single character within a sentence when it is clicked on.
For example:
This
When the user clicks on first h, jQuery would return this to me.
The only way I could think of doing this would be to wrap each character within the sentence in a span with a class of its letter such as the following example:
<span class="clickable T">T</span>
<span class="clickable h">h</span>
<span class="clickable i">i</span>
<span class="clickable s">s</span>
Followed by a $('.clickable').click(function()) that would return its second class.
My question is: is this the most efficient way to do this?
Obviously wrapping every single letter of the document in span tags is not efficient.
I was able to spin something up that works in Chrome at least. Basically, when you click on a letter, it then triggers a double clicks which selects the word. We get the selection which actually gives us the text of the entire target element. From that, we get the letter that was clicked. We remove the selection and do what we want with the letter.
Fiddle here
$(function(){
$(document).click(function(e){
var target = e.target;
$(target).dblclick();
}).dblclick(function(){
var selection,
node,
text,
start,
end,
letter;
if (window.getSelection) {
selection = document.getSelection();
node = selection.anchorNode;
if (node.nodeType === 3) {
text = node.data;
start = selection.baseOffset;
end = selection.extentOffet;
if (!isNaN(start)) {
letter = text.substr(start, 1);
}
}
window.getSelection().removeAllRanges()
} else if(document.selection) {
//continue work here
}
if (letter) {
alert(letter);
}
});
});
You could return the innerHTML as well with:
$('.clickable').on('click', function(){
alert($(this).html());
});
As for a more efficient way to do it...maybe try this:
in Javascript/jQuery, how to check a specific part of a string and determine if it is a whitespace or letter?
You can do it with this script
$('.clickable').on('click', function(){
var html = $(this).text(); // if you want the text inside the span
var index = $(this).index(); // if you want the position among siblings
var classes = $(this).attr('class').split(" ");
var secondClass = getSecondClass(classes);
});
function getSecondClass(classArray){
if(classArray.length<2){
return null;
}else{
return classArray[1];
}
}
I've also included the html and index variables if you want to do something else with the clicked element.
Basically you split the classes of the element by spaces and then check if the array has less than two elements, in that case it returns null, otherwise it returns the second element.
jsFiddle
Well wrapping all text dyanamically with span tag , it is possible what you were looking for
JS
$(function(){
var lengthText = $('#singlecharacter').text().length;
var textValue = $('#singlecharacter').text();
var textArray = textValue.split('');
var newText = new Array();
for (var i = lengthText - 1; i >= 0; i--) {
newText[i] = "<span class='sp'>"+textArray[i]+"</span>";
};
$('#singlecharacter').html(newText);
$('.sp').click(function()
{
alert($(this).text());
});
});
HTML
<div id='singlecharacter'>THIS</div>
DEMO JSFIDDLE

Categories

Resources