# Sử dụng thư viện jquery.hoverdir.js để làm hiệu ứng hover tuyệt đẹp (ok)

### [Hover 1](https://github.com/webmandesign/jquery.hoverdir)

![](/files/KOZqwNfzGx2Iy72moL4Z)

Một ví dụ thực hành :)

C:\Users\Administrator\OneDrive\Desktop\web\test.html

```
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <script src="js/jquery.min.js"></script>
  <!-- <script src="js/modernizr.js"></script> -->
  <script type="text/javascript" src="js/jquery.hoverdir.js"></script>
  <title>Document</title>
  <style type="text/css">
  .da-thumbs {
    list-style: none;
    width: 984px;
    height: 600px;
    position: relative;
    margin: 20px auto;
    padding: 0;
  }
  .da-thumbs li {
    float: left;
    margin: 0.4%;
    background: #EFEFEF;
    padding: 8px;
    position: relative;
    box-shadow: 0 1px 3px rgb(231 231 231 / 43%);
    width: 32.4%;
  }
  .da-thumbs li a {
    overflow: hidden;
  }
  .da-thumbs li a,
  .da-thumbs li a img {
    display: block;
    position: relative;
  }
  .da-thumbs li a div {
    position: absolute;
    background: #333;
    background: rgba(75, 75, 75, 0.7);
    width: 100%;
    height: 100%;
  }
  .da-thumbs li a div h5 {
    color: #FFF;
    font-size: 1.5em;
    margin: 3.5em 0 0 0;
    font-family: 'Audiowide-Regular';
    text-align: center;
  }
  .da-thumbs li a div span {
    display: block;
    padding: 10px 0;
    margin: 11px 20px 20px 20px;
    font-weight: normal;
    text-transform: capitalize;
    color: rgba(255, 255, 255, 0.9);
    text-align: center;
    font-size: 14px;
    font-family: 'Raleway-Regular';
  }
  </style>
</head>
<body>
  <section>
    <ul id="da-thumbs" class="da-thumbs">
      <li>
        <a href="images/g-1.jpg" rel="title" class="b-link-stripe b-animate-go  thickbox">
          <img src="images/g-1.jpg" alt="" />
          <div>
            <h5>Coffee</h5>
            <span>non suscipit leo fringilla non suscipit leo fringilla molestie</span>
          </div>
        </a>
      </li>
      <li>
        <a href="images/g-2.jpg" rel="title" class="b-link-stripe b-animate-go  thickbox">
          <img src="images/g-2.jpg" alt="" />
          <div>
            <h5>Coffee</h5>
            <span>non suscipit leo fringilla non suscipit leo fringilla molestie</span>
          </div>
        </a>
      </li>
      <li>
        <a href="images/g-3.jpg" rel="title" class="b-link-stripe b-animate-go  thickbox">
          <img src="images/g-3.jpg" alt="" />
          <div>
            <h5>Coffee</h5>
            <span>non suscipit leo fringilla non suscipit leo fringilla molestie</span>
          </div>
        </a>
      </li>
      <li>
        <a href="images/g-4.jpg" rel="title" class="b-link-stripe b-animate-go  thickbox">
          <img src="images/g-4.jpg" alt="" />
          <div>
            <h5>Coffee</h5>
            <span>non suscipit leo fringilla non suscipit leo fringilla molestie</span>
          </div>
        </a>
      </li>
      <li>
        <a href="images/g-5.jpg" rel="title" class="b-link-stripe b-animate-go  thickbox">
          <img src="images/g-5.jpg" alt="" />
          <div>
            <h5>Coffee</h5>
            <span>non suscipit leo fringilla non suscipit leo fringilla molestie</span>
          </div>
        </a>
      </li>
      <li>
        <a href="images/g-6.jpg" rel="title" class="b-link-stripe b-animate-go  thickbox">
          <img src="images/g-6.jpg" alt="" />
          <div>
            <h5>Coffee</h5>
            <span>non suscipit leo fringilla non suscipit leo fringilla molestie</span>
          </div>
        </a>
      </li>
      <li>
        <a href="images/g-7.jpg" rel="title" class="b-link-stripe b-animate-go  thickbox">
          <img src="images/g-7.jpg" alt="" />
          <div>
            <h5>Coffee</h5>
            <span>non suscipit leo fringilla non suscipit leo fringilla molestie</span>
          </div>
        </a>
      </li>
      <li>
        <a href="images/g-8.jpg" rel="title" class="b-link-stripe b-animate-go  thickbox">
          <img src="images/g-8.jpg" alt="" />
          <div>
            <h5>Coffee</h5>
            <span>non suscipit leo fringilla non suscipit leo fringilla molestie</span>
          </div>
        </a>
      </li>
      <li>
        <a href="images/g-9.jpg" rel="title" class="b-link-stripe b-animate-go  thickbox">
          <img src="images/g-9.jpg" alt="" />
          <div>
            <h5>Coffee</h5>
            <span>non suscipit leo fringilla non suscipit leo fringilla molestie</span>
          </div>
        </a>
      </li>
      <div class="clearfix"> </div>
    </ul>
  </section>
  <script type="text/javascript">
  $(function() {
    $(' #da-thumbs > li ').each(function() { $(this).hoverdir(); });
  });
  </script>
</body>
</html>
```

