InnerText doesn't update in html - javascript

I am trying to write a game where on-click innerText of the object changes.
Below is the function from my JS file which is called on-click. In the console I can see the expected sign, but doesn't reflect on the page.
function printx(number){
let isko = document.getElementById("r" + number);
console.log(isko);
if(isko.innerText==""){
isko.innerText = sign;
console.log(isko.innerText);
checksign();
disp.innerHTML= "<center>" + sign + " Turn " + "</center>" ;
winner();
}
}
JS Fiddle link: https://jsfiddle.net/c9ejhox4/

Your problem is that the winner function loops through and resets innerHTML for every tile item for every turn. Make sure that loop is inside the if statement to check if someone actually won.

for loop in winner() override text in td tag

There are few errors that can be corrected.
Loop in winner() function must be inside the if condition.
innerText, innerHTML and some outdated attributes are used.
You must use jquery to avoid such lengthy code.
Update this code to jquery to see if the problem solve.

Related

jQuery for loops not running function

I'm trying to make a loop in jQuery that finds all 'img' elements and places a caption below them, according to the value of the element's 'caption' attribute. Whenever I run the loop below, I am left with no captions under any of the images.
for (var i = 0; i < $('.myimage').length; i++) {
$('.myimage')[i].after('<h6>' + $('.myimage').attr('caption') + '</h6>');
};
However, when I run this code
$('.myimage').after('<h6>TEST</h6>');
the word 'TEST' appears below all of the images. Therefore I know my html is correct, I have no typos, and the selector is working, I just cannot get the for loop to work... What have I done wrong?
$('.myimage')[i] returns a DOM element (not a jQuery object) so there is no after method. If you want to loop, simply use .each
$(".myimage").each(function() {
//this refers to each image
$(this).after('<h6>' + $(this).attr('caption') + '</h6>');
});
You can loop through the .myimage elements like this, using .after()'s callback function
$('.myimage').after(function(){
return '<h6>' + $(this).attr('caption') + '</h6>';
});
One minor note, don't make up your own attributes. use the custom data attribute instead, like data-caption="something".
jsFiddle example

Javascript function cannot be executed twice

I'm kind of new to Javascript and I've bee wondering for hours how to solve my problem. I have a litle function associated to a button. It work once but I cannot get it to execute after the first time.
function CheckEmpty1(){return "false";}
function Generate(){
if(CheckEmpty1() == "true"){
alert("Please fill all mandatory field.\n\nAll missing field are black colored.\n\nPlease also make sure to make a choice for all radio button.");
}
else{
document.getElementById('TemplateOutput').style.display = "block";
lol = "lol";
document.getElementById('TemplateOutput').value = lol;
lol = "test2";
}
return;
}
"TemplateOutput" is a simple textarea centered in the browser. The code is originally more complicated than that but while doing the test to ensure the problem was not coming from somewhere else, it reduced to that but still doesn't work.
The second "lol = "test2";" is just to check that if I make a change to the variable, it is suposed to apply the second time I hit the button.
it seems to be basic for me but I can't figure out why... any help?
thanks.
EDIT:
I think I found the source of my error in my original script. My original code look like this:
function Output(){
Output = "CSD Troubleshooting: " + Troubleshoot + "\n";
return Output;
}
function Generate(){
FillVars();
GenerateOutput = Output();
alert(GenerateOutput);
}
function FillVars(){
Troubleshoot = document.getElementById('Troubleshoot').value;
}
I reduced it to the minimum but it still behave the same way.
The problem is coming from the Output() function because it work fine if I do it like this:
GenerateOutput = document.getElementById('Troubleshoot').value;
alert(GenerateOutput);
or
GenerateOutput = Troubleshoot;
alert(GenerateOutput);
BEHAVIOR: I click the button. The alert is filling like it is suposed to be. The second time I click the button, it just do nothing.
regards,
Updated Answer:
Your edit changes things markedly. The central issue is here:
function Output(){
Output = "CSD Troubleshooting: " + Troubleshoot + "\n";
return Output;
}
The first time you run that function, you replace the function with a string. The Output symbol is a reference to the function.
It looks like you might have a Visual Basic background. In JavaScript, you simply do this:
function Output(){
return "CSD Troubleshooting: " + Troubleshoot + "\n";
}
or if you want it in a variable first, declare the variable (with var) and probably to avoid confusion use a different name:
function Output(){
var result = "CSD Troubleshooting: " + Troubleshoot + "\n";
return result;
}
Original Answer:
The second "lol = "test2";" is just to check that if I make a change to the variable, it is suposed to apply the second time I hit the button.
It won't, because your previous
lol = "lol";
...line runs, setting it back to "lol". You'll never see the code put "test2" into the input.
The line
document.getElementById('TemplateOutput').value = lol;
copies the value from lol to the value property. It does not make the value property a reference to the variable lol. Changing the variable later has no effect, because there is no continuing link between it and the value property.
Since the if block in your code will never run, let's just look at the else block. Here, in detail, is what happens:
// 1
document.getElementById('TemplateOutput').style.display = "block";
That looks in the DOM for the element with the id "TemplateOutput", and sets its style object's display property to "block".
// 2
lol = "lol";
That assigns the value "lol" to the lol variable. Unless you've declared lol somewhere you haven't shown, it also creates an implicit global variable. Details: The Horror of Implicit Globals.
// 3
document.getElementById('TemplateOutput').value = lol;
That copies the value "lol" from the lol variable into the value property of the input.
// 4
lol = "test2";
That copies the value "test2" into the lol variable.

