Ways to invoke foo specifically when either a click event or a focus event is triggered

In my custom directive, I am binding focus and click events to an element:

app.directive('mydirective', function () {
  return {
    link: function ($scope, $element, $attrs) {
      $element.bind('click focus', function (e) {
        foo(e);
      });
    }
  };
});

I want the function foo to be called only once when either the focus or click event is triggered. However, on clicking the element, both the focus and click events fire, causing foo to be called twice. Is there a way to prevent foo from being called the second time?

Edit: I realize now that mixing hover with click and focus was not a good idea. Thank you all for your input.

Answer №1

To prevent multiple events from firing, you can debounce the events so that only the first event triggers the function.

$element.bind('click focus', function(e) {
    if ( !$(this).data('fired') ) foo(e);

    $(this).data('fired', true);

    setTimeout(function(self) {
        $(self).data('fired', false);
    }, 200, this);

});

Check out the JSFIDDLE demo here

Answer №2

Here is an alternative implementation of the debounce function:

link: function($scope, $element, $attrs) {

    var executeOnce = (function() {
        var timer;
        return function(event, callback) {
            clearTimeout(timer);
            timer = setTimeout(function() {
                callback.call(self, event);
            }.bind(this), 200); 
         };
    })();

    $element.bind('click focus mouseover', function(event) {
        executeOnce.call(this, event, bar);
    });
}

Check out the demo: http://plnkr.co/edit/AbcdefgUcHijkLmnoPqr?p=preview

Answer №3

  1. If you want to ensure that the function foo() is called both on click and focus events, it is recommended to use the focus event alone. This is because the click event may not fire independently but will also trigger the element to be focused.

  2. In cases where the element is not an input, opting for the click event alone instead of focus can be a suitable solution.

  3. If you are experiencing the issue of the event being fired three times, it could be due to either the click event firing twice and the focus event once, or vice versa. To address this, you can incorporate e.preventDefault(); in both your click and focus event handlers.

    app.directive('mydirective', function () {
      return {
        link: function ($scope, $element, $attrs) {
          $element.bind('click', function (e) {
            e.preventDefault();
            foo(e);
          });
        }
      };
    });
    

    Implementing this technique ensures that the same event callback is not executed multiple times.

  4. Alternatively, a straightforward approach would be to determine whether the element is an input and then bind the appropriate event handler - focus for input elements, and click for other types of elements.

    app.directive('mydirective', function () {
      return {
        link: function ($scope, $element, $attrs) {
    
            if(element is input)
            {    
                  $element.bind('focus', function (e) {
                    e.preventDefault();
                    foo(e);
                  });
            }
            else
            {       
                  $element.bind('click', function (e) {
                    e.preventDefault();
                    foo(e);
                  });
            }
        }
      };
    });
    

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

Could not locate the provider: $stateProvider

It's puzzling to me why this code is not recognizing the $stateProvider. Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to: Error: [$injector:unpr] Unknown provider: $stateProvider This is a simple example of a module: ( ...

Dividing a pair of CSS stylesheets on a single HTML page

Currently, I am working on a HTML page that includes multiple javascripts and css files in the header section. <link href="@Url.Content("~/Content/css/main.css")" rel="stylesheet" type="text/css" /> In order to make the website mobile-friendly, I s ...

Trigger the select dropdown when a key is clicked

I am currently working on a project in react where I am utilizing the Select component from material. When I open the dropdown and press a key on my keyboard, the option starting with that key gets automatically selected. This behavior is also observed in ...

Passing methods from child to parent components in Vue2 looped componentsHere is a

Currently, I am iterating through the root component, which contains a child component within it. <root-select v-for="offer in offers" > <child-options v-for="item in options" > </child-options> </root-select> However, when ...

Ways to showcase the object on the console

How can I display the object function in the console? When I try, nothing is displayed. Can you please help me figure out what went wrong? I know I must have made a mistake somewhere, as this is my first question on Stack Overflow. import React, ...

Can you create reusable components in Wordpress that are encapsulated?

