Does the callback in setTimeout get executed right away?

How can I achieve a fade-in effect for an element that remains on the page for 7 seconds before fading out, with the ability to cancel it at any time? I have implemented the following functions. However, when I invoke

info_timeout.setup(ele, 'some msg here')
, the element fades in and out immediately.

Is there something missing in my implementation?

var info_timeout = {
show_info: function(){
    this.ele.html(this.msg).fadeIn('normal');
    this.id = setTimeout(this.hide_info(), 7000);
},
hide_info: function(){
    console.log(this.ele, this.id);
    this.ele.fadeOut('slow');
    delete this.id;
},
setup: function(ele, msg) {
    this.ele = ele;
    this.msg = msg;
    this.cancel();
    this.show_info();
},
cancel: function() {
    if(typeof this.timeoutID == "number") {
        clearTimeout(this.id);
        delete this.id;
    }
}

};

Thank you.

Answer №1

There are several issues to address.

When using hide_info, it is important to note that it is invoked immediately. Remember, parentheses are not just for grouping expressions but also for invoking function-objects!

In the case of:

this.id = setTimeout(this.hide_info(), 7000);

It can be misunderstood as:

var temp = this.hide_info()       // calling a function...wait, what?
this.id = setTimeout(temp, 7000)  // temp returns "undefined" here

Oops! That's incorrect. To avoid this mistake, remove the parentheses. By doing so, the actual function-object will be passed to setTimeout. (Yes, functions in JavaScript are treated as objects. The expression this.hide_info is evaluated first to become a function-object, and if followed by (...), it will trigger the function-object.)

this.id = setTimeout(this.hide_info, 7000)

However, this still poses an issue because within the timeout function (hide_info), this will refer to the wrong context. This can be resolved by implementing a closure. (Numerous valuable explanations on this topic exist on platforms like Stack Overflow; feel free to explore!)

var self = this
this.id = setTimeout(function () {
    // now inside hide_info, "this" refers to "self", which was originally "this" outside :)
    self.hide_info()
}, 7000) 

(Alternatively, consider using Function.bind from ECMAScript ed5 or a suitable library.)

Furthermore, it's worth noting that this.id does not equate to this.timeoutID and should be validated for correctness.

Simplicity is key. It's perfectly acceptable to pass undefined or zero to clearTimeout; the method will simply disregard such inputs.

cancel: function () {
    clearTimeout(this.id)  // though "id" may be a confusing naming choice :)
    this.id = undefined
}

Wishing you success in your coding endeavors.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Learning to monitor for incoming messages in a Discord channel from the ground up

I am eager to understand how to detect new messages exclusively using requests made to the Discord API. While I have mastered loading messages by fetching , I am struggling to grasp how to listen for incoming messages. It appears that this feature is not ...

After selecting a value in a form created with Rails 4.0, CoffeeScript fails to trigger the alert message

When working with a :quote resource, I want to trigger a function when the value of the first field (a collection_select) is changed. Additionally, my code includes fields_for :bikes, which represents a relationship where bikes has_many quotes. Below is t ...

Transforming the DOM using jQuery

I am looking to manipulate the DOM using jQuery. This is the initial source code: <td class="name"><a href="position_details.php?x=-109&amp;y=95">21</a> </td> <td class="name"><a href="position_details.php?x=-109& ...

Updating the status in Reactjs

I need help with updating the status of a selected student in my code. I am able to retrieve the ID and status of the clicked student, but I am unsure of how to implement the update functionality. export const UPDATESTATUS = gql` mutation UpdateStatus($sta ...

The implementation of pushing inside a foreach loop is not correctly adding elements to

I have encountered an issue with running a foreach loop and adding values to an array in my code. The first foreach loop works as expected, adding values properly to the array. However, the second foreach loop seems to be malfunctioning as none of its valu ...

Issue with Node.js Mongoose: Attempting to store a date in UTC Timezone, but it is being saved in the local time

I am relatively new to using nodejs and mongodb. I am encountering an issue with dates while using mongoose for mongodb - whenever I attempt to save a date into the database, it automatically gets converted to the local timezone, which is not the desired b ...

Guide on injecting javascript code containing php variables into a php page

I have successfully developed a PHP page and Javascript code that includes some PHP variables. The code is designed to insert PHP variables into the database using Javascript: <?php $id = "Kevin"; $user = "Calvin"; ?> <!-- include jquer ...

Android webview experienced a blank page after completion of Facebook share button

Whenever I open the webview and click on the Facebook share button, it works perfectly. However, after the share is completed, it leads me to a blank page. Sometimes, instead of a blank page, it actually shows the original page. But most of the time, it&a ...

Creating an embedded link to a website that adjusts to different screen sizes while also dynamically changing

I've been developing a personalized site builder that includes an iframe for previewing responsive websites. In order to make the site 'zoomed out' and not appear in mobile size, I'm utilizing CSS scale and transform origin as shown bel ...

AngularJS: Utilizing angular-filter for grouping by two columns

I may come across as a bit confusing, so please allow me to clarify. Note: An operational piece of code (POC) has been included with this post. I have an array of objects with 3 properties: name name team team_rank $scope.players = [ {name: & ...

Learn how to handle JSON requests in Node.js within a router script

Hello everyone, I've been struggling to retrieve the body of a request from Postman into my scripts. The body always comes up empty. Can anyone help me figure out the correct way to do this? I have set up the server in index.js and reading the reques ...

Retrieve the initial element from a JSON object to identify errors, without being dependent on its specific key name

Utilizing AngularJS, my JSON call can result in various errors. Currently, I am handling it like this: $scope.errors = object.data.form.ERRORS or $scope.errors = object.data.system.ERRORS However, in the future, 'form' or 'system' ...

Unable to obtain the selection from the dropdown menu

I am currently populating data from a JSON file into a dropdown list. The code snippet I am using for this task is shown below: $(function() { $('#productList').append($('<option/>').attr("value", key).text(data[k ...

What is the most effective way to utilize zoom with an Orthographic projection?

I'm attempting to utilize THREE.OrbitControls for zooming in an orthographic projection, but I'm not achieving the desired outcome. I believe it may be possible to adjust the viewSize that is multiplied by left, right, top, and bottom to achieve ...

Refresh client web pages with JSON data without using eval

I am currently working as a consultant on a web application that functions as a single page app. The main purpose of the app is to constantly fetch new json data in the background (approximately every minute) and then display it on the screen. Our clients ...

What is the best way to send the current element to a function that is bound to a click

Below is an example of some code: <table> <tr data-bind='template: { name: "GridColumnTable", foreach: columns }' ></tr> </table> <script type="text/html" id="GridColumnTable"> <td> ...

Incorporating an SVG with CSS styling from a stylesheet

After exploring various articles and questions on the topic, I am yet to find a definitive solution. I have an external file named icon.svg, and my objective is to utilize it across multiple HTML files with different fill colors and sizes for each instanc ...

Is it possible to trigger an event for only one connected client instead of broadcasting it to all clients using socket.io?

I am seeking a way to send an event to just one connected client, rather than broadcasting it to all clients using io.emit(). ...

Ways to conceal a div element depending on the selection made in an AngularJS dropdown menu

Is there a way to dynamically hide a div based on a selected dropdown option? Here is the code snippet I have come up with: <div> <p>Course Type</p> <div> <select name="student-type" id="student-type&q ...

Implementing es6 syntax for overloading a library class

In my project, I have various objects that extend other objects from a library. The library object extends the Object class of the library. Therefore, the architecture is as follows: // The library object class class Object { } // The library object1 c ...