I am writing a short function that appends a random string that is equal in length to a given word. For example, if you input the word 'hello' it would return a random string that is 5 letters long.
This part works as expected. However, I am using $('output').html(""); to overwrite the last random string. I have used this for other functions before and it has worked as expected but it does not here. I have tried moving it around the function to see if it has something to do with the order of the function but it's not deleting the previous random string.
What am I doing wrong?
Fiddle here
HTML:
<input type="text" id="input">
<button id="button">Click Me</button>
<div id="output"></div>
JavaScript:
var text = "";
var possible = "abcdefghijklmnopqrstuvwxyz";
$(document).ready(function () {
$('#button').on('click', function () {
var value = ($('#input').val());
for (i = 0; i < value.length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
};
$('#input').val("");
$('#output').html("");
$('#output').html(text);
});
});
The problem is not with the .html() part. The problem is that your var text is never getting reset.
For reference - http://jsfiddle.net/oo5eLbpu/2/
Updated answer will be as follows
var possible = "abcdefghijklmnopqrstuvwxyz";
$(document).ready(function() {
$('#button').on('click', function() {
var text = ""; // moved the variable inside the click handler
var value = ($('#input').val());
for (i = 0; i < value.length; i++) {
text += possible.charAt(Math.floor(Math.random() *
possible.length));
};
$('#input').val("");
$('#output').html("");
$('#output').html(text);
});
});
Additionally, you can remove the following line from code
$('#output').html("");
As the line beneath it sets the content of the element.
For reference - http://jsfiddle.net/oo5eLbpu/4/
For documentation - http://api.jquery.com/html/
You need also reset variable text,
$('#button').on('click', function() {
text = '';
// your code
});
Example
or move text variable from parent scope to onlick handler
$('#button').on('click', function() {
var text = '';
// your code
});
Example
Also you don't need
$('#output').html("");
because you set content
$('#output').html(text);
Try
$('#output').empty();
From: https://api.jquery.com/empty/
Related
Why this code is not working ?
I think i am doing some silly mistake here.
document.addEventListener("DOMContentLoaded", function() {
var text = "Planing";
document.getElementsByTagName("div").innerHTML = text;
});
<div id="demo" class="eg"></div>
getElementsByTagName returns a collection of all the matching elements(<div>s in this case) on the page/DOM, to select first element use array notation with zero index.
document.addEventListener("DOMContentLoaded", function() {
var text = "Planing";
document.getElementsByTagName("div")[0].innerHTML = text;
});
<div id="demo" class="eg"></div>
If you want to select first element, you can use document.querySelector('div');
If you want to perform some operation on all the selected elements, you need to iterate over them.
var allDivs = document.getElementsByTagName("div");
for (var i = 0; i < allDivs.length; i++) {
allDivs[i].innerHTML = 'Div ' + i;
}
getElementsByTagName, as the name suggests returns an array of elements (even if there is just one). You need to access the first one before applying the text.
document.addEventListener("DOMContentLoaded", function() {
var text = "Planing";
document.getElementsByTagName("div")[0].innerHTML = text;
});
<div id="demo" class="eg"></div>
I have a monospaced textarea (not unlike the stackexchange editor). When my user clicks, I need a character to automagically appear on the previous line using jQuery. I know I need to use .click() to bind a function to that event, but the logic of the function eludes me.
Desired Behavior...user will click at position of the asterisk *
Here is some text in my editor.
When I double click at a position*
I want to insert a new line above, with a new character at the same position
The above text should become the following after the function gets run
Here is some text in my editor.
*
When I double click at a position*
I want to insert a new blank line above, at the same position
What I have tried:
I have found the caret jQuery plugin, which has a function called caret() that I can get to find the position of the the asterisk when I click (the position is 74).
<script src='jquery.caret.js'></script>
$('textarea').click(function(e) {
if (e.altKey){
alert($("textarea").caret());
}
});
But I really need to know the position of the character within the line, not the entire textarea. So far this eludes me.
Here's something without using caret.js
$('textarea').dblclick(function(e){
var text = this.value;
var newLinePos = text.lastIndexOf('\n', this.selectionStart);
var lineLength = this.selectionStart - newLinePos;
var newString = '\n';
for(var i=1; i < lineLength; ++i){
newString += ' ';
}
newString += text.substr(this.selectionStart,this.selectionEnd-this.selectionStart);
this.value = [text.slice(0, newLinePos), newString, text.slice(newLinePos)].join('');
});
Here's a fiddle. Credit to this post for 'inserting string into a string at specified position'.
Just realised that doing that on the top line is a bit broken, I'll have a look when I get home!
Update
Fixed the top-line problem.
if(newLinePos == -1){
this.value = newString + '\n' + this.value;
} else {
this.value = [text.slice(0, newLinePos), '\n'+newString, text.slice(newLinePos)].join('');
}
http://jsfiddle.net/daveSalomon/3dr8k539/4/
Assuming you know the position of the caret in the whole text area here's something you might do with it.
function getCaretPosition(text, totalOffset) {
var line = 0, pos = 0;
for (var i = 0; i < Math.min(totalOffset, text.length); i++) {
if (text[i] === '\n') {
line++;
pos = 0;
} else {
pos++;
}
}
return { row: line, col: pos };
}
var caretPosition = getCaretPosititon($("textarea").val(), $("textarea").caret());
It is a calculator which has spans from which I want to take a values(1,2,3, etc.) and two fields: First for displaying what user is typing and the second is for result of calculation.
The question how to get values so when I click on spans it will show it in the second field
Here is the code.
http://jsfiddle.net/ovesyan19/vb394983/2/
<span>(</span>
<span>)</span>
<span class="delete">←</span>
<span class="clear">C</span>
<span>7</span>
<span>8</span>
<span>9</span>
<span class="operator">÷</span>
....
JS:
var keys = document.querySelectorAll(".keys span");
keys.onclick = function(){
for (var i = 0; i < keys.length; i++) {
alert(keys[i].innerHTML);
};
}
var keys = document.querySelectorAll(".keys span");
for (var i = 0; i < keys.length; i++) {
keys[i].onclick = function(){
alert(this.innerHTML);
}
}
keys is a NodeList so you cannot attach the onclick on that. You need to attach it to each element in that list by doing the loop. To get the value you can then simple use this.innerHTML.
Fiddle
This should get you started.. you need to get the value of the span you are clicking and then append it into your result field. Lots more to get this calculator to work but this should get you pointed in the right direction.
Fiddle Update: http://jsfiddle.net/vb394983/3/
JavaScript (jQuery):
$(".keys").on("click","span",function(){
var clickedVal = $(this).text();
$(".display.result").append(clickedVal);
});
You can set a click event on the span elements if you use JQuery.
Eg:
$("span").click(
function(){
$("#calc").val($("#calc").val() + $(this).text());
});
See:
http://jsfiddle.net/vb394983/6/
That's just to answer your question but you should really give the numbers a class such as "valueSpan" and the operators a class such as "operatorSpan" and apply the events based on these classes so that the buttons behave as you'd expect a calculator to.
http://jsfiddle.net/vb394983/7/
var v="",
max_length=8,
register=document.getElementById("register");
// attach key events for numbers
var keys = document.querySelectorAll(".keys span");
for (var i = 0; l = keys.length, i < l; i++) {
keys[i].onclick = function(){
cal(this);
}
};
// magic display number and decimal, this formats like a cash register, modify for your own needs.
cal = function(e){
if (v.length === self.max_length) return;
v += e.innerHTML;
register.innerHTML = (parseInt(v) / 100).toFixed(2);
}
Using JQuery will make your life much easier:
$('.keys span').click(function() {
alert(this.innerHTML);
});
My object is to take a header and by only using JavaScript (no JQuery), randomly color each individual letter. What I have seems to be pretty close:
<!DOCTYPE html>
<html>
<body>
<h1 id="demo">TEST</h1>
<script language="javascript" type="text/javascript">
function myFunction()
{
var x=document.getElementById("demo");
var l=x.innerHTML.length;
var newText="";
for(var a=0;a<l;a++)
{
var letter = x.innerHTML.charAt(a);
newText += letter.fontcolor(getColor());
}
x.innerHTML=newText;
alert(x.innerHTML);
}
function getColor()
{
var colorString="";
for(var i=0;i<6;i++)
{
var num = Math.floor(Math.random()*17);
hexNum = num.toString(16);
colorString += hexNum;
}
return colorString;
}
</script>
<button type="button" onclick="myFunction()">Change Color</button>
</body>
</html>
What's happening is the fontcolor method actually does <FONT color=#FF0000>T</FONT><FONT color=#00FF00>E</FONT><FONT color=#0000ff>S</FONT><FONT color=#000000>T</FONT> This works for the first time I hit the button, but the next time I hit it, it does the fontcolor for every letter in the code snipit. I've confirmed this based on my alert I have in my code. Is there a more practical way of coloring individual letters? Is it possible to retrieve just the letters from the header instead of the letters plus the font coloring code? I'm unable to use JQuery and, if possible, would rather not use spans. Thanks a lot!
Well, after calling the function once x.innerHTML will not only contain the text, but also the HTML for the font elements. If you want to get the inner text only, you can use textContent or innerText (depending on the browser):
var x = document.getElementById("demo");
var text = x.textContent || x.innerText;
var newText="";
for(var a=0; a < text.length; a++) {
var letter = text.charAt(a);
// ...
}
If you don't care about IE8 or IE7, you can do this more elegantly with:
var new_text = Array.prototype.map.call(x.textContent || x.innerText, function(letter) {
return letter.fontcolor(getColor());
}).join('');
But you really shouldn't use the font element anymore, it's deprecated since ages.
Warning: fontcolor is not standard and <font> elements are deprecated!
This feature is non-standard and is not on a standards
track. Do not use it on production sites facing the Web: it will not
work for every user. There may also be large incompatibilities between
implementations and the behavior may change in the future.
You can use .textContent:
function myFunction()
{
var x = document.getElementById("demo"),
txt = x.textContent,
newText = "";
for(var i=0, l=txt.length; i<l; i++)
{
newText += txt.charAt(i).fontcolor(getColor());
}
x.innerHTML = newText;
}
Demo
You could use
function myFunction()
{
var x = document.getElementById("demo"),
txt = x.innerHTML;
(myFunction = function() {
var newText = "";
for(var i=0, l=txt.length; i<l; i++)
{
newText += '<span style="color:#'+getColor()+'">'+txt.charAt(i)+'</span>';
}
x.innerHTML = newText;
})();
}
Demo
It works on old browsers because it doesn't use .textContent, and doesn't use the non-standard fontcolor
Well, you could before you replace the text, you move the text in the title attribute, and then use the attribute for the original text and then you will always have the original text. For example:
<h1>Flip That</h1>
Then you have your script before it does the random colors set the title if it hasn't been set before like below:
<h1 title="Flip That">Flip That</h1>
Then you always use the title instead for the original string:
<h1 title="Flip That"><font color="#0a0a0a">F</font><font color="#0b0b0b">l</font><font color="#0c0c0c">i</font><font color="#0d0d0d">p</font><font color="#0e0e0e"> </font><font color="#0a0a0a">T</font><font color="#0b0b0b">h</font><font color="#0b0b0b">a</font><font color="#0b0b0b">t</font></h1>
ok here is what i have:
<div id="mydiv">
<font color="green"><font size="3"><font face="helvetica">hello world</font></font></font>
</div>
I know the tags are strange, but that's what produced by the website.
So basically I want to change the font tag to bbcdoe tag, the jquery code I wrote:
$("#mydiv").find("font").text(function(){
var text = $(this).text();
var size = $(this).attr("size");
var color = $(this).attr("color");
var face = $(this).attr("face");;
if(size!=undefined){
return '[size="'+size+'"]'+text+'[/size]';
}
if(color!=undefined){
return '[color="'+color+'"]'+text+'[/color]';
}
if(face!=undefined){
return '[type="'+face+'"]'+text+'[/type]';
}
});
so what I got is only: [color="green"] hello world [/color]. always only the first tag. any idea?
ps: I tried each, replaceWith, html(), all the same result. only the first tag is change.
The reason it doesn't work is because when you call
$("#mydiv").find("font").text("New text")
For each font tag, starting from the first tag, it will replace the text within that tag.
Here is an example to show you what's going on.
Example | Code
$fonts = $("font","#mydiv");
console.log($fonts.text());
$fonts.text(function(){
return "New text";
});
console.log($fonts.text());
Here is an example of how you could do it instead
Example | Code
jQuery.fn.reverse = [].reverse;
var attributes= ["size", "color", "face"];
var text = $.trim($("#mydiv").text());
$("font","#mydiv").reverse().each(function(i, e) {
for (var i = 0; i < attributes.length; ++i){
var attr = $(e).attr(attributes[i]);
if( typeof attr != "undefined")
text = "["+attributes[i]+"="+attr+"]"+text+"[/"+attributes[i]+"]";
}
});
$("#mydiv").text(text);
A room full of sad, wailing kittens wishes that you'd get rid of those <font> tags, but you could probably make it work by explicitly working your way down through the nested tags.
It does what it does now because the outer call to .text() runs for the very first <font> tag, and it obliterates the other tags.
edit — to clarify, when you call
$('#mydiv').find('font')
jQuery will find 3 font tags. The library will therefore call the function you passed into .text() for each of those elements. However, the first call will have the effect of removing the other two <font> elements from the DOM. Even though the library proceeds to call your callback for those elements, there's no effect because they're not on the page anymore.
Here's what could work:
var $fonts = $('#mydiv').find('font');
var text = $fonts.text();
var attrs = {};
$fonts.each(function(_, font) {
var names = ["size", "color", "face"];
for (var i = 0; i < names.length; ++i)
if (font[names[i]]) attrs[names[i]] = font[names[i]];
});
var newText = "";
for (var name in attrs) {
if (attrs.hasOwnProperty(name))
newText += '[' + name + '=' + attrs[name] + ']';
}
newText += text;
for (var name in attrs) {
if (attrs.hasOwnProperty(name))
newText += '[/' + name + ']';
}
$('#mydiv').text(newText);
Note that I'm not really sure why you want to put the BBCode onto the page like that, but it seems to be the intention.
Seems to me your first line should be:
$("#mydiv").find("font").each(function(){