Morgari
Morgari

Reputation: 555

Image is shaking with onmouseover event

I'cant solve my problem with quaking image on mouseover. I have the following script:

      function displayText(id)
      {
        var el = document.getElementById(id);

        el.style.display = 'block';
      }

      function hideText(id)
      {
        var el = document.getElementById(id);

        el.style.display = 'none';
      }
    
.btn {
    margin-top: -90px;
    z-index: 999999999;
    position: absolute;
    text-align: center;
    background: #37a000;
    displa: block;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<a href='#' >
<img class="streamer_img" alt="example" src="https://placeimg.com/640/480/nature"
onmouseover="this.src='https://placeimg.com/640/480/people'; displayText('hiddentext')" 
onmouseout="this.src='https://placeimg.com/640/480/nature'; hideText('hiddentext')" />
<p class="btn" id="hiddentext" style="display: none;">Watch/play</p>
</a>

Everything is fine but when I move my mouse over the displayed Watch text everything starts to shake.

How can I solve this trouble? Thanks

Upvotes: 1

Views: 1056

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337560

The issue is because when you hover over the Watch element it triggers the mouseout event on the img which changes the image. That in turn hides the text, which triggers the mouseover which shows the image... and so on infinitely.

To fix this you can instead attach the event handlers to the parent a element and find the img element within that to amend it, like this:

function displayText(id) {
  var el = document.getElementById(id);
  el.style.display = 'block';
}

function hideText(id) {
  var el = document.getElementById(id);
  el.style.display = 'none';
}
.btn {
  margin-top: -90px;
  z-index: 999999999;
  position: absolute;
  text-align: center;
  background: #37a000;
  displa: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<a href='#' onmouseenter="this.getElementsByClassName('streamer_img')[0].src='https://placeimg.com/640/480/people'; displayText('hiddentext')" onmouseleave="this.getElementsByClassName('streamer_img')[0].src='https://placeimg.com/640/480/nature'; hideText('hiddentext')">
  <img class="streamer_img" alt="example" src="https://placeimg.com/640/480/nature" />
  <p class="btn" id="hiddentext" style="display: none;">Watch/play</p>
</a>

Note that I changed the event handlers to onmouseenter and onmouseleave for better performance.

However you should note that using on* event attributes is awfully outdated. You should be using unobtrusive event handlers instead, like this:

window.addEventListener('load', function() {
  var a = document.querySelector('a');
  var img = document.querySelector('img');
  var p = document.querySelector('p');

  a.addEventListener('mouseenter', function() {
    img.src = a.dataset.hoversrc;
    p.style.display = 'block';
  });
  
  a.addEventListener('mouseleave', function() {
    img.src = a.dataset.leavesrc;
    p.style.display = 'none';
  });
});
.btn {
  margin-top: -90px;
  z-index: 999999999;
  position: absolute;
  text-align: center;
  background: #37a000;
  displa: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<a href='#' data-hoversrc="https://placeimg.com/640/480/people" data-leavesrc="https://placeimg.com/640/480/nature">
  <img class="streamer_img" alt="example" src="https://placeimg.com/640/480/nature" />
  <p class="btn" id="hiddentext" style="display: none;">Watch/play</p>
</a>

Upvotes: 5

Related Questions