Error, word is not displaying one letter at a time - javascript

I am trying to make sure that when a word is shown, it will be shown letter for letter. However, this is not working. And I am keep getting an error.
I have already looked on StackOverflow to see if there are other people that have the same problem as I do. There are people with the same goal, yet, I cannot find anyone with the same problem. The programming language that I am using to reach this goal is JavaScript.
The code:
<script type="text/javascript"><![CDATA[
document.documentElement.addEventListener('load',function(evt){
alert('OK');
},false);
var text = 'dog';
var curr = "";
var Write = function write(){
var elem = document.getElementById('cls-3');
elem.textContent += text.charAt(curr);
curr++;
if (curr < text.length)
window.setTimeout(write, 20);
};
Write();
]]></script>
The error:
Logo_infomaatje.svg?version=3613:51 Uncaught TypeError: Cannot read
property 'textContent' of null
at write (Logo_infomaatje.svg?version=3613:51)
at Logo_infomaatje.svg?version=3613:56
With this code, I am expecting that the word "dog" will be spelled out a letter for letter. This is unfortunately not happening. I hope that I have provided enough information.
Greetings,
Parsa237

As Stefan said in the comment, i think that when the line var elem = document.getElementById('cls-3'); is executed, there's no cls-3 element in your html.
Maybe this element is never created, or maybe your javascript code is executed before this element creation.
According to your code, Write() is called immediately instead of waiting for the DOM loaded event. You should try this:
document.documentElement.addEventListener('load',function(evt){
alert('OK');
Write();
},false);

Related

Javascript element giving text from before it was updated

I've just been trying to make some code to test out tampermonkey stuff on simple maths questions when I came across this error. it would work for the first question, get the question, solve it, enter the answer. The element then changes to a new question however when I use .innerHTML or .textContent it always gives the original question.
Here is my code which shows this:
console.log(document.getElementById('currgamename'))
console.log(document.getElementById('currgamename').textContent)
I get this output:
<span id="currgamename">12-7</span>
6-3 //The first question that appears
Full code:
var delayInMilliseconds = 1000; //1 second
var x = 0
setTimeout(function() {
var handler = setInterval(function() {
document.getElementById('playPadding').childNodes[1].click()
var equation = document.getElementById('currgamename').textContent
var actual = equation.split('-')
var answer = (parseInt(actual[0]) - parseInt(actual[1])).toString()
document.getElementById('currgamename').innerHTML = 'hello'
console.log(document.getElementById('currgamename'))
console.log(document.getElementById('currgamename').textContent)
document.getElementById('gameinput').value = answer
document.getElementById('nextButton').click()
x++;
if (x >= 5) {
clearInterval(handler);
}
}, 1000);
}, delayInMilliseconds);
I have absolutely no clue why it gives the updated element but not the updated text so I could really use some clarification here thanks!
In the console:
>document.querySelector("#currgamename")
<-<span id="currgamename">12-7</span>
>document.querySelector("#currgamename").textContent = "hello"
<-"hello"
------And the HTML on the screen changed to show the "hello" instead of "12-7"------
>document.querySelector("#currgamename").innerHTML = "bye"
<-"bye"
>document.querySelector("#currgamename").innerText
<"bye"
So it works as long as your querySelector is aimed at the correct element it should work
I genuinely cannot believe my stupidity, I've been at this for 4 hours now and the error was that I had document.getElementById('playPadding').childNodes[1].click() inside the setinterval. It was pressing the start button everytime i wanted to answer a new question so it was just replacing it with the old one FML.

"document.getElementsByClassName" found elements but can not access