Javascript taking too long to run

I have a script that is taking too long to run and that is causing me This error on ie : a script on this page is causing internet explorer to run slowly.
I have read other threads concerning this error and have learned that there is a way to by pass it by putting a time out after a certain number of iterations.
Can u help me apply a time out on the following function please ?
Basically each time i find a hidden imput of type submit or radio i want to remove and i have a lot of them . Please do not question why do i have a lots of hidden imputs. I did it bc i needed it just help me put a time out please so i wont have the JS error. Thank you
$('input:hidden').each(function(){
var name = $(this).attr('name');
if($("[name='"+name+"']").length >1){
if($(this).attr('type')!=='radio' && $(this).attr('type')!=='submit'){
$(this).remove();
}
}
});
One of the exemples i found : Bypassing IE's long-running script warning using setTimeout
You may want to add input to your jquery selector to filter out only input tags.
if($("input[name='"+name+"']").length >1){
Here's the same code optimised a bit without (yet) using setTimeout():
var $hidden = $('input:hidden'),
el;
for (var i = 0; i < $hidden.length; i++) {
el = $hidden[i];
if(el.type!=='radio' && el.type!=='submit'
&& $("[name='" + el.name + "']").length >1) {
$(el).remove();
}
}
Notice that now there is a maximum of three function calls per iteration, whereas the original code had up to ten function calls per iteration. There's no need for, say, $(this).attr('type') (two function calls) when you can just say this.type (no function calls).
Also, the .remove() only happens if three conditions are true, the two type tests and check for other elements of the same name. Do the type tests first, because they're quick, and only bother doing the slow check for other elements if the type part passes. (JS's && doesn't evaluate the right-hand operand if the left-hand one is falsy.)
Or with setTimeout():
var $hidden = $('input:hidden'),
i = 0,
el;
function doNext() {
if (i < $hidden.length) {
el = $hidden[i];
if(el.type!=='radio' && el.type!=='submit'
&& $("[name='" + el.name + "']").length >1) {
$(el).remove();
}
i++;
setTimeout(doNext, 0);
}
}
doNext();
You could improve either version by changing $("[name='" + el.name + "']") to specify a specific element type, e.g., if you are only doing inputs use $("input[name='" + el.name + "']"). Also you could limit by some container, e.g., if those inputs are all in a form or something.
It looks like the example you cited is exactly what you need. I think if you take your code and replace the while loop in the example (keep the if statement for checking the batch size), you're basically done. You just need the jQuery version of breaking out of a loop.
To risk stating the obvious; traversing through the DOM looking for matches to these CSS selectors is what's making your code slow. You can cut down the amount of work it's doing with a few simple tricks:
Are these fields inside a specific element? If so you can narrow the search by including that element in the selector.
e.g:
$('#container input:hidden').each(function(){
...
You can also narrow the number of fields that are checked for the name attribute
e.g:
if($("#container input[name='"+name+"']").length >1){
I'm also unclear why you're searching again with $("[name='"+name+"']").length >1once you've found the hidden element. You didn't explain that requirement. If you don't need that then you'll speed this up hugely by taking it out.
$('#container input:hidden').each(function(){
var name = $(this).attr('name');
if($(this).attr('type')!=='radio' && $(this).attr('type')!=='submit'){
$(this).remove();
}
});
If you do need it, and I'd be curious to know why, but the best approach might be to restructure the code so that it only checks the number of inputs for a given name once, and removes them all in one go.
Try this:
$("[type=hidden]").remove(); // at the place of each loop
It will take a short time to delete all hidden fields.
I hope it will help.
JSFiddle example

How do I concatenate a string with a variable?

So I am trying to make a string out of a string and a passed variable(which is a number).
How do I do that?
I have something like this:
function AddBorder(id){
document.getElementById('horseThumb_'+id).className='hand positionLeft'
}
So how do I get that 'horseThumb' and an id into one string?
I tried all the various options, I also googled and besides learning that I can insert a variable in string like this getElementById("horseThumb_{$id}") <-- (didn't work for me, I don't know why) I found nothing useful. So any help would be very appreciated.
Your code is correct. Perhaps your problem is that you are not passing an ID to the AddBorder function, or that an element with that ID does not exist. Or you might be running your function before the element in question is accessible through the browser's DOM.
Since ECMAScript 2015, you can also use template literals (aka template strings):
document.getElementById(`horseThumb_${id}`).className = "hand positionLeft";
To identify the first case or determine the cause of the second case, add these as the first lines inside the function:
alert('ID number: ' + id);
alert('Return value of gEBI: ' + document.getElementById('horseThumb_' + id));
That will open pop-up windows each time the function is called, with the value of id and the return value of document.getElementById. If you get undefined for the ID number pop-up, you are not passing an argument to the function. If the ID does not exist, you would get your (incorrect?) ID number in the first pop-up but get null in the second.
The third case would happen if your web page looks like this, trying to run AddBorder while the page is still loading:
<head>
<title>My Web Page</title>
<script>
function AddBorder(id) {
...
}
AddBorder(42); // Won't work; the page hasn't completely loaded yet!
</script>
</head>
To fix this, put all the code that uses AddBorder inside an onload event handler:
// Can only have one of these per page
window.onload = function() {
...
AddBorder(42);
...
}
// Or can have any number of these on a page
function doWhatever() {
...
AddBorder(42);
...
}
if(window.addEventListener) window.addEventListener('load', doWhatever, false);
else window.attachEvent('onload', doWhatever);
In javascript the "+" operator is used to add numbers or to concatenate strings.
if one of the operands is a string "+" concatenates, and if it is only numbers it adds them.
example:
1+2+3 == 6
"1"+2+3 == "123"
This can happen because java script allows white spaces sometimes if a string is concatenated with a number. try removing the spaces and create a string and then pass it into getElementById.
example:
var str = 'horseThumb_'+id;
str = str.replace(/^\s+|\s+$/g,"");
function AddBorder(id){
document.getElementById(str).className='hand positionLeft'
}
It's just like you did. And I'll give you a small tip for these kind of silly things: just use the browser url box to try js syntax. for example, write this: javascript:alert("test"+5) and you have your answer.
The problem in your code is probably that this element does not exist in your document... maybe it's inside a form or something. You can test this too by writing in the url: javascript:alert(document.horseThumb_5) to check where your mistake is.
Another way to do it simpler using jquery.
sample:
function add(product_id){
// the code to add the product
//updating the div, here I just change the text inside the div.
//You can do anything with jquery, like change style, border etc.
$("#added_"+product_id).html('the product was added to list');
}
Where product_id is the javascript var and$("#added_"+product_id) is a div id concatenated with product_id, the var from function add.
Best Regards!

Why won't innerHTML work for me?

This function uses jQuery to modify the contents of a DOM element. What am I doing wrong?
function updateScore() {
alert("Test score is: " + bucket.score);
$("#testScore").innerHTML = 'Current score is: + bucket.score';
}
The alert runs, but nothing else does. I have a <p> with the id testScore, but it doesn't change when I run the function. Why?
Thanks, Elliot Bonneville
Try .html() on a jQuery object. innerHTML is for DOM-Elements.
$("#testScore").html('Current score is: '+ bucket.score);
If, for some reason, you really want to use innerHTML, you can convert the jQuery Object back to its DOM variant, for example using [0] or .get(0). Call like this, then:
$("#testScore")[0].innerHTML ='Current score is: '+ bucket.score
But I don't see why you would want to do that - since you're already writing in jQuery, there's no need to fallback to DOM methods that have a perfectly fine jQuery equivalent.
function updateScore() {
alert("Test score is: " + bucket.score);
$("#testScore").text('Current score is: ' + bucket.score);
}
try
$("#testScore").innerHTML('Current score is: + bucket.score');
The jQuery objects do not support assignment to the attributes. (Its a Javascript limitation) You have to call the function with a parameter to set something.

Categories