Connecting events across various browsers

In a function, I had to add an event to an element called newElement. To cater for different browsers like IE and Firefox, I checked the condition based on the attachEvent property (only works in IE).

if ( typeof(newElement.attachEvent) != "undefined" )
{               
    newElement.attachEvent("onclick", deleteRow) ;  
    newElement.attachEvent("onclick", customDeleteScript) ;
}else
{   
    newElement.addEventListener("click", deleteRow, false) ;    
    newElement.addEventListener("click", customDeleteScript, false) ;               
} 

The original requirement was for deleteRow to run before customDeleteScript. This setup worked correctly in Firefox and Chrome but not in IE where customDeleteScript executed first. In order to fix this issue, I had to rearrange the event additions as shown below:

if ( typeof(newElement.attachEvent) != "undefined" )
{               
    newElement.attachEvent("onclick", customDeleteScript) ;
    newElement.attachEvent("onclick", deleteRow) ;  
}else
{   
    newElement.addEventListener("click", deleteRow, false) ;    
    newElement.addEventListener("click", customDeleteScript, false) ;               
} 

The question arises whether this behavior is specific to IE or if it's just a random occurrence with IE always?

EDIT: What happens if my function has parameters like this and others, and I'm unsure which function requires which parameters.

Answer №1

To ensure the order of operations is maintained, it's recommended not to use separate event handlers. Instead, you can call both functions in the desired sequence from a single event handler as shown below:

function delete() {
    deleteRow();
    customDeleteScript();
}

if ( typeof(newElement.attachEvent) != "undefined" )
{               
    newElement.attachEvent("onclick", delete) ;  
}else
{   
    newElement.addEventListener("click", delete, false) ;    
} 

If you want to create a reusable event handler function, you can follow this approach:

function addEvent(elem, event, fn) {
    if (elem.addEventListener) {
        elem.addEventListener(event, fn, false);
    } else {
        elem.attachEvent("on" + event, function() {
            // set the this pointer same as addEventListener when fn is called
            return(fn.apply(elem, arguments));   
        });
    }
}

It's advisable to check for addEventListener first so that your code utilizes the standard method if it's available, even in browsers like IE9 where both methods exist.

You can implement your code using the addEvent function like so:

addEvent(newElement, 'click', function() {
    deleteRow();
    customDeleteScript();
});

Answer №2

To ensure that the customDeleteScript() function is executed after deleteRow(), simply include a return true statement at the end of the deleteRow() function:

function deleteRow()
{
    // other code
    return true;
}

Then, you can call customDeleteScript() like this:

if(deleteRow()) customDeleteScript();

You can follow jfriend00's suggestion for event registration as it allows for more dynamic handling. Registering two separate event handlers as described in the question may not be the most suitable approach.

Update: Research shows that in Internet Explorer, registered event handlers are fired "last in first out (in reverse order)" for elements with multiple events. You can test this behavior by using this fiddle. For instance:

function addEventHandler(to_element,event,handler)
{
    if (to_element.addEventListener) to_element.addEventListener(event,handler,false);
    else if (to_element.attachEvent) to_element.attachEvent("on"+event,handler);
    else return false;
}

function function1()
{
    alert("first alert");
}

function function2()
{
    alert("second alert");
}

var obj=document.getElementById('obj');
addEventHandler(obj,"click",function1);
addEventHandler(obj,"click",function2);​

In Chrome, function1 will be triggered first followed by function2, while in IE, function2 will be triggered first and then function1. Therefore, it would be best to register only one event and call both functions within the same handler:

function deleteRow()
{
    // other code here
    return true;
}
function customDeleteScript()
{
    // code here
}
addEventHandler(obj,"click",myHandler);
function myHandler()
{
    if(deleteRow()) customDeleteScript();
}

Answer №3

To tackle this issue, combine both handlers into one function and designate that singular function as the handler:

function handleAction() {
    deleteRow();
    customDeleteScript();
}

if (typeof(newElement.attachEvent) != "undefined") {               
    newElement.attachEvent("onclick", handleAction);  
} else {   
    newElement.addEventListener("click", handleAction, false);               
} 

Answer №4

The sequence of events linked with attachEvent to the same element and type is unpredictable, as opposed to addEventListener, which follows the order in which they are declared. If order matters, consider invoking the second function from the first or merging them into one.

Another contrast is that attachEvent can attach the same handler multiple times upon each call, allowing a single function to be executed repeatedly. In contrast, addEventListener only assigns it once regardless of how many times it is called with the same parameters.

Given that IE9+ does support addEventListener, rearrange your assignments accordingly and handle multiple assignments (there is no harm in attempting to remove a non-existent handler):

if (newElement.addEventListener){
    newElement.addEventListener("click", deleteRow, false);
    newElement.addEventListener("click", customDeleteScript, false);
}
else if(newElement.attachEvent){
    newElement.detachEvent("onclick", customDeleteScript);
    newElement.detachEvent("onclick", deleteRow);
    newElement.attachEvent("onclick", customDeleteScript);
    newElement.attachEvent("onclick", deleteRow);
}

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 access a custom filter in ng-repeat using AngularJS

