1、根据鼠标的位置定位在元素内出现的方向
2、根据方向动态设置遮罩层样式
3、设置动画移动遮罩层
jQuery插件可以通过$.fn.extend方法进行拓展。
<div class="container"> <div class="content" style="background:aqua"> <div class="shade"> <p>mouse hover</p> </div> </div> <div class="content" style="background:bisque"> <div class="shade"> <p>mouse hover</p> </div> </div> <div class="content" style="background:cadetblue"> <div class="shade"> <p>mouse hover</p> </div> </div> <div class="content" style="background:chocolate"> <div class="shade"> <p>mouse hover</p> </div> </div> <div class="content" style="background:cornflowerblue"> <div class="shade"> <p>mouse hover</p> </div> </div> <div class="content" style="background:darkkhaki"> <div class="shade"> <p>mouse hover</p> </div> </div> </div>
.container {
 width: 600px;
 margin: auto;
 margin-top: 100px;
}
.content {
 float: left;
 position: relative;
 height: 150px;
 width: 150px;
 margin: 20px;
 overflow: hidden;
 background: #ccc;
}
.content .shade {
 position: absolute;
 top: 0;
 display: none;
 width: 100%;
 height: 100%;
 line-height: 100px;
 color: #fff;
 background: rgba(0, 0, 0, 0.7);
}<script>
 (function ($) {
 $.fn.extend({
 "mouseMove": function (child) {
 $(this).hover(function (e) {
 $this = $(this);
 var ele = $this.find(child);
 var clientX = e.clientX;
 var clientY = e.clientY;
 var top = parseInt($this.offset().top);
 var bottom = parseInt(top + $this.height());
 var left = parseInt($this.offset().left);
 var right = parseInt(left + $this.width());
 var absTop = Math.abs(clientY - top);
 var absBottom = Math.abs(clientY - bottom);
 var absLeft = Math.abs(clientX - left);
 var absRight = Math.abs(clientX - right);
 var min = Math.min(absTop, absBottom, absLeft, absRight);
 var eventType = e.type;
 switch (min) {
 case absTop:
 animate("top", eventType, ele);
 break;
 case absBottom:
 animate("bottom", eventType, ele);
 break;
 case absLeft:
 animate("left", eventType, ele);
 break;
 case absRight:
 animate("right", eventType, ele)
 }
 })
 }
 });
 function animate(direction, type, ele) {
 var timer = 200;
 var $target = $(ele);
 if (type == "mouseenter") {
 $target.stop(true, true);
 }
 if (direction == "top") {
 if (type == "mouseenter") {
 $target.css({
 display: "block",
 top: "-100%",
 left: "0"
 }).animate({
 top: 0,
 left: 0
 }, timer)
 } else {
 $target.animate({
 display: "block",
 top: "-100%",
 left: "0"
 }, timer)
 }
 } else if (direction == "left") {
 if (type == "mouseenter") {
 $target.css({
 display: "block",
 top: "0",
 left: "-100%"
 }).animate({
 left: 0,
 top: 0
 }, timer)
 } else {
 $target.animate({
 display: "block",
 left: "-100%"
 }, timer)
 }
 } else if (direction == "bottom") {
 if (type == "mouseenter") {
 $target.css({
 display: "block",
 top: "100%",
 left: "0"
 }).animate({
 top: 0,
 left: 0
 }, timer)
 } else {
 $target.animate({
 display: "block",
 top: "100%",
 left: "0"
 }, timer)
 }
 } else if (direction == "right") {
 if (type == "mouseenter") {
 $target.css({
 display: "block",
 top: 0,
 left: "100%"
 }).animate({
 left: "0%",
 top: 0
 }, timer)
 } else {
 $target.animate({
 display: "block",
 left: "100%"
 }, timer)
 }
 }
 }
 $('.content').mouseMove('.shade')
 })(window.jQuery);
