Creating a delayed hover effect in AngularJS that only triggers if the user stays in place for the specified amount of time

Objectives:

  • Trigger a popover after hovering over a tag for 2 seconds
  • Close any open popovers when leaving a tag
  • No display should occur if a tag is left before 2 seconds

Main Issue: http://plnkr.co/edit/PDcLQNudx53Dag49FyCw?p=preview

Failed Attempted Solution: http://plnkr.co/edit/39FGMocKB5GtQWnI1TFw?p=preview

The goal is to have a delayed popover div show up after hovering over a tag div for 2 seconds.

In the provided plnkr example, a setTimeout function with a delay of 1.5 seconds is utilized to achieve the desired effect.

However, an issue arises when quickly mousing over multiple tags in succession, causing all the setTimeout functions to trigger and resulting in multiple stuck popovers being displayed.

$scope.showTagDetails = function(t) {

function showDetails() {
    t.showDetails = true;
}

$timeout(showDetails, 1500);
}

$scope.leaveTag = function(t) {
    t.showDetails = false;
}

The objective is to prevent this issue, ensuring that no action takes place if the user swiftly scrolls over tags. A popover should only appear if the user lingers on a tag for a couple of seconds.


Suggested Resolution:

A unique function is required for each item, but implementation is currently halted:

HTML Markup:

<li ng-repeat="t in tags">
  <div class="tag"
       ng-mouseover="showTagDetails(t)"
       ng-mouseleave="leaveTag(t)"
       ng-click="sendTag(t)">{{t.name}}</div>
  <tag-details tag="t"></tag-details>
</li>

Controller Logic:

var hoverTimer;

function callHoverTimer() {
  console.log('callHoverTimer');
  setTimeout(function() {
      console.log('true');
      return true;
  }, 2000);
}

$scope.showTagDetails = function(t) {

// function showDetails() {
//   t.showDetails = true;
// }

t.showDetails = callHoverTimer();
console.log(t.showDetails);

setTimeout(function() {
    console.log(t.showDetails);
}, 2000);

// $timeout(showDetails, 1500);
}

$scope.leaveTag = function(t) {
    t.showDetails = false;
}

Included is the faulty production code snippet as well: The existing functionality works once, displaying tagHover after hovering and staying on a tag for 2 seconds, but fails upon subsequent interactions:

var hoverTimer;

function callHoverTimer(ticker, tag) {
    hoverTimer = setTimeout(function() {
        TagDetailsFactory.saveTagDetails(ticker, tag);
    }, 2000);
};

function hoverTag(tag) {
    var thisTicker = '';
    thisTicker = vs.ticker;

    callHoverTimer(thisTicker, tag);
};

function leaveTag(tag) {
    tagsHover = ScopeFactory.getScope('tagsHover');
    tagsHover.leavingTag(tag);
    clearTimeout(hoverTimer);
    callHoverTimer = function(){};  // <- I can 'break' the function here, but then it's broken forever :(
};

Answer №1

A simple solution can be achieved with the use of CSS styling.

ng-class

and

.tag-details {
  opacity:0;
  transition: opacity 0.5s linear;
  transition-delay:0s;
}

.tag-details.open{
  opacity:1;
  transition-delay:2s;
}

Example Link

Answer №2

Ensuring the proper storage and clearing of timeouts is crucial for effective code execution.

Check out this corrected code snippet.

$scope.hoverTimeout = null;

$scope.showTagDetails = function(t) {
  $scope.hoverTimeout = $timeout(function() { 
    t.showDetails = true; 
  }, 1500);
}

$scope.leaveTag = function(t) {
  $timeout.cancel($scope.hoverTimeout);
  t.showDetails = false;
}

If you opt for setTimeout over $timeout, remember to include $scope.$apply() to ensure Angular acknowledges any modifications made.

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

How to set up Jest in your JavaScript project using npm

I have been attempting to install jest using npm, both locally and globally, but it fails to install. My npm version is 7.5.2 and my node version is 12.22.5. I am using ubuntu. I have tried the following commands: npm i -D jest npm i -g jest npm i jest ...

Attempting to craft a multi-filter feature using AngularJS that will allow for the precise filtering of JSON data based on both month and year identifiers

