为了账号安全,请及时绑定邮箱和手机立即绑定

鼠标移入移出效果 -- jQuery/Vue版

标签:
JQuery Vue.js

元素内遮罩层根据鼠标方向显示的效果比较常见,比如百度图片里的图片信息展示。自己动手实现jQuery插件版和Vue组件版效果。

原文链接

实现思路

1、根据鼠标的位置定位在元素内出现的方向
2、根据方向动态设置遮罩层样式
3、设置动画移动遮罩层

jQuery版

jQuery插件可以通过$.fn.extend方法进行拓展。

html

<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>

css

.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);
}

js

<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版

通用Vue的组件实现判断元素内鼠标的位置,利用插槽的方式显示遮罩层内容。

html

<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>

css

<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>

js

<script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.min.js"></script><script>
        (function () {                const mouseHover = {                        name: 'mouseHover',                        template: `
                        <div class="content" @mouseenter="handleIn" @mouseleave="handleOut">
                                <div class="shade" ref="shade">
                                        <slot></slot>
                                </div>
                        </div>
                        `,                        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>

效果

webp

image



作者:bestvist
链接:https://www.jianshu.com/p/f61505c3c09b


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消