Button click event image hiding is delayed

In summary, the function does not hide the image until after the sleep function completes. This is because the sleep function delays updating the browser display.
  • #1
Bob Walance
Insights Author
Gold Member
81
55
TL;DR Summary
The style.visibility = 'hidden' image attribute is not taking effect until end of sleep function
My webpage project has a button labeled 'Harmonics' with a mouse-click event. I want an image to be hidden as soon as the button is clicked, however this doesn't happen.

Here's a snippet of the html. It doesn't matter what order the two Javascript functions are called. The 'hidden' attribute for the image does not take effect until the sleep function completes.

gwd.Harmonics = function(event) {
document.getElementsByClassName('gwd-img-17a0')[0].style.visibility = 'hidden'; // hide the image
sleep(2000); // delay for 2000ms

Can anyone tell me if this can be fixed so that the image is hidden as soon as the button is clicked?
 
Technology news on Phys.org
  • #3
PeterDonis said:
Why is the sleep function there at all?
I'm just using a sleep function here to simply demonstrate the issue. The real project is playing a tone and I need to know when the tone has ended. There is an event-driven mechanism for this but it is unreliable so I'm using a simple date/time-based timer in order to know when to start the next tone.
 
  • #4
Bob Walance said:
I'm just using a sleep function here to simply demonstrate the issue.
Unfortunately, the issue you are running up against, at least as I understand how the Javascript engine works, is simple: your function is an event handler and Javascript doesn't update the browser display to reflect any changes the event handler makes until after the handler returns. So you can't put any kind of time delay tracking mechanism in an event handler because it delays updating the browser display.

Bob Walance said:
There is an event-driven mechanism for this but it is unreliable
How so?
 
  • #5
PeterDonis said:
Unfortunately, the issue you are running up against, at least as I understand how the Javascript engine works, is simple: your function is an event handler and Javascript doesn't update the browser display to reflect any changes the event handler makes until after the handler returns. So you can't put any kind of time delay tracking mechanism in an event handler because it delays updating the browser display.
PeterDonis said:
How so?
1 - I was afraid of that. That's really how it appears to be behaving. Darn.
2 - I think that the audioContext tone generation 'onend' event issue is related to "Javascript doesn't update the browser display..." operation that you pointed out.

My app's purpose is to demonstrate the difference, musically, between equal-temperament tuning and simple harmonics of an instrument note (nature). The part of the app that plays one tone or chord works perfectly. When I need a sequence of tones (e.g. in a musical scale) then I run into these issues.

I have a complete application written and working in Python, but I can't distribute the Python code here. That's why I'm attempting to get it to work in a web browser.
 
  • #6
Bob Walance said:
2 - I think that the audioContext tone generation 'onend' event issue is related to "Javascript doesn't update the browser display..." operation that you pointed out.
There is no AudioContext onend event. Perhaps you are thinking of the AudioScheduledSourceNode ended event: https://developer.mozilla.org/en-US/docs/Web/API/AudioScheduledSourceNode/ended_event

Bob Walance said:
My app's purpose is to demonstrate the difference, musically, between equal-temperament tuning and simple harmonics of an instrument note (nature). The part of the app that plays one tone or chord works perfectly. When I need a sequence of tones (e.g. in a musical scale) then I run into these issues.
Perhaps you might be better off using the tone.js module I showed you on another thread.

Bob Walance said:
I have a complete application written and working in Python, but I can't distribute the Python code here. That's why I'm attempting to get it to work in a web browser.
Programming for the web is very different from programming in Python, you need to completely change your mindset to write asynchronous, event driven code rather than the blocking code you are used to.
 
  • #8
pbuk said:
There is no AudioContext onend event. Perhaps you are thinking of the AudioScheduledSourceNode ended event: https://developer.mozilla.org/en-US/docs/Web/API/AudioScheduledSourceNode/
Perhaps you might be better off using the tone.js module I showed you on another thread.

Programming for the web is very different from programming in Python, you need to completely change your mindset to write asynchronous, event driven code rather than the blocking code you are used to.

pbuk said:
There is no AudioContext onend event. Perhaps you are thinking of the AudioScheduledSourceNode ended event: https://developer.mozilla.org/en-US/docs/Web/API/AudioScheduledSourceNode/ended_eventPerhaps you might be better off using the tone.js module I showed you on another thread.Programming for the web is very different from programming in Python, you need to completely change your mindset to write asynchronous, event driven code rather than the blocking code you are used to.

I did look at tone.js but I don't think it'll do what I want. For example, I need to play two major chords:
A + C# + E
and
440Hz + 550Hz + 660Hz

They both sound close but the latter is much sweeter sounding. The beat frequency produced between the C# and the fifth harmonic of 110Hz is very obvious when it's juxtaposed with the natural major third interval.
 
  • #9
jedishrfu said:
Maybe this will work:

https://www.codegrepper.com/code-ex...+to+reload+page+on+button+click+in+javascript

It's likely an ugly solution, but from it, you might find a better way.

Thanks. I'm aware of this and am utilizing it to make repeated musical scales more reliable (I'm not sure where the real issue is there).

