Javascript element giving text from before it was updated - javascript

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.

Related

How to have a variable increase over time (JS)

i was wondering how to make a variable go up over time, ive tried to do this -->
var i = 1;
var c = document.getElementById("click");
function workers() {
if (click >= workers*50000)) {
click += -(workers*50000)
click += i++
c.innerHTML = click;
}
}
but it hasnt worked, how do i fix this?
you could do this
let i = 0;
// instead of 2000 insert the frequency of the wanted update (in milliseconds)
const incrementInterval = setInterval(() => i++, 2000)
// when you want it to stop it
clearInterval(incrementInterval)
anyway, i don't really understand how the code supplied with the question has anything to do with it
You have an element and a variable 'click', which tells me you're really not wanting to grow over time per se, but rather grow with every click.
Another difficulty is finding out what you're trying to do with multiplying by 50000. I am assuming you are trying to reset the count after 50000.
One big thing you're missing is the actual association of the click event to your 'click' HTML element. Below, I'm using addEventListener to do that. From there, I'm resetting the counter to '1' if 'i' goes above '5' (I use 5 just to show the reset in a reasonable number of clicks). Then I take the value of 'i' and put it into the innerHTML label of the element that triggered the event.
var i = 1;
document
.getElementById("click")
.addEventListener('click', function(e) {
if (i > 5)
i = 1;
e.target.innerHTML = `click: ${i++}`;
})
<div id='click'>click<div>
Define your question better. What is your goal? What has your code achieved? What result are you getting and how is it different than your expectations? What is 'i' meant to be used for? How does it interact with the function? Why are you multiplying it with 50000? Is workers a separate variable that's globally defined and not shown? Communication is an important skill in this field, and comments are often helpful tools to document your code for others to understand.
I think an alternative answer could be formatted in this way:
let i = 0;
function increment(){
i++;
document.querySelector('h3').textContent = i
}
document.querySelector('button').addEventListener('click',increment)
<button>Click Me</button>
<h3>0</h3>

"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>

Why will my button not advance to the next question?

I am a new developer and this is my first question. I am trying to make a multiple choice quiz for an assignment. I am stuck on making the NEXT button move to the next question. I think the rest of the JS file is correct...
Right now the clickNext doesn't do anything, so I need to do the following
check if the time expired (line 39)
did the user answer the question in the allotted time (line 40)
if no, try again and the clock will start over (line 60-70)
if yes, then store the answer selected - I think this part is tripping me up and I am not sure what to use here
check if the selected answer is correct (line 50-57)
if the answer is correct, move to the next question (line 52-53)
if the answer is wrong, alert "Please try again" (line 55-56)
I have tried to return the answer, the addEventListener, putting the checkAnswer function in the clickNext function
var indexQuestion = 0; // Current index of question we are on
var timer = 0; // A clock that goes up by 1 every second
var timeLastSubmit = 0; // the time we last submitted an answer
var timeExpired = false; // Did time expire for current question?
// number of seconds to wait for each question
var WAIT_TIME = 30;
// all questions to be used on the website
var QUESTIONS = [
{
"question":"Which city is the capital of Ontario?",
"choices":["New York","Toronto","Berlin","Kuala Lumpur"],
"answer":1
},
{
"question":"Which city is the capital of Canada?",
"choices":["New York","Toronto","Ottawa","Vancouver"],
"answer":2
},
{
"question":"Which continent does the south pole reside?",
"choices":["Africa","Antarctica","Asia","Australia","Europe","North America","South America"],
"answer":1
},
];
function loadApplication() {
loadQuestion(indexQuestion); // load the first question into the web page
// update the timer every second and check if question has been answered yet
setInterval(function(){
timer++;
checkExpirationTime();
},1000);
}
function clickNext() {
// make sure that the user has answered the question before the time has expired
timeLastSubmit = timer;
checkExpirationTime();
// Get the answer from drop down
var selectedIndexAnswer = getElementById('choices');
return selectedIndexAnswer;
// Get the anwer from the array
var answer = QUESTIONS[indexQuestion].choices[i];
checkAnswer();
};
function checkAnswer(){
// Compare answer. Only if correct, do you move onto next question - if(answer == QUESTIONS[indexQuestion].answer)
if(selectedIndexAnswer == answer) {
nextQuestion();
}
else {
alert('Please try again.');
}
}
function checkExpirationTime() {
// check the time, once the clock has reached 30 seconds do not move to the next quesiton
if(timer - timeLastSubmit < WAIT_TIME && !timeExpired){
document.getElementById("seconds").innerHTML = WAIT_TIME;
}
else{
timeExpired = true;
alert('Please try again.');
clearInterval(timeExpired);
}
}
function nextQuestion() {
// advance to the next question, until the there are no more questions
if(indexQuestion<QUESTIONS.length-1)
{
indexQuestion++;
loadQuestion(indexQuestion);
}
}
function loadQuestion(indexQuestion){
// grab the question
document.getElementById("question").textContent = QUESTIONS[indexQuestion].question;
// build the html string for select menu
var choices = "";
var i=0;
//loop through the choices
while(i<QUESTIONS[indexQuestion].choices.length){
// create a string of <option>answer</option><option>answer</option><option>answer</option>... and load it into the choices variable
choices += "<option>" + QUESTIONS[indexQuestion].choices[i] +"</option>";
i++;
}
document.getElementById("choices").innerHTML = choices;
}
// When the DOM is ready, run the function loadApplication();
document.addEventListener("DOMContentLoaded",loadApplication);
Right now the program does not advance to the next question, but it just stays on the first question.
To answer your first question
I am stuck on making the NEXT button move to the next question
For this you need to add click event listener to next button.
document.getElementById("btnNext").addEventListener("click",clickNext)
And the next part
I think the rest of the JS file is correct.
Almost.. You need to make a few corrections here and there.
I made some edits to the pen and is available here.
https://codepen.io/nithinthampi/pen/Yzzqqae
As, you are a learner, I would suggest not to copy it. Even the codepen I shared is not complete, but should help you to move on.
Going through your pens, here are the following issues I found with your code:
Misuse of return statements. You added a return statement in the second line of your function causing the rest of it to be completely ignored.
function clickNext() {
// make sure that the user has answered the question before the time has expired
timeLastSubmit = timer;
checkExpirationTime();
// Get the answer from drop down
var selectedIndexAnswer = getElementById('choices');
Here --> return selectedIndexAnswer;
// Get the anwer from the array
var answer = QUESTIONS[indexQuestion].choices[i];
checkAnswer();
}
onclick not added to your "Next" button, neither a addEventListener in your script was. As a result, clicking the "Next" button had no effect on your app, at all.
<button id="btnNext">Next</button>
Scoping problems. In JavaScript, when you define a variable within a scope, that variable can never be accessed from outside that very scope. Meaning defining a variable inside a function (like in your case) will not make it available in another completely separate function (unless you pass it as a parameter in some way). I'd recommend researching a bit more about JavaScript scopes to get a better of idea of how it works.
All 3 issues have been fixed in a new pen I've created for you to take a look at: https://codepen.io/MMortaga/pen/PooNNYE?editors=1010
However you might need to play a bit more with your timer, so see if you can fix it :P
Take the time to review all the changes I've mentioned and if you still face any issues just comment below, I'd be glad to help.

Error, word is not displaying one letter at a time

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);

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