</script>通用Vue的组件实现判断元素内鼠标的位置,利用插槽的方式显示遮罩层内容。
<div id="app"> <mouse-hover style="background:aqua"> <div slot>mouse hover</div> </mouse-hover> <mouse-hover style="background:bisque"> <div slot>mouse hover</div> </mouse-hover> <mouse-hover style="background:cadetblue"> <div slot>mouse hover</div> </mouse-hover> <mouse-hover style="background:chocolate"> <div slot>mouse hover</div> </mouse-hover> <mouse-hover style="background:cornflowerblue"> <div slot>mouse hover</div> </mouse-hover> <mouse-hover style="background:darkkhaki"> <div slot>mouse hover</div> </mouse-hover> </div>
<style>
 html,
 body {
 text-align: center;
 color: #000;
 background-color: #353535;
 }
 * {
 box-sizing: border-box;
 }
 #app {
 width: 600px;
 margin: auto;
 margin-top: 100px;
 }
 .content {
 float: left;
 position: relative;
 height: 150px;
 width: 150px;
 margin: 20px;
 overflow: hidden;
 background: #ccc;
 }
 .content .shade {
 position: absolute;
 top: 0;
 left: -100%;
 width: 100%;
 height: 100%;
 line-height: 100px;
 color: #fff;
 background: rgba(0, 0, 0, 0.7);
 }
</style><script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.min.js"></script>
<script>
 (function () {
 const mouseHover = {
 name: 'mouseHover',
 template: `
 <p class="content" @mouseenter="handleIn" @mouseleave="handleOut">
 <p class="shade" ref="shade">
 <slot></slot>
 </p>
 </p>
 `,
 data: () => {
 return {}
 },
 methods: {
 handleIn: function (e) {
 const direction = this.direction(e);
 this.animate(direction, 'in');
 },
 handleOut: function (e) {
 const direction = this.direction(e);
 this.animate(direction, 'out');
 },
 direction: function (e, type) {
 const clientX = e.clientX;
 const clientY = e.clientY;
 const top = e.target.offsetTop;
 const bottom = parseInt(top + e.target.offsetHeight);
 const left = e.target.offsetLeft;
 const right = parseInt(left + e.target.offsetWidth);
 const absTop = Math.abs(clientY - top);
 const absBottom = Math.abs(clientY - bottom);
 const absLeft = Math.abs(clientX - left);
 const absRight = Math.abs(clientX - right);
 const min = Math.min(absTop, absBottom, absLeft, absRight);
 let direction;
 switch (min) {
 case absTop:
 direction = "top";
 break;
 case absBottom:
 direction = "bottom";
 break;
 case absLeft:
 direction = "left";
 break;
 case absRight:
 direction = "right";
 break;
 };
 return direction;
 },
 animate: function (direction, type) {
 let top = 0,
 left = 0;
 if (type == 'in') {
 this.$refs.shade.style.transition = 'none';
 if (direction == 'top') {
 top = '-100%';
 left = 0;
 } else if (direction == 'right') {
 top = 0;
 left = '100%';
 } else if (direction == 'bottom') {
 top = '100%';
 left = 0;
 } else if (direction == 'left') {
 top = 0;
 left = '-100%';
 }
 this.$refs.shade.style.top = top;
 this.$refs.shade.style.left = left;
 setTimeout(() => {
 this.$refs.shade.style.transition = 'all .2s ease 0s';
 this.$refs.shade.style.top = 0;
 this.$refs.shade.style.left = 0;
 }, 0)
 } else if (type == 'out') {
 if (direction == 'top') {
 top = '-100%';
 left = 0;
 } else if (direction == 'right') {
 top = 0;
 left = '100%';
 } else if (direction == 'bottom') {
 top = '100%';
 left = 0;
 } else if (direction == 'left') {
 top = 0;
 left = '-100%';
 }
 this.$refs.shade.style.top = top;
 this.$refs.shade.style.left = left;
 }
 }
 }
 }
 Vue.component(mouseHover.name, mouseHover)
 new Vue({
 el: '#app'
 })
 })();
</script>下载本文