How to effectively implement addEventListener() / attachEvent()?

Can anyone provide guidance on how to correctly use addEventListener and attachEvent?

window.onload = function (myFunc1) { /* do something */ }

function myFunc2() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc2, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc2);
}

 // ...

or

function myFunc1() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc1, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc1);
}

function myFunc2() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc2, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc2);
}

 // ...

Which approach is cross-browser secure or would it be better to utilize the following method:

function myFunc1(){ /* do something */ }
function myFunc2(){ /* do something */ }
// ...

function addOnloadEvent(fnc){
  if ( typeof window.addEventListener != "undefined" )
    window.addEventListener( "load", fnc, false );
  else if ( typeof window.attachEvent != "undefined" ) {
    window.attachEvent( "onload", fnc );
  }
  else {
    if ( window.onload != null ) {
      var oldOnload = window.onload;
      window.onload = function ( e ) {
        oldOnload( e );
        window[fnc]();
      };
    }
    else
      window.onload = fnc;
  }
}

addOnloadEvent(myFunc1);
addOnloadEvent(myFunc2);
// ...

Additionally: How should we modify the correct/preferred method if `myfunc2` specifically for IE7?

Answer №1

Both of these methods have a similar purpose, but they differ slightly in their syntax for the event parameter:

addEventListener (mdn reference):

Supported by major browsers like Firefox, Chrome, and Edge.

obj.addEventListener('click', callback, false);

function callback(){ /* do stuff */ }

Check out the events list for addEventListener.

attachEvent (msdn reference):

Specifically supported by IE 5-8*

obj.attachEvent('onclick', callback);

function callback(){ /* do stuff */ }

Refer to the events list for attachEvent.

Arguments

In both methods, the arguments are as follows:

  1. The event type.
  2. The function to call when the event is triggered.
  3. (Only for addEventListener) If true, indicates that the user wants to initiate capture.

Explanation

Both methods serve the same purpose of attaching an event to an element.
The key difference is that attachEvent is limited to older trident rendering engines (IE5-8*) while addEventListener is a W3 standard implemented in most other browsers (Firefox, Webkit, Opera, IE9+).

To ensure solid cross-browser event support with normalizations not provided by the Diaz solution, consider using a framework.

*IE9-10 support both methods for backward compatibility.

Credit to Luke Puplett for noting that attachEvent has been removed in IE11.

Minimal cross-browser implementation

Following Smitty's recommendation, you can utilize this Dustin Diaz addEvent implementation for a robust cross-browser solution without relying on frameworks:

function addEvent(obj, type, fn) {
  if (obj.addEventListener) {
    obj.addEventListener(type, fn, false);
  }
  else if (obj.attachEvent) {
    obj["e"+type+fn] = fn;
    obj[type+fn] = function() {obj["e"+type+fn](window.event);}
    obj.attachEvent("on"+type, obj[type+fn]);
  }
  else {
    obj["on"+type] = obj["e"+type+fn];
  }
}

addEvent( document, 'click', function (e) {
  console.log( 'document click' )
})

Answer №2

If you're still following this thread and haven't found the solution you need, take a look at:

I came across this elegant solution that works well for those of us who are limited in using frameworks.

function addEvent(obj, type, fn) {

    if (obj.addEventListener) {
        obj.addEventListener(type, fn, false);
        EventCache.add(obj, type, fn);
    } else if (obj.attachEvent) {
        obj["e" + type + fn] = fn;
        obj[type + fn] = function() {
            obj["e" + type + fn](window.event);
        }
       
        obj.attachEvent("on" + type, obj[type + fn]);
        
        EventCache.add(obj, type, fn);
    } else {
        obj["on" + type] = obj["e" + type + fn];
    }

}

var EventCache = function() {

    var listEvents = [];
    
    return {
        listEvents: listEvents,
        
        add: function(node, sEventName, fHandler) {
            listEvents.push(arguments);
        },
        
        flush: function() {
            var i, item;

            for (i = listEvents.length - 1; i >= 0; i = i - 1) {
                item = listEvents[i];
                
                if (item[0].removeEventListener) {
                    item[0].removeEventListener(item[1], item[2], item[3]);
                };

                if (item[1].substring(0, 2) != "on") {
                    item[1] = "on" + item[1];
                };

                if (item[0].detachEvent) {
                    item[0].detachEvent(item[1], item[2]);
                };

                item[0][item[1]] = null;
            };
        }
    };
}();

addEvent(window, 'unload', EventCache.flush);

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

Unable to load more than one controller in a single partial view using AngularJS

