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

Monitor a user's activity and restrict the use of multiple windows or tabs using a combination of PHP and

I am looking to create a system that restricts visitors to view only one webpage at a time, allowing only one browser window or tab to be open. To achieve this, I have utilized a session variable named "is_viewing". When set to true, access to additional ...

Issue with jQuery not being able to retrieve the data from my CSS property

this is my custom style code: table.table tr td{ padding:30px; border-left: double 1px white; border-bottom: double 1px white; cursor:cell; } and below is the jQuery script I am using: $(document).ready(function () { ...

What are the steps to restrict the scope of a <style> declaration in HTML?

Currently, I am in the process of creating a user interface for a webmail. Whenever I receive an email, I extract its content and place it within a <div> element for display purposes. However, one challenge that I am facing is that each email contain ...

Add integer to an array of strings

Currently, I am utilizing an autocomplete feature and aiming to save the IDs of the selected users. My goal is to store these IDs in a string array, ensuring that all values are unique with no duplicates. I have attempted to push and convert the values u ...

What is the best method for sending a document to a web API using Ajax, without relying on HTML user controls or forms?

I have successfully utilized the FormData api to upload documents asynchronously to a web api whenever there is a UI present for file uploading. However, I now face a situation where I need to upload a document based on a file path without relying on user ...

Which is the better option: utilizing the submit event of the form, or incorporating ajax functionality?

Forms are an essential part of my website design, and I often find myself contemplating whether it's better to submit a form using a standard submit button or utilizing Ajax. Typically, I opt for Ajax to prevent the dreaded issue of form re-submission ...

Mongoose is unable to update arrays, so it will simply create a new array

Having trouble updating my collection without any errors. Can someone lend a hand? I've been at this for 3 hours now. const product_id = req.body.cartItems.product_id; const item = cart.cartItems.find(c => c.product_id == product_id); i ...

Changing color of entire SVG image: a step-by-step guide

Check out this SVG image I found: https://jsfiddle.net/hey0qvgk/3/ <?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <svg version="1.1" width="90" height="9 ...

Enhance your Morris.js charts by incorporating detailed notes and annotations

Is there a way to include annotations in my morris.js charts? I couldn't find any information about this on their official website. I specifically need to add notes to certain dates. ...

Queries with MongoDB RegEx fail to return any matches if the search string contains parentheses

When trying to implement case-insensitivity using regex, it seems to work well for plain strings. However, if special characters like parenthesis are involved in the search query for the name, the database returns no results. For example, a search for "Pu ...

Ways to customize the appearance of an iframe's content from a separate domain

I am facing a challenge with my widget and multiple websites. The widget is hosted on one domain, but the websites use an iframe to display it. Unfortunately, because of the Same Origin Policy, I cannot style the content of the iframe from the parent websi ...

The only numbers that can be typed using Typescript are odd numbers

I am looking for a way to create a type in Typescript that can check if a value is an odd number. I have searched for solutions, but all I find are hardcoded options like odds: 1 | 3 | 5 | 7 | 9. Is there a dynamic approach to achieve this using only Types ...

Clicking our way back through the loop

Looking to display a name when each item is clicked. I've assigned an ID to each element, but it seems like I'm overlooking something. In the current code, I'm thinking there should be a variable involved, but I'm uncertain: $(document ...

The instance does not have a definition for the property or method "foo" that was referenced during rendering

[Vue warn]: Property or method "modelInfo" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. Whenever I ...

I need guidance on how to successfully upload an image to Firebase storage with the Firebase Admin SDK

While working with Next.js, I encountered an issue when trying to upload an image to Firebase storage. Despite my efforts, I encountered just one error along the way. Initialization of Firebase Admin SDK // firebase.js import * as admin from "firebas ...

Anticipate that the typescript tsc will generate an error, yet no error was encountered

While working in the IDE to edit the TypeScript code, an issue was noticed in checkApp.ts with the following warning: Argument type { someWrongParams: any } is not assignable to parameter type AddAppToListParams. Surprisingly, when running tsc, no error ...

What could be causing my router UI in angular.js to malfunction?

Having an issue with routing not functioning as intended, here is the relevant code: $urlRouterProvider. otherwise('/list'); $stateProvider. state('home', { abstract: true, views: { 'header': { templateUrl: &apos ...

What is the safest way to convert a local file path to a file:// URL in Node.js?

In my node.js application, I am faced with the task of converting local file paths into file:// urls. After some research, I came across the File URI scheme on Wikipedia and I believe that there must be a solution out there or perhaps even an npm module t ...

Styling a Pie or Doughnut Chart with CSS

I am working on creating a doughnut chart with rounded segments using Recharts, and I want it to end up looking similar to this: Although I have come close to achieving the desired result, I am encountering some issues: Firstly, the first segment is over ...

The jQuery extension for XDomainRequest in the $.ajax function called onprogress is

Summary: I am trying to make this compatible with this: Detailed Explanation: My goal is to develop a jQuery extension that introduces a progress method to the $.ajax object and works seamlessly with IE8 & IE9's XDomainRequest object. Currently, I ...