专栏首页HTML5学堂“鼠标移入显示悬浮框”特效,也可以“高大上”

“鼠标移入显示悬浮框”特效,也可以“高大上”

HTML5学堂(码匠):网站中最为常见的一种特效——鼠标移入元素,出现介绍信息的悬浮框,要么是淡入,要么是单方向的滑入,总觉得太单一了有木有?其实,稍微调整一下,这个效果就可以变得“高大上”起来,虽然会涉及到一些计算,不过不难哦!快来get新技能,让自己的网站效果变得更漂亮吧!

本文主要内容

1、案例效果与说明

2、实现原理分析

3、功能实现

1、案例效果与说明

在效果当中,当用户将鼠标移入一个块时,会从鼠标的移入方向滑入一个悬浮块,悬浮块会随着鼠标移出当前块,且滑出方向遵循鼠标的移出方向(录制gif图像时不能够录制鼠标,因此无法展示鼠标位置)。看完以后,不知道大家有没有自己的实现思路或想法。该效果的难点在于鼠标临界值位置的判断。

2、实现原理分析

2.1.结构分析

由于悬浮层有可能从上下左右四个方向滑入目标块,因此需要先针对结构进行处理。

在此,可以通过两种方法实现“悬浮层”。

一种方法是为每个块定位四个悬浮块(上下左右),当满足鼠标移入的条件时,让相应的悬浮块滑入;

第二种方法是只为每个块定位一个悬浮框,每次鼠标移入时,先“初始化”悬浮块的位置,之后再控制悬浮框滑入。

在本文的案例当中,小编使用的是第二种方法(初始化悬浮块位置)来实现滑动。

2.2.功能实现逻辑分析

首先通过JS,获取鼠标在块当中的坐标;

此后,根据“鼠标所处的位置”判断鼠标移入方向“;

最后,再根据鼠标移入方向来执行相应的功能。

3、功能实现

3.1.获取鼠标块内坐标

想要得到鼠标在块内位置,需要使用如下JS中获取位置的方法:

jQuery方法中的“$(元素).offset().top”用于获取元素距页面顶部的距离;“$(元素).offset().left”用于获取元素距页面左边的距离;

原生JS中,通过事件对象(event)的pageX可以获取鼠标相对于页面的X轴位置;通过事件对象(event)的pageY可以获取鼠标相对于页面的Y轴位置。

通过jQuery获取到当前元素与页面顶部、左侧的距离,再获取鼠标处于页面的坐标;之后通过计算获取到下图中的“h”和“w”。

“h”为event.pageY-$(元素).offset().top,是鼠标相对于块元素内的Y轴值;“w”同理。详细可见下图和代码。

范例代码

  1. var x=event.pageX-$(this).offset().left,//得到鼠标在块中的坐标
  2. y=event.pageY-$(this).offset().top,//得到鼠标在块中的坐标

3.2.划分方向区域

由于需要根据“鼠标所处的位置”判断“鼠标移入方向”,因此为四个方向确定“临界值”。为了便于理解,可以使用“对角线”将一个块划分为四个区域(如下A、B、C、D四个区域),与“鼠标移入方向”相对应。

3.3.获取到鼠标的值,判断所处的区域

如何根据鼠标位置值,计算当前鼠标所在位置呢?根据当前X值,求出四条对角线(即Y的临界值),再根据该值进行判断。

↗(左下角到右上角) Y值临界值求法:

当前X值对应的Y值临界值1 = 当前元素高度 / 当前元素宽度 * 当前鼠标X值;

↘(左上角到右下角) Y值临界值求法:

当前X值对应的Y值临界值2 = 当前元素高度 - (当前元素高度 / 当前元素宽度* 当前鼠标X值);

A区域条件:y值 > 临界值1; y值 < 临界值2(在↗对角线上方,↘的下方)

B区域条件:y值 > 临界值1; y值 > 临界值2(在↗对角线上方,↘的上方)

C区域条件:y值 < 临界值1; y值 > 临界值2(在↗对角线下方,↘的上方)

D区域条件:y值 < 临界值1; y值 < 临界值2(在↗对角线下方,↘的下方)

感觉很乱?别急,看图!!!

判断鼠标处于B区的代码实例:

var x=event.pageX-$(this).offset().left,//得到鼠标在块中的坐标
    y=event.pageY-$(this).offset().top,//得到鼠标在块中的坐标
    h=$(this).outerHeight(),//用于获得包括内边界(padding)和边框(border)的元素高度
    w=$(this).outerWidth(),//用于获得包括内边界(padding)和边框(border)的元素宽度
    k=Math.floor(h/w);//正切值,为了防止不能整除
if((k * x) >= y && (h - k * x) >= y){
   //上方进入
}

3.4.根据区域,执行相应方向的功能代码

在判断移入方向之后,接下来就简单多了,为每个元素定位一个悬浮块,根据初始位置执行相应代码。

//上方初始悬浮块位置
$(this).children().css({
  "top":"-100px",
  "left": "0"
})
//设置移入动画
$(this).children().stop(true,true).animate({
   "top":"0"
 },此处设置动画时间,不设置为默认);
//设置移出动画
$(this).children().stop(true,true).animate({
   "top":"-100px"
});