I have a realy hard problem that I couldn't find any solution in Internet
I used document.getElementsByClassName to access one HTML Element by It's class, my element is filterRow of dxDataGrid:
var filterRowElement = document.getElementsByClassName("dx-datagrid-filter-row");
console.log(filterRowElement);
console.log(filterRowElement.length);
My Problem is: The first console.log return HTMLCollection with length = 1 but the second return 0 (I tried to get length to access filterRowElement[0]).
I've tried console.log(filterRowElement[0]) and got undefined too
This is screen shoot:
I don't know why, it is the first time I got this problem
Please give me some advise. Thank you!
THANK YOU, I THINK MY PROBLEM IS DXGRID FILTERROW ELEMENT IS CONSECUTIVELY CHANGE SO I CAN'T ACCESS OLD ELEMENT
UPDATE
I don't know why but Using Jquery save Me (may be not alway true)
setTimeout(function () {
var getfilterRowElement = $(".dx-datagrid-filter-row");
console.log(getfilterRowElement[0]);
}, 3000);
Result:
Thank you so much
Updated: One reason why you might got a 0 for the second line, and a 1 for first line is: you print out filterRowElement.length, and it is true at that time, it was 0. When your event cycle is over, your framework (React, Angular, etc) updated the page (either after your actions or before your actions in the next event cycle). Now console.log prints out the whole structure and when you look at it in the debugger, now it is 1.
In order to solve this problem, I had to do something like this before:
setTimeout(() => {
doSomething();
}, 0);
So now you are waiting for the next event cycle so that your page is "constructed" or "updated".
If it is a static page, I was able to get 1 for both cases and able to access it:
Do you mean
console.log(filterRowElement);
gave you an object with length being 1, and then
console.log(filterRowElement.length);
gave you 0?
The following works:
arr = document.getElementsByClassName("foo-bar");
console.log(arr);
console.log(arr.length);
arr[0].innerHTML = "hello world";
arr[0].style.background = "orange";
arr[0].style.display = "inline-block";
arr[0].style.padding = "1.2em";
arr[0].style.borderRadius = "6px";
<div class="foo-bar"></div>
getElementsByClassName is live... is your page being changed meanwhile? Try document.querySelectorAll(".foo-bar") instead:
arr = document.querySelectorAll(".foo-bar");
console.log(arr);
console.log(arr.length);
arr[0].innerHTML = "hello world";
arr[0].style.background = "orange";
arr[0].style.display = "inline-block";
arr[0].style.padding = "1.2em";
arr[0].style.borderRadius = "6px";
<div class="foo-bar"></div>

Game loop appears to be breaking at the end of iterating through array. Uncaught TypeError