{% file src="/files/Yh1SH8YS1CdBbWHEDI2d" %}

### [Hover 2](https://codepen.io/muhammad_mabrouk/pen/JKgZQL)

```javascript
<div class="da-thumbs">
  
  <div>
    <a href="#">
      <img src="https://cdn.shopify.com/s/files/1/1047/8278/products/electric-toy-car-bmw-x5_large.png?v=1449651980" />
      <div>hover image 1</div>
    </a>
  </div>
  
  <div>
    <a href="#">
      <img src="https://cdn.shopify.com/s/files/1/1047/8278/products/electric-toy-car-bmw-x5_large.png?v=1449651980" />
      <div>hover image 2</div>
    </a>
  </div>
  
  <div>
    <a href="#">
      <img src="https://cdn.shopify.com/s/files/1/1047/8278/products/electric-toy-car-bmw-x5_large.png?v=1449651980" />
      <div>hover image 3</div>
    </a>
  </div>

  <div>
    <a href="#">
      <img src="https://cdn.shopify.com/s/files/1/1047/8278/products/electric-toy-car-bmw-x5_large.png?v=1449651980" />
      <div>hover image 4</div>
    </a>
  </div>
  
  <div>
    <a href="#">
      <img src="https://cdn.shopify.com/s/files/1/1047/8278/products/electric-toy-car-bmw-x5_large.png?v=1449651980" />
      <div>hover image 5</div>
    </a>
  </div>
  
  <div>
    <a href="#">
      <img src="https://cdn.shopify.com/s/files/1/1047/8278/products/electric-toy-car-bmw-x5_large.png?v=1449651980" />
      <div>hover image 6</div>
    </a>
  </div>
  
</div>
```

```javascript
.da-thumbs {
	position: relative;
  width: 800px;
	margin: 20px auto;
	padding: 0;
}
.da-thumbs > div {
  float: left;
  background-color: #eee;
  margin: 5px;
  padding: 3px;
	position: relative;
}
.da-thumbs > div a,
.da-thumbs > div a img {
	display: block;
	position: relative;
}
.da-thumbs > div a {
	overflow: hidden;
}
.da-thumbs > div a img {
	height: 200px;
}
.da-thumbs > div a div {
	position: absolute;
	width: 100%;
	height: 100%;
	background: rgba(60, 60, 60, 0.7);
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center
}
```

