2

Demo: jsfiddle

var $item = $('.item');
var $img = $item.find('img');

var handler = function(event) {
  console.log('fired');
  $img.remove(); // remove child
};

var handlerRestore = function() {
  $item.append($img);
};

/// double fired event on chrome, safari, firefox
$('.item').mouseenter(handler);
$('.item').mouseleave(handlerRestore);

// one fired event on chrome, but double fired on firefox and safari
//$('.item')[0].onmouseenter = handler;
//$('.item')[0].onmouseleave = handlerRestore;
.item {
  background: #EFEFEF;
  display: inline;
  float: left;
  height: 300px;
  margin: 0 10px 80px 0;
  position: relative;
  width: 300px;
  transition: opacity 0.6s ease;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

.item img {
  margin: auto;
  max-height: 300px;
  max-width: 300px;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="item">
  <img src="http://img.ifcdn.com/images/237b9b19a8cc0ea78a3b32b567423a4cd0acf77fb19b8c5a485325e2252a7b7a_1.jpg" />
</div>

Questions:

  1. Why event fires twice?
  2. Why native-event fires once in Chrome, but jquery-event fires twice in Chrome?
  3. How it fix?

Firefox and Safari fired twice native-event also so jquery-event. I think it is wrong.

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
Alexpts
  • 21
  • 4
  • possible duplicate of [mouseenter event called twice even after stopPropagation](http://stackoverflow.com/questions/6888590/mouseenter-event-called-twice-even-after-stoppropagation) – jazZRo Feb 05 '15 at 12:34
  • If you output the `event.target` when the event fires you'll see the first event is for the div and the second is for the img. If you specified ".item img" for your event selector it will only fire once. – Lee Taylor Jun 26 '22 at 19:51

2 Answers2

0

You can solve this by delegating the event to the image:

$('.item').on('mouseenter', 'img', handler);

Updated fiddle

Another way to get around the problem is to attach the event only once the first time and every time handleRestore() is called.

var handlerRestore = function(){
    $item.one('mouseenter', handler);
    console.log('restored');
    $item.append($img);
};

$item.one('mouseenter', handler);

Fiddle 2

jazZRo
  • 1,598
  • 1
  • 14
  • 18
  • **Our example differ**. I listen mouseenter on '.item'. You listen mouseenter on 'img'. I use delegate in real code. It is simple example.**Our example differ**. I listen mouseenter on '.item'. You listen mouseenter on 'img'. I use delegate in real code. It is simple example. – Alexpts Feb 05 '15 at 13:34
  • It fires twice when quickly hovering over the div to the img because the event is attached to the div and is propagated to the img . Thats why I think this question is a duplicate. – jazZRo Feb 05 '15 at 14:02
  • I don’t know why certain browsers beahve this way. But I added another solution to get around this. – jazZRo Feb 05 '15 at 14:02
  • Event target is div and event propagated up on DOM from div to document . Event bubbling not pass through img. http://jsfiddle.net/alexpts/4res6aey/12/ – Alexpts Feb 05 '15 at 14:51
  • I can use detach event or one, but it is not elegant. I would like to deal with this problem. – Alexpts Feb 05 '15 at 14:57
0

The .on() function can be a solution for your problem.You can even set event with "document".As you can call .on() function on "document" and set whatever event you want.

Here is the link: http://www.w3docs.com/learn-javascript/javascript-events.html

Hazarapet Tunanyan
  • 2,809
  • 26
  • 30