Suraj Jadhav
Suraj Jadhav

Reputation: 652

Flicker on hover of element while trying to shrink it's size on the same event

$myPseudoEl.on({
    mouseenter: function (e) {
            $(this).animate({
                'width': '50%'
            }, 50);
        }
    },
    mouseleave: function (e) {
          $(this).animate({
              'width': '70%'
          }, 50);
        }
    }
});

Here is a JSFiddle to see it in action. To reproduce it just make sure you enter your cursor inside the element from sideways i.e. from right and left. I know why it is happening, just wanted an elegant solution to it.

Upvotes: 2

Views: 40

Answers (2)

kpucha
kpucha

Reputation: 729

Try this.

var $el = $('.book-button-handle')
var $wrapper = $el.find('.handle-content');
var enter = false;
var exit = false;

var changeContent = function (content) {
    $wrapper.fadeOut(50, function () {
        $wrapper.html('<span class="handle-content">' + content + '</span>').fadeIn(50);
    });
};

var labelChanger = function (off, on) {
    $el.off('mouseenter').off('mouseleave');
    $el.on({
        mouseenter: function (e) {
          if (!$(this).is(':animated') && !enter){
          	changeContent(on);
            $(this).animate({
              'width': '50%',
              'height': '15px',
              'color': 'white',
              'background-color': 'black'
            }, 50);
            $('.log').append('<li>enter</li>');
            enter=true;
            exit=false;
          } 
        },
        mouseleave: function (e) {
        	if (!$(this).is(':animated') && !exit){
            changeContent(off);
            $(this).animate({
              'width': '70%',
              'height': '15px',
              'color': 'black',
              'background-color': 'white'
            }, 50);
            $('.log').append('<li>leave</li>');
            enter=false;
            exit=true;
          }
        }
    });
};


labelChanger("+","more options");
.book-button-handle {
    margin: 10px auto 0px;
    width: 70%;
    height: 15px;
    border: 1px solid silver;
    font-size: 10pt;
    line-height: 15px;
    color: black;
    text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="book-button-handle"> <span class="handle-content"> + </span>

</div>
<ul class="log">
</ul>

  • I added if (!$(this).is(':animated')) to prevent the triggering of the event while it is under the previous animation.
  • I added if (exit) & if (enter) to prevent triggerint two times the same event on enter/leave the element.

Upvotes: 0

Jai
Jai

Reputation: 74738

I would wrap it within a wrapper element:

 var $el = $('#wrapper')
 var $wrapper = $el.find('.handle-content');

 var changeContent = function(content) {
   $wrapper.fadeOut(50, function() {
     $wrapper.html('<span class="handle-content">' + content + '</span>').fadeIn(50);
   });
 };

 var labelChanger = function(off, on) {
   $el.off('mouseenter').off('mouseleave');
   $el.on({
     mouseenter: function(e) {
       changeContent(on);
       $(this).find('.book-button-handle').animate({
         'width': '50%',
         'height': '15px',
         'color': 'white',
         'background-color': 'black'
       }, 50);
       $('.log').append('<li>enter</li>');
     },
     mouseleave: function(e) {
       changeContent(off);
       $(this).find('.book-button-handle').animate({
         'width': '100%',
         'height': '15px',
         'color': 'black',
         'background-color': 'white'
       }, 50);
       $('.log').append('<li>leave</li>');
     }
   });
 };


 labelChanger("+", "more options");
#wrapper {
  margin: 10px auto 0px;
  width: 70%;
  height: 15px;
  background: yellow;
}
.book-button-handle {
  margin: 0 auto;
  width: 100%;
  height: 15px;
  border: 1px solid silver;
  font-size: 10pt;
  line-height: 15px;
  color: black;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='wrapper'>
  <div class="book-button-handle">
    <span class="handle-content"> + </span>
  </div>
</div>

<ul class="log">
</ul>

Upvotes: 2

Related Questions