I am having trouble loading a second controller to populate a select in my view. Despite my efforts, it just won't cooperate. This is the code snippet I'm using: app.js (function() { 'use strict'; angular .module('app.lazylo ...

Pass the identification of a particular card to the following route in order to retrieve data using that specific id in nextjs

[]Hello! I am currently working on fetching data from an API and using the map function to display the retrieved data. My goal is to extract more details about a specific piece of data by taking its ID and passing it to another page. The issue arises in my ...

Tips for making a website display in landscape mode rather than portrait orientation

As a newcomer to web design, I am curious if it is feasible to create a website that automatically rotates to landscape view when accessed on a mobile device. The current project I am working on is fluid in design, so this feature would greatly enhance t ...

Ways to prompt a specific text value to generate varied responses

Whenever I try to input the letter "h", I expect a specific value in return but for some reason, it's not working as intended. Despite my best efforts to troubleshoot the issue, I have been unsuccessful in finding a solution. It's frustrating bec ...

Transform the blob, which includes an image, into just an image and insert it into the <img> tag

When adding a record to a MySQL database with XAMPP and the "mysql2" package (^3.6.2), I encountered an issue. export const addPage = async (req,res) => { try { if(req.session.user !== undefined) { ...

"Enhance your website with the magic of jQuery magnific-popup

Is there a way to add an additional button to the jquery magnific-popup component that can close the dialog box? I am currently utilizing this component to insert descriptions for photos, so I need a submit button that will successfully add the descriptio ...

What is the reason for the value of an object's key becoming undefined when it is set within a loop?

I've always wondered why setting a certain object's key as its own value in a loop results in undefined. Take this code block, for example: var text = 'this is my example text', obj = {}, words = text.split(' '); for (i = ...

How can I generate a list of JavaScript files to be included in a template for both production and development environments using Grunt?

I need a way to organize a list of JavaScript files in one central location, either within gruntfile.js or an external JSON file, and then dynamically implement it into a template for both development and production environments. List of JavaScript files: ...

Improved AJAX Dependency

A few days ago, a question was posted with messy code and other issues due to my lack of experience (please forgive the form handling as well). However, I have made some improvements and added context. The main problem now lies in the second AJAX call. Ch ...

The ng-click function ceases to trigger after the $location dependency is included in the controller

I need some help with running a ng-click function from my controller. The strange thing is, when I don't use the $location dependency, the ng-click function works fine. But as soon as I add $location to the controller, the ng-click function stops work ...

Accessing the camera or photo library in React Native does not require any permissions

In my current project, I am developing an app that requires users to upload images from their photo library or camera. To access the camera functionality, I am utilizing the react-native-image-picker library without integrating react-native-permissions. ...

The ng-isolate-scope is not properly connected to the specified templateUrl

I am encountering difficulties when trying to implement isolated scope with templateUrl. Here is my directive test: beforeEach(ngModule('app.directives')); var scope, compile beforeEach(inject(function($rootScope, $compile){ scope = $ro ...

After subscribing, my Angular template fails to refresh

Currently, I am facing an issue with my Angular 17 project where the data fetched from the API is not updating the template. This means that despite receiving the data, I am unable to display it on the page. The code snippet below shows the service compon ...

Update the text using JavaScript to modify the price range dropdown when the user clicks away

Dropdown functionality is working when selecting a price, but updating the price in the text box manually does not trigger an update. How can you implement an onblur change event for manual entry of prices? JSFiddle function nFormatter(num, digits) { ...

How to assign a value to an array within a form in Angular 8

I'm facing an issue with my Angular 8 edit form that utilizes a form array. When I navigate to the page, the form array is not populated with values as expected. Can anyone help me identify and solve this problem? ngOnInit(): void { // Fetc ...

Best Practices for Safely Storing the JWT Client Credentials Grant

Currently, I am working on a NodeJS Express Application that connects to an Auth Server using client credentials grant. After receiving the token from the Auth Server, I use it to access data from an API. I am seeking advice on the most effective way to s ...

What is the best way to display JavaScript in a view in ASP.NET MVC 3?

Good day Everyone, I am currently facing an issue with a javascript variable in my view. This is what I have been trying to do... var skinData = null; and then, when the document is ready.... $.ajax({ type: 'POST', ...

Tips for converting JSON information on a website and inserting it into a designated division?

I've recently delved into front-end development, searching for solutions and hints without much success. I'm currently in the process of building my first website, specifically a "find recipes" website. Lacking knowledge of API calls, I created a ...

Having trouble retrieving the value of a textarea within a jQuery UI dialog box

I attempted to place a textarea within a dialog box, with the intention of retrieving the value of that textarea when the "ok" button is clicked. However, I am encountering difficulties in retrieving the value. What could possibly be causing this issue? ...

The data stored in LocalStorage disappears when the page is refreshed

I'm facing an issue with the getItem method in my localStorage within my React Form. I have added an onChange attribute: <div className = 'InputForm' onChange={save_data}> I have found the setItem function to save the data. Here is ...