鼠标移入移出效果 -- jQuery/Vue版_bestvist的博客-程序员宅基地

技术标签: mouse  vue  javascript  jquery  

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

原文地址

git地址

实现思路

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

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 src="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>

效果

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_38082661/article/details/80797566

智能推荐

php文件上传_yuese丶的博客-程序员宅基地

开发的时候需要做个图片接口,在写php文件上传功能的时候网上找了不少php代码都没讲清楚,于是自己写了一个2.html和2.php两个文件能实现文件上传2.html里&lt;html&gt;&lt;head&gt;&lt;meta charset="utf-8"&gt;&lt;title&gt;1&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;form action="2.php" method="post" enctype="multipart.

winform打开新窗体关闭旧窗体_Jakie_Zhan的博客-程序员宅基地_winform打开新窗体关闭旧窗体

项目需求,程序的主页面不关闭,当点击流程页面时候弹出新窗体,关闭旧窗体。利用委托实现了这个需求,直接上代码旧窗体(Form3窗体)中代码:private void button1_Click(object sender, EventArgs e) { //this.Hide();隐藏旧窗体 //Form4 f = new Form4(...

ucore lab8 操作系统实验_coding丁的博客-程序员宅基地

实验相关知识(主要从教学ppt、gitbook、学堂在线上了解掌握并根据CSDN查询了解更加详细的信息。同时结合自己的理论课笔记,实际上是对理论知识的复习)文件系统:操作系统中负责管理和存储可长期保存数据的软件功能模块UNIX提出了四个文件系统抽象概念:文件(file)、目录项(dentry)、索引节点(inode)和安装点(mount point)。文件:UNIX文件中的内容可理解为是...

android 转移照片ios,React-Native 支持ios与android图片保存到本地_weixin_40008339的博客-程序员宅基地

看了 http://1c7.me/2018-react-native-save-image-file-from-app-to-phone/ 以为要这两个库配合使用 (react-native-fetch-blob 、react-native-fs) 后来发现用react-native-fs 就能实现我的业务需求:保存一张图片到本地 !因为不知道RNFS提供的存储路径有权限问题,导致会看不到存...

Aegisub的视频窗口详解_YukiNo_2020的博客-程序员宅基地_aegisub

Aegisub的视频窗口详解标准模式拖放字幕绕Z轴旋转字幕绕X轴或Y轴旋转字幕沿X轴和Y轴方向缩放矩形裁剪矢量裁剪标准模式在标准模式下,想要对字幕的位置进行更改,可通过下面两种方法来实现 1. 鼠标左键在指定的位置上双击(字幕位置与对齐方式有关) 2. 通过鼠标右键的复制坐标到剪切板得到坐标,粘贴到编辑框内拖放字幕这个模式可以直接鼠标左键拖拽字幕到想要的字幕,更加直观。️...

人生苦短,我学Python-006:组合数据类型_-西西弗斯的博客-程序员宅基地_word,count=items[i]

    #CalStatisticsV1.py    def getNum():       #获取用户不定长度的输入        nums = []        iNumStr = input(&quot;请输入数字(回车退出): &quot;)        while iNumStr != &quot;&quot;:            nums.append(eval(iNumStr))            iNumSt...

随便推点

webcat——基于netty的http和websocket框架_weixin_33699914的博客-程序员宅基地

代码地址如下:http://www.demodashi.com/demo/12687.htmlWebcat是一个基于netty的简单、高性能服务端框架,目前提供http和websocket两种协议的快速开发模式。webcat采用spring进行对象管理,因此工程需要依赖spring框架,Github地址。下载源代码后,可以直接运行WebcatServerTest启动http和websock...

[转载]游戏相关引擎荟萃2_syaka007的博客-程序员宅基地

[转载]游戏相关引擎荟萃2NameLanguagePlatformLicenseGraphicsSoundNetworkingScriptingOther featuresPlusMinus3DCakeWalkPythonWindows/LinuxCommercial2D/3D via Dire

qml语言基础_-兮的博客-程序员宅基地

如上图,新建一个空的Qt Quick Application,运行就是一个空的窗口文件import语句导入模块,类似于c++中的includeQtQuick 2.9:此模块为创建图形用户界面提供了最基本的类型QtQuick.Window模块:window类型可以为Qt Quick场景创建一个顶级窗口QML对象对象类型被实例化以后,就叫做该对象类型的对象如Window,在代码中现在就是一个对象,以大写字母开头,后面跟一对大括号,在括号中包含对象的属性QML元素如以下的控件...

OS-操作系统_Dymc的博客-程序员宅基地

好玩的OS:有趣的对话:(1)啥是操作系统?(概念)哈哈哈,操作系统就是控制和管理硬件和软件资源、合理地对各类作业进行调度、以及方便用户使用的程序(或系统软件)的集合。所以,OS属于软件。(2)那计算机好好的,干嘛要装OS尼?它可以解决啥问题?(作用)告诉你吧,在没有OS的年代里用户需要直接与计算机的最低层硬件接触,不管是执行什么命令,首先都是了解其物理结构,而物理结构又是如此的复杂,这对用户使用...

学习Python的代码记录_Rou1998的博客-程序员宅基地

#0925-第三关 if条件语句answer=input ('''人在烦躁的时候要怎么办?你有三个选项,请回答1、2、3、4 ''')if answer=='1': print('没有什么是一杯酸奶解决不了的')elif answer=='2': print('你可以多跑几圈')elif answer=='3': print('写写日记和自己对话吧')else: print('那就坐着发呆吧')#0928-第四关 布尔值#1.布尔值的使用情况:两个数值在