In my quest to explore innovative approaches to Wordpress theme development, I have stumbled upon a variety of options such as the "Roots Sage" starter theme, the "Themosis Framework," and "Flynt." While these solutions address intriguing problems, they do ...

Tic-Tac-Toe: The square's value stays unchangeable

Currently, I am working on creating a tic-tac-toe game using pure vanilla Javascript, so I am aiming to keep it as simple as possible. I have run into an issue and need some guidance. The main requirement is that once a square has been clicked and filled ...

Conceal a card once verified within a bootstrap modal upon successful AJAX completion

On my delete page, there are multiple posts with a delete button. When the delete button is clicked, a Bootstrap modal opens asking for confirmation "Are you sure you want to delete this post? YES : NO" If the YES button is clicked, the .click(function(e) ...

Storing HTML values in a Meteor database is a common practice for web

Within my meteor project, I have a paragraph in HTML containing a JSON value as follows: {"Active Template Id":"6467","Shirt Brand":"levis","ProductId":"EB301","Brand":"on","Material":"cotton","Price":"1800","Combo Id":"S90"} I am looking to store this v ...

The Checkbox handler in Material-UI component fails to update the state - Version 5.0

Hey everyone, I'm facing an issue with my "Checkbox" component in React. After clicking on it, the state doesn't update to 'true' as expected. The checkbox works visually in the DOM but the state remains 'false'. Can someone p ...

The MVC 5 view is unable to display an HTML image when adding it within an appended div

Currently, I am working with ASP.net MVC5 at a novice level. I'm faced with the challenge of creating a div that displays an image using a JavaScript function. Here is the code snippet I have: function showLoadingImage() { $('#submit_Em ...

Guide to changing an image on a canvas with KineticJS

I am currently working on developing a canvas that will display a hotel floor view. I have images stored in a database which I am drawing onto the canvas using x and y coordinates from the database as reference points. However, I want to add touch events t ...

Using a constructor function in a for loop

Currently, I am learning how to build a Blackjack game with Javascript on Codecademy. I'm struggling to figure out what code to write inside the for-loop. The task at hand is to create a "score" method within the Hand constructor. This method should ...

Transforming an array in JavaScript into a JSON object

I'm currently working on creating a loop in JavaScript or jQuery to generate a new JSON object from an array. The goal is to convert an input JavaScript array into a desired format for the output. Here's the input array: INPUT: [ { ...

Is it possible for the 'error' attribute to be deemed invalid or inappropriate within ajax?

I am encountering an issue with my mobile cordova application. When attempting to log in, I am facing the following error: Error: JavaScript runtime error - Object doesn't support property or method 'error' The error is being traced back t ...

What is the best way to save a jQuery or JavaScript variable into a JSON file?

Is there a way to save a jquery variable in a json file? I have the following: var image='/test/test.png'; I am obtaining this path through file upload: <input type="file" name="imageurl" value="imagefile"></input> Therefore, I ne ...

Navigating to a specific route upon the arrival of a push notification (Angular, Ionic, ngcordova)

Imagine this situation. I am working with an ionic / angular app and implementing the ngcordova plugin for push notifications. Picture this: a push notification comes in while the app is running in the background. The user checks the notification in the ...

Angularjs failing to navigate to different components

My attempt to route through this using the href led me to: "#/Loginc", "#/registers" (function() { var app = angular.module("UniqueFSPA", ["ngRoute"]); var routes=[ { templateUrl: "/uniqueviews/registers.html", controller: "HomeController" }, ...

Using Javascript to extract information from the div element

Within my HTML code, I have a total of 4 <div> tags and a corresponding <a> tag for each of these <div> tags. Inside each div tag, there are 2 span tags and an additional a tag. Upon clicking the a tag, I aim to extract the product name ...

When I utilize the redux connect function, the class information in my IDE (PhpStorm/WebStorm) seems to disappear

When I use the connect function from redux, it seems to hinder my IDE (PhpStorm) from "Find Usages" on my classes. This is likely because connect returns any, causing the type information from the imported SomeClass file to be lost. export default connect ...