Morning all,
Definitely a novice question here, this is my first real JS project - so apologies in advance for the clunky code.
The following functions are being used to show the light sequence for a "simon" game. The code seems to work fine initially, as I've tested multiple lengths of array, however on exiting the loop I get the following error:
Uncaught TypeError: Cannot read property 'setAttribute' of null
at show (script.js:95)
at showLights (script.js:83)
at script.js:88
I've looked around a lot for fixes to this error, and the majority of feedback is that it's related to the DOM and a wrapper will fix. I've found that a wrapper doesn't resolve. Similarly, I can't see that it's an issue with the CSS or HTML as the functions work ok until exit.
The looping functions are copied below:
// iterates through simon.array then allows button press
function showLights(x) {
if (x >= simon.array.length) {
clearTimeout(timer);
show(x);
allowPress();
} else {
show(x);
var timer = setTimeout(function(){
showLights(x+1);
},500);
}
}
// adds then removes flash class to light pads.
function show(x){
var display = document.getElementById("light" + simon.array[x]);
display.setAttribute("class", "flasher");
setTimeout(function(){
display.setAttribute("class", "game-box");
},500);
}
Apologies in advance for any errors or faux pas in posting this. I strongly suspect that I'll be kicking myself when this is fixed.
Kind Regards
Andy
The issue is related to you checking the length of an array, then trying to use an element of that array that does not exist. You are possibly also trying to set an attribute to an element that does not exist.
At a guess, this is the real cause of the issue:
if (x >= simon.array.length) {
clearTimeout(timer);
show(x);
allowPress();
Simply removing show(x) should help. The reason is you are checking for the length of simon.array, then later in function show(x) you make a request for simon.array[x], but that is not going to find anything, as x is greater than the length of that array.
The other possible issue is in the following chunk, but could be solved a number of ways. One way is to check x before passing. Another is making sure the element (display) is not null before setting the attribute.
// adds then removes flash class to light pads.
function show(x){
var display = document.getElementById("light" + simon.array[x]);
display.setAttribute("class", "flasher");
setTimeout(function(){
display.setAttribute("class", "game-box");
},500);
}
My suggestion would be as follows:
// adds then removes flash class to light pads.
function show(x){
var display = document.getElementById("light" + simon.array[x]);
if (display) {
display.setAttribute("class", "flasher");
setTimeout(function(){
display.setAttribute("class", "game-box");
},500);
}
}
You may want to check out classList as well as an alternative to setAttribute.
Something else to consider instead of using setTimeout would be to use a CSS animation.

My JS function for my wordgame keeps throwing script error in Firefox ONLY

Well, there was me thinking my JS wordgame was functioning beautifully ( with a little help from Ryan J - thanks!). I was about to begin adding styling when I realised that I hadn't tested in Firefox at all - my bad, I got the dreaded script timeout error. So, after hours of testing and playing around I still can't understand what's wrong. I'm being told by the error that it's the following function that's causing the problem:
function guessLetter( letter, shown, answer ) {
var checkIndex = 0;
checkIndex = answer.indexOf(letter);
while (checkIndex >= 0) {
shown = alterAt(checkIndex, letter, shown);
checkIndex = answer.indexOf(letter, checkIndex + 1);
}
return shown;
}
alterAt is previously defined, totally puzzled - any tips most welcomed.
Thanks
Terry
EDT: Oops! Here's a link - completely unstyled but you get the idea.
http://theelectricunderground.net/eltel/currentaffairs/wordpress/?p=449
I have confirmed it... this is because letter is an empty string. You should add something like this to your code (in the keypress event):
if (tempChar === "") return;
before the line
tempString = guessLetter(tempChar, gameShownAnswer, gameAnswer );
This is because sometimes the keyup event occurs but there is nothing in the input box.
For example, what happens when you press the control key?
The index of an empty string never be -1, so the loop will never break.
For example, "petrol".indexOf("", 100) returns 6.

Javascript/jQuery function yields undefined in <IE8

A short while back I asked a question here about how I could calculate when a heading was longer than one line within a given container, and subsequently wrap each of these lines in a <span>:
Use Javascript/jQuery to determine where a heading breaks to the next line?
I chose an answer which worked great for me, at least until I checked in IE7 and IE6, in which all the headings handled by this script rendered as
"undefinedundefinedundefinedundefinedundefinedundefined[...]"
on the page. As I'm not really a JavaScript person (that's why I asked such a question in the first place), it's really tough for me to figure out where the problem is. I assumed an undefined variable or something, but I just can't seem to grasp it.
Can anyone help?
I'll repeat the code here, but please refer to the link above for context:
$(function(){
$h = $('.fixed').find('h3');
$h.each(function(i,e){
var txt = $(e).text();
$th = $('<h3 />').prependTo($(e).parent());
var lh = $(e).text('X').height();
$(e).text('');
while (txt.length > 0) {
$th.text($th.text() + txt[0]);
txt = txt.slice(1);
if (($th.height() > lh) || (txt.length <= 0)) {
var shc = $th.text().split(' ');
var ph = shc.slice(0,-1).join(' ')+' ';
if (txt.length <= 0) { ph += shc.pop(); }
$('<span />').text(ph).appendTo($(e));
$th.text(shc.pop());
}
}
$th.remove();
})
});
You need to change
$th.text($th.text() + txt[0]);
to be
$th.text($th.text() + txt.charAt(0));
IE<8 doesn't accept string positions through array indexes ;)
The styling doesn't work, but that'll be a CSS issue which I couldn't fix before leaving. But everything is wrapped in spans :)
Nothing jumps out at me. But, since you mentioned in your comment to your question that you see "undefined" in Firebug, I would start there. Even though those browsers are failing gracefully, the fact that you see undefined there is your first hint to finding the problem for the harder-to-diagnose IE6/7. I would use Firebug and either breakpoint in the function, or use some console.log() calls to document what the values that you are working with are each step of the way. Once you start seeing undefined... you have likely found your problem.

Categories

Resources