i can find text of an element by using this code.but i want to find a single word any where in my page if mouse hovers on that word for certain time.
$(document).bind("mouseover", function (e) {
var event = e;
setTimeout(function () { $(event.target).contents().each(function(index, elem) {
if( elem.nodeType === 3 && $.trim(elem.nodeValue).length ) {
var text = $.trim(elem.nodeValue);
text = text.split(" ");
console.log($.trim(elem.nodeValue));
//alert($.trim(elem.nodeValue));
return false;
}
});
}, 5000);
});
This is likely not the best code ever, but it might get you on the right track, going off of andyb's comment.
Something like
$(".first").on("hover",function(){
var words = $(this).text().split(" ");
var fullText = "";
for(i=0;i<words.length;i++){
words[i] = "<span>"+words[i]+"</span> ";
fullText += words[i];
}
$(this).text("").append(fullText);
$(this).children("span").on("hover", function(){
$(".second").text($(this).text());
});
});
Though looking at the working example is your best option.
$(document).bind("mouseover", function (e) {
var event = e;
setTimeout(function () { $(event.target).contents().each(function(index, elem) {
if( elem.nodeType === 3 && $.trim(elem.nodeValue).length ) {
var text = $.trim(elem.nodeValue);
text = text.split(" ");
var words = (elem.nodeValue).split(" ");
var fullText = "";
for(i=0;i<words.length;i++){
words[i] = "<span>"+words[i]+"</span> ";
fullText += words[i];
}
$(event.target).html("").append(fullText);
$(event.target).children("span").on("hover", function(){
//$(".second").text($(this).text());
console.log($(this).text());
});
console.log($(event.target).html());
return false;
} //alert($(event.target).text()+$(event.target).html());
});},
10000);
});
now my code is this....and working well.but the problem is that now, if an anchor tag or tag have chailds tag or span tag after some text, it just picks up the text parse it and neglect the child nodes.......:(....i want to pick these child nodes...put span tags for every word and than the outer text
Related
I have text, in which on selection I need to replace the text.
Here my requirement is, the space must be remain same after replacing the characters which contains spaces between them.
JavaScript:
function getSel() {
// obtain the object reference for the textarea>
var txtarea = document.getElementById("mytextarea");
// obtain the index of the first selected character
var start = txtarea.selectionStart;
// obtain the index of the last selected character
var finish = txtarea.selectionEnd;
//obtain all Text
var allText = txtarea.value;
// obtain the selected text
var sel = Array(finish - start).join("*");
//append te text;
var newText = allText.substring(0, start) + sel + allText.substring(finish, allText.length);
txtarea.value = newText;
$('#newpost').offset({ top: 0, left: 0 }).hide();
}
$(document).ready(function () {
var position;
$('#newpost').hide();
$('#mytextarea').on('select', function (e) {
$('#newpost').offset(position).show();
var txtarea = document.getElementById("mytextarea");
var start = txtarea.selectionStart;
var finish = txtarea.selectionEnd;
$('#newpost p').text(Array(finish - start).join("*"));
}).on('mousedown', function (e) {
position = { top: e.pageY-5, left: e.pageX};
});
$('#newpost').hide();
});
Here is my plunker
I am getting output as shown in above image but in expected output the space must not be replaced with asterisk .
Use string.replace instead, try this:
console.log('g2ggg gggGG'.replace(/[a-zA-Z0-9]/g, '*'))
Your all string manipulation logic will be only 1 line:
newText = allText.replace(/[a-zA-Z0-9]/g, '*')
I'm not very good at regex so I used a for-loop but maybe this still helps you.
$(document).ready(function () {
$('#mytextarea').on('select', function (e) {
var $output = $("#output");
var $txtarea = $("#mytextarea");
var start = $txtarea[0].selectionStart;
var finish = $txtarea[0].selectionEnd;
var subtext = $txtarea.text().substr(start, finish);
var out = "";
for (var i = 0; i < subtext.length; i++) {
var char = subtext[i];
if (char == " ") {
out += " ";
} else {
out += "*";
}
}
$output.text(out);
});
});
Based on your code you can see the working example in this fiddle:
I'm using a Kendo UI Editor. I want to highlight the excess characters that are typed/pasted in the editor. This is what I've done:
$(function () {
var $editor = $('#txt-editor');
$editor.kendoEditor({
keydown: ValidateRichTextEditor
});
});
function ValidateRichTextEditor(e) {
var editor = $(e.sender.textarea),
kendoEditor = editor.data('kendoEditor'),
characters = kendoEditor.body.innerText.length,
limit = editor.data('valLengthMax');
if (characters > limit) {
var textNodes = getTextNodes(kendoEditor.body),
charCount = 0,
startNode, startOffset;
for (var i = 0, textNode; textNode = textNodes[i++];) {
var chars = charCount + textNode.length;
if (limit < chars) {
//set the text node as the starting node
//if the characters hit the limit set
startNode = textNode;
startOffset = chars - charCount;
break;
}
//add the length of the text node to the current character count
charCount += textNode.length;
}
var range = kendoEditor.createRange();
range.setStart(startNode, startOffset);
kendoEditor.selectRange(range);
kendoEditor.document.execCommand('backColor', false, '#fcc');
}
}
function getTextNodes(node) {
var textNodes = [];
//node type 3 is a text node
if (node.nodeType == 3) {
textNodes.push(node);
} else {
var children = node.childNodes;
for (var i = 0, len = children.length; i < len; i++) {
textNodes.push.apply(textNodes, getTextNodes(children[i]));
}
}
return textNodes;
}
jsfiddle
So far, the highlighting works but the cursor position is always at the position where the highlighting starts. How can I position the cursor so that it would remember the last place it was? Say for example I just keep on typing, the cursor should be at the end of the editor content. Or when I click somewhere in the middle of the content, the cursor should start where I clicked on the content.
Help on this would be greatly appreciated. Thanks!
If I am correctly interpreting your requirement, there is a much simpler solution than what you are attempting.
(function () {
var $editor = $('#txt-editor'),
limit = $editor.data('valLengthMax')
limitExceeded = false;
$editor.kendoEditor({
keyup: ValidateRichTextEditor
});
function ValidateRichTextEditor(e) {
var characters = this.body.innerText.length;
console.log('\'' + this.body.innerText + '\' : ' + this.body.innerText.length);
if (characters >= limit && !limitExceeded) {
limitExceeded = true;
this.exec('backColor', { value: '#fcc' });
}
}
})();
Update 1: This solution is a bit buggy. The backspace key causes some hiccups.
Update 2: After a lot of fiddling, you cannot trust body.innerText.length. It never returns the correct value once the background color style is executed. My reasoning is that the <span> elements that are added to the body are counted as characters and the backspace key does not remove them as would be expected.
Here is a JSBin example where you can read the console output as you type. Illogical to say the least.
I managed to make this little jquery function to count the number of words entered in textarea field.
here is the fiddle
and here is the code:
JQUERY:
$(document).ready(function()
{
var wordCounts = {};
$("#word_count").keyup(function() {
var matches = this.value.match(/\b/g);
wordCounts[this.id] = matches ? matches.length / 2 : 0;
var finalCount = 0;
$.each(wordCounts, function(k, v) {
finalCount += v;
});
$('#display_count').html(finalCount);
am_cal(finalCount);
}).keyup();
});
and here is html code
<textarea name="txtScript" id="word_count" cols="1" rows="1"></textarea>
Total word Count : <span id="display_count">0</span> words.
how can i make modifications in it to have the output like this
Total word Count : 0 words. Words left : 200
and when it reach 200 words it shall not allow to either paste, or type more words in the textarea field, in jquery? i.e. it shall restrict user to type exactly 200 words not more than that.
Please help.
Thanks a lot in advance.
EDIT: The modification is needed in this code only, as i am very well aware of the plugins, but they may interfere with the main code.
Using return false to stop keyup events doesn't block the event, because in this case the event has already fired. The keyup event fires when the user releases a key, after the default action of that key has been performed.
You will need to programmatically edit the value of the textarea you have as #wordcount:
$(document).ready(function() {
$("#word_count").on('keyup', function() {
var words = 0;
if ((this.value.match(/\S+/g)) != null) {
words = this.value.match(/\S+/g).length;
}
if (words > 200) {
// Split the string on first 200 words and rejoin on spaces
var trimmed = $(this).val().split(/\s+/, 200).join(" ");
// Add a space at the end to make sure more typing creates new words
$(this).val(trimmed + " ");
}
else {
$('#display_count').text(words);
$('#word_left').text(200-words);
}
});
});
http://jsfiddle.net/k8y50bgd/
I would do it like this ?
$("#word_count").on('keydown', function(e) {
var words = $.trim(this.value).length ? this.value.match(/\S+/g).length : 0;
if (words <= 200) {
$('#display_count').text(words);
$('#word_left').text(200-words)
}else{
if (e.which !== 8) e.preventDefault();
}
});
FIDDLE
A simple plugin can be found here:
Simple Textarea Word Counter using jQuery
Adding a simple if condition will solve your problem.
$.each(wordCounts, function(k, v) {
if(finalCount <= 200) {
//Todos
}
else {
return false; //prevent keyup event
}
});
$(document).ready(function(){
$("textarea").on('keyup',function(){
var value = $('textarea').val();
var wordCount = 0;
if(value == ""){
$('textarea').empty();
}
else{
var regex = /\s+/gi;
var wordCount = value.trim().replace(regex, ' ').split(' ').length;
}
if(wordCount > 25){
var trimmed = $(this).val().split(/\s+/,25).join(" ");
$(this).val(trimmed + " ");
}
else{
$('#display_count').html(25- wordCount +" words left");
}
});
});
You can use positive lookahead regexes to preserve the whitespace - so that returncodes and tabs are not collapsed to a single space. Something like this:
var wordLimit = 5;
var words = 0;
var jqContainer = $(".my-container");
var jqElt = $(".my-textarea");
function charLimit()
{
var words = 0;
var wordmatch = jqElt.val().match(/[^\s]+\s+/g);
words = wordmatch?wordmatch.length:0;
if (words > wordLimit) {
var trimmed = jqElt.val().split(/(?=[^\s]\s+)/, wordLimit).join("");
var lastChar = jqElt.val()[trimmed.length];
jqElt.val(trimmed + lastChar);
}
$('.word-count', jqContainer).text(words);
$('.words-left', jqContainer).text(Math.max(wordLimit-words, 0));
}
jqElt.on("keyup", charLimit);
charLimit();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="my-container">
<textarea class="my-textarea"></textarea>
<span class="words-left"></span> words left
<div>
Here is the final solution.
(function(){
$("textarea").after("<p>Number of words: <span class='count'>0</span>/10</p>");
$("textarea").keypress(function(){
var words = $.trim($(this).val()).split(" ").filter(function(word){
return $.trim(word).length > 0
});
var wordlength = words.length;
$(".count").text(wordlength);
if(wordlength > 10){
alert("Please do not enter more than 10 words");
$(this).val( words.splice(0,10).join(" "));
return false;
}
})
})
can we get the word on which a right click was made and x,y coordinates of that word ?
i tried:
document.onclick=getTextOnClick;
function getTextOnClick(e)
{
console.log(e);
if (window.getSelection) {
txt = window.getSelection();
console.log(">>>"+txt);
} else if (document.getSelection) {
// FireFox
txt = document.getSelection();
console.log(txt);
} else if (document.selection) {
// IE 6/7
txt = document.selection.createRange().text;
console.log(txt);
}
}
Now this code works if i select some text, but can i get the same when i just eight click or click on certain word ? And event object is giving me coordinates of click. can i get coordinates of the word on which the click was made ? Plz help
This can be done with pure JavaScript, assuming your container contain "simple" words only:
window.onload = function() {
var oDiv = document.getElementById("Container");
var rawHTML = oDiv.innerHTML;
var arrWords = rawHTML.split(" ");
oDiv.innerHTML = "";
for (var i = 0; i < arrWords.length; i++) {
var curWord = arrWords[i];
var curSpan = document.createElement("span");
curSpan.innerHTML = curWord;
if (i < (arrWords.length - 1))
curSpan.innerHTML += " ";
curSpan.onclick = WordClicked;
curSpan.oncontextmenu = WordClicked;
oDiv.appendChild(curSpan);
}
};
function WordClicked() {
var word = this.innerHTML;
alert("You clicked: " + word);
return false;
}
Live test case - handles both left and right click.
One way that comes to mind is putting each word in a span of its own. Apart from that, I think it will be difficult to find a solution that runs consistently on all browsers.
Thy this ?
Text ->
<div id="foo">Hello I am a text. I have no clue why I am here or
what I am good for, but I have QUOTES and other things I can offer.</div>
jQuery ->
$('#foo').contents().each(function(_, node) {
var nodelist = node.textContent.split(/\s/).map(function( word ) {
return $('<span>', {
text: word + ' ',
click: function() {
alert( $(this).text() );
}
}).get(0);
});
$('#foo').empty().append(nodelist);
});
Demo -> http://jsfiddle.net/qLuEF/
I have a regular expression task at hand and can really use some help.
Say I have a text like below:
To Sherlock Holmes she is always <i>THE</i> woman.
I need to enclose each character in a span tag, with exception of HTML tags. For example, the text above would be:
<span>T</span><span>o</span><span> </span><span>S</span><span>h</span>
<span>e</span><span>r</span><span>l</span><span>o</span><span>c</span>
<span>k</span><span> </span><span>H</span><span>o</span><span>l</span>
<span>m</span><span>e</span><span>s</span><span> </span><span>s</span>
<span>h</span><span>e</span><span> </span><span>i</span><span>s</span>
<span> </span><span>a</span><span>l</span><span>w</span><span>a</span>
<span>y</span><span>s</span><span> </span><i><span>T</span><span>H</span>
<span>E</span></i><span> </span><span>w</span><span>o</span><span>m</span>
<span>a</span><span>n</span><span>.</span>
Note that:
each character is enclosed in a span
tag, even a space
HTML tag, <i></i> is not
Any suggestion is welcome.
Thanks!
This job is better handled by DOM interactions. The following two utility functions will work help wrapping each character in the given text with a span tag.
/**
* recursively get all text nodes as an array for a given element
*/
function getTextNodes(node) {
var childTextNodes = [];
if (!node.hasChildNodes()) {
return;
}
var childNodes = node.childNodes;
for (var i = 0; i < childNodes.length; i++) {
if (childNodes[i].nodeType == Node.TEXT_NODE) {
childTextNodes.push(childNodes[i]);
}
else if (childNodes[i].nodeType == Node.ELEMENT_NODE) {
Array.prototype.push.apply(childTextNodes, getTextNodes(childNodes[i]));
}
}
return childTextNodes;
}
/**
* given a text node, wrap each character in the
* given tag.
*/
function wrapEachCharacter(textNode, tag) {
var text = textNode.nodeValue;
var parent = textNode.parentNode;
var characters = text.split('');
characters.forEach(function(character) {
var element = document.createElement(tag);
var characterNode = document.createTextNode(character);
element.appendChild(characterNode);
parent.insertBefore(element, textNode);
});
parent.removeChild(textNode);
}
Now given some piece of HTML, we will create a DOM representation of it, and then retrieve all text nodes from it using the first function - getTextNodes. Once we have all the text nodes, we can pass each one of them to the second function - wrapEachCharacter.
// create a wrapper element that will hold our HTML.
var container = document.createElement('div');
container.innerHTML = "To Sherlock Holmes she is always <i>THE</i> woman.";
// get all text nodes recursively.
var allTextNodes = getTextNodes(container);
// wrap each character in each text node thus gathered.
allTextNodes.forEach(function(textNode) {
wrapEachCharacter(textNode, 'span');
});
An example is posted here.
Something along this line should do the trick
txt = txt.replace (/(<.*?>)|(.)/g, function (m0, tag, ch) {
return tag || ('<span>' + ch + '</span>');
});
Don't use a regex, just loop over the string using a for loop:
var s = 'To Sherlock Holmes she is always <i>THE</i> woman.';
var out = '';
for (var z = 0; z < s.length; ++z) {
var ch = s.charAt(z);
if (ch == '<') {
while (ch != '>') {
out += ch;
ch = s.charAt(++z);
}
out += ch;
continue;
}
out += '<span>' + ch + '</span>';
}
alert(out);