3.5.成品代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
    </head>
    <style type="text/css">
        .move {
            width: 240px;
            height: 240px;
            margin: 100px auto;
        }
        .move li {
            position: relative;
            overflow: hidden;
            list-style: none;
            float: left;
            width: 100px;
            height: 100px;
            margin: 0 20px 20px 0;
            background: #39f;
        }
 .move li div {
            position: absolute;
            width: 100px;
            height: 100px;
            background: #000;
            opacity: 0.5;
            left: 100%;
            top: 0;
        }
    </style>
    <body>
        <ul class="move">
            <li>
                <div></div>
            </li>
            <li>
                <div></div>
            </li>
            <li>
                <div></div>
            </li>
            <li>
                <div></div>
            </li>
        </ul>
        <script src="jquery-1.7.2.js" type="text/javascript"></script>
        <script type="text/javascript">
            $('.move li').hover(function(){// 移入效果
                var x=event.pageX-$(this).offset().left,//得到鼠标在块中的坐标
                    y=event.pageY-$(this).offset().top,//得到鼠标在块中的坐标
                    h=$(this).outerHeight(), //用于获得包括内边界(padding)和边框(border)的元素高度
                    w=$(this).outerWidth(), ///用于获得包括内边界(padding)和边框(border)的元素宽度
                    k=Math.floor(h/w);//为了防止不能整除


                if((k * x) >= y && (h - k * x) >= y){//上方进入
                    //初始悬浮块位置,下同
                    $(this).children().css({
                        "top":"-100px",
                        "left": 0
                    })
                    //设置出现动画,下同
                    $(this).children().stop(true,true).animate({
                        "top": "0"
                    });
                }


                if((k * x) < y && (h - k * x) < y){// 从下方进入
                    $(this).children().css({
                        "top": "100px",
                        "left": "0"
                    })
                    $(this).children().stop(true,true).animate({
                        "top": "0"
                    });
                }


                if((k * x) < y && (h - k * x) > y){
                    $(this).children().css({// 从左边进入
                        "top": "0",
                        "left": "-100px"
                    })
                    $(this).children().stop(true,true).animate({
                        "left": "0"
                    });
                }


                if((k*x)>y && (h-k*x)<y){// 从右边进入
                    $(this).children().css({
                        "top": "0",
                        "left": "100px"
                    })
                    $(this).children().stop(true,true).animate({
                        "left": "0"
                    });
                }


            },function() { // 移出效果
                var x=event.pageX-$(this).offset().left,//得到鼠标在块中的坐标
                    y=event.pageY-$(this).offset().top,//得到鼠标在块中的坐标
                    h=$(this).outerHeight(),            
                    w=$(this).outerWidth(),
                    k=Math.floor(h / w);//为了防止不能整除
                if((k * x) >= y && (h - k * x) >= y){ //从上方移出
                    //移出动画,下同
                    $(this).children().stop(true,true).animate({
                        "top": "-100px"
                    });
                }


                if((k * x) < y && (h - k * x) < y){ //从下方移出
                    $(this).children().stop(true,true).animate({
                        "top": "100px"
                    });
                }


                if((k * x ) < y && (h - k * x) > y){ //从左边移出
                    $(this).children().stop(true,true).animate({
                        "left": "-100px"
                    });
                }
                if((k * x) > y && (h - k * x) < y){ //下右边移出
                    $(this).children().stop(true,true).animate({
                        "left": "100px"
                    });
                }
            })
        </script>
    </body>
</html>

总结

本次文章主要介绍了如何获取鼠标在一个元素中的位置、鼠标的移入方式,还应用到了一些数学计算,大家可以基于该效果做进一步的优化与修改,将该效果融入到其他的相关网页制作当中。

本文分享自微信公众号 - HTML5学堂(h5course-com)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-12-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 动态实现指定图片半透明及鼠标事件

    说明:在不改变HTML代码的前提下,通过CSS和JavaScript,对指定的图片实现半透明效果。并为该图片添加鼠标滑过和滑出特效。 具体实现: 1.假设我们要...

    小李刀刀
  • 走近 Python (类比 JS)

    Python 是一门运用很广泛的语言,自动化脚本、爬虫,甚至在深度学习领域也都有 Python 的身影。作为一名前端开发者,也了解 ES6 中的很多特性借鉴自 ...

    程序员宝库
  • web前端工程师入门须知,你全部了解吗?

    划重点 一名合格的web前端工程师必须得掌握HTML、CSS和JavaScript。只懂其中一个或两个还不行,你必须对这三门语言都很熟悉。也不是说必须对这三门语...

    企鹅号小编
  • 精心收集的 48 个 JavaScript 代码片段,仅需 30 秒就可理解

    该项目来自于 Github 用户 Chalarangelo,目前已在 Github 上获得了 5000 多Star,精心收集了多达 48 个有用的 JavaSc...

    程序员宝库
  • 10 分钟理解 JS 引擎的执行机制

    作者: ziwei3749 原文:https://segmentfault.com/a/1190000012806637 首先,请牢记2点: JS是单线程语言 ...

    程序员宝库
  • 使用 JavaScript 实现机器学习和神经学网络

    英文:JeffHeaton 译文: 云+社区/白加黑大人 https://cloud.tencent.com/developer/article/103589...

    程序员宝库
  • JavaScript 深拷贝性能分析

    作者:justjavac 链接:https://segmentfault.com/a/1190000013107871 如何在 JavaScript 中拷贝一个...

    程序员宝库
  • 用JavaScript动态输出的JS脚本不能执行

    随着Ajax的越来越多地运用,HTML的内容又开始由“所见即所得”开始向“所见未必所得”发展了。这就是动态改变网页内容的魅力所在吧。 在公司产品动易2006版...

    小李刀刀
  • 15 个有趣的 JS 和 CSS 库

    作者:Danny Markov,译者:IT程序狮 译文:https://zhuanlan.zhihu.com/p/31321429 原文:https://tut...

    程序员宝库
  • 10 种最常见的 Javascript 错误

    英文:SKOWRONSKI 译文:elevenbeans elevenbeans.github.io/2018/02/05/top-10-javascript...

    程序员宝库

扫码关注云+社区

领取腾讯云代金券