I should have been a software engineer. Their life is SO much easier overall. They can just sit at their computers all day sipping their Daiquiris while us EEs have to go into the lab and inhale lead fumes.
 
  • #10
Sadly, you have a romanticized view of software engineers. Yes, we can code but a lot of time is spent tracking down your own or other people's misguided coding mistakes, and some can be downright impossible to find in a timely fashion.

So revel in the fact that you are a talented engineer learning the ropes of programming.
 
  • Like
Likes Bob Walance
  • #11
There is actually no sleep function in javascript. And if you keep javascript busy in a different fashion, all other activity is on hold as @PeterDonis already pointed out. Moreover, if you keep javascript busy for too long (a couple of seconds), the browser will complain that a script is causing trouble and ask if you want to kill it.

If you do want to sleep, then the relevant function is setTimeout, which takes a callback that will be called after a time. During this time all other activity resumes and the browser will display anything that was changed.

If you want to wait for it and continue what you were doing, then you can use:
Code:
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
gwd.Harmonics = async function(event) {
  document.getElementsByClassName('gwd-img-17a0')[0].style.visibility = 'hidden'; // hide the image
  await sleep(2000); // delay for 2000ms
  // Other processing
}
Note that the sleep is implemented using setTimeout, and all other activity will resume during this time so your element will immediately become invisible.
 
Last edited:
  • Love
Likes Bob Walance
  • #12
I like Serena said:
If you want to wait for it and continue what you were doing, then you can use:
Code:
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
gwd.Harmonics = async function(event) {
  document.getElementsByClassName('gwd-img-17a0')[0].style.visibility = 'hidden'; // hide the image
  await sleep(2000); // delay for 2000ms
  // Other processing
}
Note that the sleep is implemented using setTimeout, and all other activity will resume during this time so your element will immediately become invisible.
YES! Your solution works perfectly. I was just about to give up and try a different approach, but you completely solved my problem.

Thank you very much, liker of Serena.
 
  • Like
Likes I like Serena

FAQ: Button click event image hiding is delayed

Why is the image hiding delayed after clicking the button?

The delay in image hiding after clicking the button could be due to the time taken for the event handler to trigger the hiding function. It could also be caused by other operations or functions running in the background, which take priority over the hiding function.

Can the delay be reduced or eliminated?

Yes, the delay can be reduced or eliminated by optimizing the code and ensuring that the event handler and hiding function are executed efficiently. Additionally, minimizing the number of operations or functions running in the background can also help reduce the delay.

Is the delay affected by the size or type of the image?

The size or type of the image may affect the delay, as larger or more complex images may take longer to hide compared to smaller or simpler images. However, the delay is mainly dependent on the efficiency of the code and the operations running in the background.

Are there any alternative ways to hide the image without delay?

Yes, there are alternative ways to hide the image without delay, such as using CSS to hide the image or using JavaScript to manipulate the CSS display property. These methods may be faster and more efficient compared to using a button click event.

How can I troubleshoot and fix the delay in image hiding?

To troubleshoot and fix the delay in image hiding, you can check the code for any inefficiencies or conflicts with other functions or operations. You can also use debugging tools to identify the cause of the delay and make necessary adjustments to optimize the code. Additionally, simplifying the hiding function or using alternative methods may also help reduce the delay.

Similar threads

Replies
3
Views
2K
Replies
2
Views
4K
Back
Top