I have integrated AngularJS into the RoR framework and am working on creating a multi-filter for the "ng-repeat" function to filter JSON data based on "month_id" and "year_id". Here is the current code: JSON: [ { "date":"October 4, ...

Struggling to verify and output all three conditions in Javascript

I need to modify a method that evaluates a variable called con as either true or false, and retrieves a device tag for each device. However, I am only able to retrieve the tag for the first device, even when the 2nd and 3rd conditions are true. How can I ...

Using Javascript, populate an array with Enum variable values

Hey there! I've got this code that creates an array from an enum variable in JavaScript, but it's looking a bit old and clunky. I'm curious if any JavaScript or jQuery experts out there have a cleaner (best practice) approach for achieving ...

Transitioning to Firebase Authentication

I made the decision to transition away from firebase authentication. To accomplish this, I exported all firebase users along with their email addresses, hashed passwords, salt keys, and other necessary information. Next, I transferred them to a database a ...

How can you selectively export a single function from a JavaScript file?

Within my project, I have two separate modules - one written in ts and the other in js. There is a utility within the js module that needs to be accessed by the ts module. The utility service.js looks like this: module.exports = { helloFriends: functi ...

Is there a way to retrieve the present value of a dropdown menu once an ajax call is successful?

Currently, I am facing an issue where I am unable to retrieve the selected value from a dropdown menu. The logged value is always the first option in the dropdown menu, even though I have set it to a different value. Can someone help me identify what I may ...

AngularJS scope variables refer to the data objects that are

Having an issue regarding variable scope in a Cordova program. Here is the code snippet: angular.module('starter.services', []) .factory('myFactory', function ($http) { var myVar = "HELLO"; alert(myVar); //HELLO -> S ...

Issue with Vue Leaflet causing map to not display

Below is the code that I have been working on, but all I see is a blank white page without any errors in the console. My goal is to render a map with markers. I am new to Vue and would appreciate your help in getting this to work. I have looked at some tut ...

Converting JSON data into an array of a particular type in Angular

My current challenge involves converting JSON data into an array of Recipe objects. Here is the response retrieved from the API: { "criteria": { "requirePictures": true, "q": null, "allowedIngredient": null, "excluded ...

What is the process for integrating an AngularJS component as a header in our index.html file?

Within my project, I have a header component that is comprised of its own HTML and JavaScript files. How can I effectively integrate this component into the main index.html of my application? ...

Mongoose model middleware post encounters a type error being thrown

I need to remove all 'Shifts' associated with an 'Event', but I keep encountering this error in VSCode: No matching overload found. The last attempt resulted in the following error: Argument of type '"remove"' is n ...

The challenge in displaying data from the backend using ajax in Vue.js 2.0 is hindering its visibility on the view

Currently, I am utilizing vue.js version 2.0, and the demo provided below is fully functional. <div class="container" id="app"> <ol> <li v-for="(todo,index) in todos"> {{ index }} {{ todo.text }} </li&g ...

CSS modified after opening a modal dialog that has loaded external HTML content

Within my ASP.NET MVC project, I am utilizing a tab wizard. On one of the tabs, I trigger a modal dialog by loading HTML content from an external API. However, once I close the wizard and navigate to the next tab, the table style (specifically border color ...

Tips for utilizing a nested Map in a React component using the provided dataset

There is data being retrieved from an API [ { title: "Lesson 1", topics: [ "Topic 1", "Topic 2", "Topic 3" ] }, { title: "Lesson 2", topics: ...

Is it possible to merge various jQuery setTimeout functions together?

I am currently using the following jQuery code for a specific task: setTimeout(function() { $("#ToDo1").removeClass("fa-spin fa-spinner"); $("#ToDo1").addClass("fa-check-square"); $("li:first").html("<i class='fa-li fa fa-check-square& ...

How come my h1 heading gets obstructed by the input box when the slideUp function is triggered

On my wikisearch page, I have a title and input box positioned around the middle of the page. When I click on the button, the title slides up along with the input box. However, the input box ends up covering the title completely. I'm trying to figure ...

You may encounter an error in Next.js stating: "Invalid element type: expected a string or class/function but received undefined."

I'm attempting to render a React element in the root/components folder, but I am encountering the following error: Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: unde ...

How can I transfer data from a C# code to a JavaScript file in asp.net?

I am faced with the task of transferring values from a C# class to a JavaScript file. To achieve this, I have generated a string in C# which contains the values of the list as follows: count = 0; JString = "["; for(i=0; i<x; i++) { JString += "{Sou ...

using the ng-repeat directive to display the first line only once

I am working with a mongodb collection that has the following parameters: { "_id": ObjectId("59c265235e21f8a8b7d75b23"), "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7004071f02031e190019301212135e131f5e051b">[em ...