```javascript
$(function () {
  $('.da-thumbs > div').hoverdir();
});

// external js file

(function (factory) {
  'use strict';
  if (typeof define === 'function' && define.amd) {
    define(['jquery'], factory);
  } else if (typeof exports !== 'undefined') {
    module.exports = factory(require('jquery'));
  } else {
    factory(jQuery);
  }
})(function ($) {
  'use strict';

  function Hoverdir(element, options) {
    this.$el = $(element);
    // set options
    this.options = $.extend(true, {}, this.defaults, options);
    // initialize visibility to false for show and hide method
    this.isVisible = false;
    // get the hover for this element
    this.$hoverElem = this.$el.find(this.options.hoverElem);
    // transition properties
    this.transitionProp = 'all ' + this.options.speed + 'ms ' + this.options.easing;
    // support for CSS transitions
    this.support = this._supportsTransitions();
    // load the events
    this._loadEvents();
  }

  Hoverdir.prototype = {
    defaults: {
      speed: 300,
      easing: 'ease',
      hoverDelay: 0,
      inverse: false,
      hoverElem: 'div'
    },
    constructor: Hoverdir,
    /**
         * Detect if CSS transitions are supported
         *
         * @return {Boolean}
         */
    _supportsTransitions: function () {
      if (typeof Modernizr !== 'undefined') {
        return Modernizr.csstransitions;
      } else {
        var b = document.body || document.documentElement,
            s = b.style,
            p = 'transition';

        if (typeof s[p] === 'string') {
          return true;
        }

        // Tests for vendor specific prop
        var v = ['Moz', 'webkit', 'Webkit', 'Khtml', 'O', 'ms'];
        p = p.charAt(0).toUpperCase() + p.substr(1);

        for (var i = 0; i < v.length; i++) {
          if (typeof s[v[i] + p] === 'string') {
            return true;
          }
        }

        return false;
      }
    },
    /**
         * Bind the events to the element
         */
    _loadEvents: function () {
      this.$el.on('mouseenter.hoverdir mouseleave.hoverdir', $.proxy(function (event) {
        this.direction = this._getDir({x: event.pageX, y: event.pageY});

        if (event.type === 'mouseenter') {
          this._showHover();
        }
        else {
          this._hideHover();
        }
      }, this));
    },
    /**
         * Show the hover of the element
         */
    _showHover: function () {
      var styleCSS = this._getStyle(this.direction);

      if (this.support) {
        this.$hoverElem.css('transition', '');
      }

      this.$hoverElem.hide().css(styleCSS.from);
      clearTimeout(this.tmhover);

      this.tmhover = setTimeout($.proxy(function () {
        this.$hoverElem.show(0, $.proxy(function () {
          if (this.support) {
            this.$hoverElem.css('transition', this.transitionProp);
          }
          this._applyAnimation(styleCSS.to);

        }, this));
      }, this), this.options.hoverDelay);

      this.isVisible = true;
    },
    /**
         * Hide the hover to the element
         */
    _hideHover: function () {
      var styleCSS = this._getStyle(this.direction);
      if (this.support) {
        this.$hoverElem.css('transition', this.transitionProp);
      }
      clearTimeout(this.tmhover);
      this._applyAnimation(styleCSS.from);
      this.isVisible = false;
    },
    /**
         * get the direction when the event is triggered
         * credits : http://stackoverflow.com/a/3647634
         *
         * @param {Object} coordinates
         * @returns {Interger}
         */
    _getDir: function (coordinates) {
      // the width and height of the current div
      var w = this.$el.width(),
          h = this.$el.height(),
          // calculate the x and y to get an angle to the center of the div from that x and y.
          // gets the x value relative to the center of the DIV and "normalize" it
          x = (coordinates.x - this.$el.offset().left - (w / 2)) * (w > h ? (h / w) : 1),
          y = (coordinates.y - this.$el.offset().top - (h / 2)) * (h > w ? (w / h) : 1),
          // the angle and the direction from where the mouse came in/went out clockwise (TRBL=0123);
          // first calculate the angle of the point,
          // add 180 deg to get rid of the negative values
          // divide by 90 to get the quadrant
          // add 3 and do a modulo by 4 to shift the quadrants to a proper clockwise TRBL (top/right/bottom/left) **/
          direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
      return direction;
    },
    /**
         * get the style when the event is triggered
         *
         * @param {(Interger|String)} direction
         * @returns {Object}
         */
    _getStyle: function (direction) {
      var fromStyle, toStyle,
          slideFromTop = {'left': '0', 'top': '-100%'},
          slideFromBottom = {'left': '0', 'top': '100%'},
          slideFromLeft = {'left': '-100%', 'top': '0'},
          slideFromRight = {'left': '100%', 'top': '0'},
          slideTop = {'top': '0'},
          slideLeft = {'left': '0'};

      switch (direction) {
        case 0:
        case 'top':
          // from top
          fromStyle = !this.options.inverse ? slideFromTop : slideFromBottom;
          toStyle = slideTop;
          break;
        case 1:
        case 'right':
          // from right
          fromStyle = !this.options.inverse ? slideFromRight : slideFromLeft;
          toStyle = slideLeft;
          break;
        case 2:
        case 'bottom':
          // from bottom
          fromStyle = !this.options.inverse ? slideFromBottom : slideFromTop;
          toStyle = slideTop;
          break;
        case 3:
        case 'left':
          // from left
          fromStyle = !this.options.inverse ? slideFromLeft : slideFromRight;
          toStyle = slideLeft;
          break;
      }

      return {from: fromStyle, to: toStyle};
    },
    /**
         * Apply a transition or fallback to jquery animate based on Modernizr.csstransitions support
         *
         * @param {Object} styleCSS
         */
    _applyAnimation: function (styleCSS) {
      $.fn.applyStyle = this.support ? $.fn.css : $.fn.animate;
      this.$hoverElem.stop().applyStyle(styleCSS, $.extend(true, [], {duration: this.options.speed}));
    },
    /**
         * Show $hoverElem from the direction in argument
         *
         * @param {String} [direction=top] direction
         */
    show: function (direction) {
      this.$el.off('mouseenter.hoverdir mouseleave.hoverdir');
      if (!this.isVisible) {
        this.direction = direction || 'top';
        this._showHover();
      }
    },
    /**
         * Hide $hoverElem from the direction in argument
         *
         * @param {String} [direction=bottom] direction
         */
    hide: function (direction) {
      this.rebuild();
      if (this.isVisible) {
        this.direction = direction || 'bottom';
        this._hideHover();
      }
    },
    setOptions: function (options) {
      this.options = $.extend(true, {}, this.defaults, this.options, options);
    },
    /**
         * Unbinds the plugin.
         */
    destroy: function () {
      this.$el.off('mouseenter.hoverdir mouseleave.hoverdir');
      this.$el.data('hoverdir', null);
    },
    /**
         * Bind the plugin.
         */
    rebuild: function (options) {
      if (typeof options === 'object') {
        this.setOptions(options);
      }
      this._loadEvents();
    }
  };

  $.fn.hoverdir = function (option, parameter) {
    return this.each(function () {
      var data = $(this).data('hoverdir');
      var options = typeof option === 'object' && option;

      // Initialize hoverdir.
      if (!data) {
        data = new Hoverdir(this, options);
        $(this).data('hoverdir', data);
      }

      // Call hoverdir method.
      if (typeof option === 'string') {
        data[option](parameter);

        if (option === 'destroy') {
          $(this).data('hoverdir', false);
        }
      }
    });
  };

  $.fn.hoverdir.Constructor = Hoverdir;
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://javascriptuse.gitbook.io/javascript/su-dung-thu-vien-jquery.hoverdir.js-de-lam-hieu-ung-hover-tuyet-dep-ok.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
