2

I have this simple scenario where I am first binding javascript event listeners like so:

(function () {

/*Loading widget initialization code on window load*/
if (window.addEventListener) {// W3C standard
    window.addEventListener('load', initWidget, false);
} else if (window.attachEvent) {// Microsoft
    window.attachEvent('onload', initWidget);
}

})();

Please don't mind the initWidget as it is defined and works I just didn't put the code here since it was not needed.

So these events work fine, but when I add some jquery event handlers in there, the jquery events don't work. I add the jQuery events in $.ready() like so :

$().ready(function() {
$("#header").mouseover(function() {
    $("#header").css("background-color", "red");
}).mouseout(function() {
    $("#header").css("background-color", "transparent");
});
})

The jQuery mouseover and mouseout don't work unless I remove the window.addEventListener code block. Somehow js events are causing conflicts with jQuery and there is nothing in console.

I have also put up a fiddle here : https://jsfiddle.net/kzmvaysq/ replicating the exact problem. I need a way so that event listeners don't conflict with jQuery.

UPDATE

I traced to the main problem area and that seems to be trying to change the innerHTML of body tag in initWidget. If you see the fiddle now : https://jsfiddle.net/kzmvaysq/4/ it might help you better understand the problem.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
xmaestro
  • 1,084
  • 2
  • 16
  • 44
  • https://jsfiddle.net/arunpjohny/7wj2zk4L/1/ - fiddle is fine – Arun P Johny Jun 25 '15 at 04:51
  • @ArunPJohny Please see update to the post. – xmaestro Jun 25 '15 at 05:09
  • 2
    jQuery's event model requires it to add properties to DOM elements (which is one reason that some will not use it). Using `+=` with the *innerHTML* property probably requires the entire document body to be serialised then reparsed, trashing jQuery's DOM properties (and listeners added by *addEventListener*). – RobG Jun 25 '15 at 05:13

3 Answers3

1

The problem is document.getElementsByTagName("body")[0].innerHTML += mainButtons; which replaces the current dom structure with a new one, which will result in loosing all the events/data attached to each element by jQuery.

A simple solution is to append a new div element, instead of using innerHTML to add the new content

function initWidget() {
    var div = document.createElement('div');
    div.innerHTML = 'Somehtml';
    document.getElementsByTagName("body")[0].appendChild(div);
}

Demo: Fiddle

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
0

I cannot actually name a reason of it.
However, I would recommend you switching all of your events to jQuery to prevent conflicts.

You can attach the same event this way:

 $(window).load(initWidget);

It will also decrease the amount of code because jQuery applies events correctly for you.

Here is the JS Fiddle Demo based on your one.

Update: Why do you think that it conflicts at all?

Here is an another JSFiddle and it's working for me.

Update 2:

It is a known problem. If you change JS element properties and use jQuery events, it causes some problems. Read more here.

You need to choose one of this options:

  1. Assign events AFTER you have changed your innerHTML. Now it happens before it because $(document).ready() is being fired before $(window).load().

For example, place your #header events to initWidget after editing.

  1. Use jQuery.append() function (as for me, that is the best solution).

For example, this way:

function initWidget() 
{
    $("body").append("<div>Somehtml</div>");
}
  1. Use event delegation.

Look at this code:

$(document).ready(function() {
    $(document).on('mouseover', '#header', function() {
        $("#header").css("background-color", "red");
    });
    $(document).on('mouseout', '#header', function() {
        $("#header").css("background-color", "transparent");
    });
});

Here is the [JS Fiddle Demo][5].
Community
  • 1
  • 1
Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101
0

I don't think there is any conflict.

When I added initWidget() function it started working.

Here is the fiddle- https://jsfiddle.net/51sxLe7f/

Updated fiddle - https://jsfiddle.net/pg40wp43/2/

Rahul G Nair
  • 1,366
  • 10
  • 11