I'm working on creating a filter to sort through the items displayed in a table. Specifically, I want to filter out items based on a certain property value that may change depending on user input. I have attempted the following approach and it seems t ...

switch between showing and hiding dynamic table rows

As I dynamically add rows to a table, each row can either be a parent row or a child row. My goal is to toggle the visibility of child rows when the parent row is clicked. if (response != null && response != "") { ...

Using val() on a checkbox will give you an element, not a string literal

How can I retrieve only the literal values of all checked checkboxes without any additional data? My current approach is: $('input:checked').map(function() { return $(this).val(); }) The result that I am getting looks like this: e.fn.init[1]0 ...

Is there a way to retrieve the intersection point (Vector3) of the intersectObjects?

I need assistance in finding the point where a ray cast from 'child' intersects with a mesh (child2) using Raycaster: var raycaster = new THREE.Raycaster(); var meshList = []; meshList.push(child2); for (var i = 0; i < child.geometry.vertices ...

Is there a way to automatically scroll vertically to a specific line in HTML?

Trying to explain this is a bit tricky. I am looking to add an element to the HTML that prompts the browser to scroll vertically to its location automatically when loaded, similar to an anchor. So: | visible area | | content html | | content html | ...

Keycloak does not support using the updateToken() function within an asynchronous function

In our development of a Spring application with React/Redux frontend, we faced an issue with Keycloak authentication service. The problem arose when the access token expired and caused unexpected behavior in our restMiddleware setup. Here is a simplified v ...

Submitting a form using an anchor tag in Angular 8: A step-by-step guide

I have a question about how to submit form data using hidden input fields when a user clicks on an <a> tag. <form action="/submit/form/link"> <input type="hidden" [attr.value]="orderNumber.id" /> <input type="hidden" [attr.value]= ...

Delving into the World of CSS

I have been working on changing the background image using this JavaScript code, but I am not sure what to reference in the CSS file. Despite reading through everything, my screen still remains blank. $(function() { var body = $('body'); var bac ...

Setting up and launching a fresh JS project

Hey there, I recently began a course on Udemy to dive into the world of JavaScript and React. However, after installing Node.js and NPM, I encountered an issue when trying to use npm start. The error message reads "ENOENT: no such file or directory." I&apo ...

The 'exhaustive-deps' warning constantly insists on requiring the complete 'props' object instead of accepting individual 'props' methods as dependencies

This particular issue is regarding the eslint-plugin-react-hooks. While working in CodeSanbox with a React Sandbox, I noticed that I can use individual properties of the props object as dependencies for the useEffect hook: For instance, consider Example ...

The functionality of two-way data binding seems to be failing when it comes to interacting with Knock

I am currently working on a piece of code that consists of two main functions. When 'Add more' is clicked, a new value is added to the observable array and a new text box is displayed on the UI. Upon clicking Save, the values in the text boxes ...

Tips for utilizing jQuery to identify an image that is being hovered on?

Concept My goal is to create an effect where a user hovers over an image and a transparent overlay div appears on top of it. This overlay div starts with a height of 0px and should increase to half of the image height upon hover. The hover functionality ...

Troubleshooting: Angular Custom Elements malfunction on Firefox, Microsoft Edge, and Internet Explorer

Experimented with the Angular Elements Demo After downloading, installing, and building the demo locally. Implemented the following code: <!doctype html> <html lang="en> <head> <meta charset="utf-8> <title>Angular Eleme ...

Navigating using passing data in ReactJs

The following data contains information about people: const people = [ { img: 11, name: "Ahmed", job: "developer", }, { img: 13, name: "Kazim", job: "Engineer", }, ...

Broken links detected in the Full Page Navigation menu on a one-page website

The hyperlinks on this particular page seem to be malfunctioning despite the fact that the li.a tags are correctly targeting specific section IDs. Markup: <header> <a href="#0" class="nav_icon"><i></i></a> </header> ...

"An error occurred stating that currDateEnd.setHours is not a valid function

I am attempting to transform my date into ISO format and adjust the hours to 23. Below is my code: var currDateEnd = $('#calendar').fullCalendar('getView').start; console.log(currDateEnd); currDateEnd.toDate().toISOString(); console.lo ...

What is the best way to handle multiple promises when loading a state in Angular?

When loading the /home state, I need to retrieve all users from the database in order to customize the home controller and view based on the logged-in user. Currently, in the :resolve section of the state configuration, I am fetching all 'posts' ...

Updating data scope in AngularJS using $http request not functioning properly

I am facing an issue where the $scope.user_free_status is not updating when I set a user free, but works perfectly fine when I unset the parameter. It's strange that I need to reload the page in one case and not the other. The data fetched is stored i ...

Creating a dynamic multi-choice dropdown list with Django and Vue.js

I have been attempting to implement the Vue.js multiselect component from the following link: However, I am encountering an issue where instead of the expected multiselect dropdown, the output is not as desired and looks like this: https://i.sstatic.net/ ...

What is the method for stopping a slide in this script?

Welcome everyone! Check out this piece of code I have: <script type="text/javascript" > $(function(){ var time = 10000;//milliseconds var index = 0; var container = $("#containerr"); var child ...