页面点击特效源码解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 这次给大家分享一个被广泛应用在个人网站中的骚骚的效果,就是鼠标左键点击出现小心心,来看下效果 :

这次给大家分享一个被广泛应用在个人网站中的骚骚的效果,就是鼠标左键点击出现小心心,来看下效果 :

由于我的网站改版了三次,所以效果展示就略掉了哦,咱就讲下源码咯,ok,let's go


微信图片_20220610084307.jpg


   就是当用户点击操作时,会从用户点击处生成一个心形,然后慢慢向上移动,并且伴随着透明度的减小和面积的放大,最终消失.同样适用于PC端和移动端(手机、ipad等终端设备) 其实这个效果的实现,相信学过js的小可爱稍微看下源码就会发现也没有很难,不过借用一句古话,我现在是”醉翁之意不在酒,在乎山水之间”,是不是觉得我很有文化,哈哈,你被骗了,我会花很少的时间去说源码这回事,毕竟很简单,再其中我会夹杂着重点强调debug调试这回事.


   ok,先不用太急,咱们先不看我网站实现这个效果的源码,咱们先思考一个问题,如果要你实现一个效果:点击页面,出现的不是心形,而是出现一些关于博主的关键词,就像这样:


微信图片_20220610084418.png


说下思路:很简单,监听用户操作,当用户执行点击时,在用户当前点击的位置附近(具体位置涉及到用户群对于样式的要求)生成一个标签(我用的是span),里面包裹着对于博主的描述关键词,然后执行一系列动画效果,执行完毕后,移除此标签.

var a_idx = 0;
jQuery(document).ready(function($) {
    $("body").click(function(e) {
        var a = new Array("萌萌哒","帅气","阳光","八块腹肌","治愈系","无敌暖男","运动狂魔","软件开发","酷爱外语");
        var $i = $("<span/>").text(a[a_idx]);
//                    a_idx = (a_idx + 1) % a.length;
                    a_idx = Math.round(Math.random()*a.length);
        var x = e.pageX,
                y = e.pageY;
        $i.css({
            "z-index": 999999999999999999999999999999999999999999999999999999999999999999999,
            "top": y - 20,
            "left": x,
            "position": "absolute",
            "color":`rgba(${Math.random()*255},${Math.random()*255},${Math.random()*255},1)`
        });
        $("body").append($i);
        $i.animate({
            "top": y - 180,
            "opacity": 0
         },1500,function() {
             $i.remove();
         });
        });
});

代码很简单,就不逐行解释了,这里说几个注意的点就行:


  • 在使用的时候记着引入jquery源代码
  • 代码中监听的是body元素内的所有内容,所以在使用的时候读者务必在body标签内部添加些内容,这样才能保证结果的正确显示
<p>石璞东好帅</p>
<p>石璞东好帅</p>
<p>石璞东好帅</p>
<p>石璞东好帅</p>
<p>石璞东好帅</p>
<p>石璞东好帅</p>

   ok,这部分代码就不详讲了,如果有哪个小可爱还有不懂滴,欢迎小姐姐私信我哟,(男生就算了,这代码都看不懂,还好意思说自己是学前端的~)


   第二个问题,来咱们说下我网站心形效果的事:

首先贴出源代码:

! function(e, t, a) {
     //对当前页面由用户点击产生的心进行操作,若产生的心的透明度小于零了,则移除该元素,若不小于零,则该心继续向上移动,并慢慢放大
    function r() {
        for(var e = 0; e < n.length; e++) 
            n[e].alpha <= 0 ? (t.body.removeChild(n[e].el), n.splice(e, 1)) : (n[e].y--, n[e].scale += .004, 
            n[e].alpha -= .013, 
            n[e].el.style.cssText = "left:" + n[e].x + "px;top:" + n[e].y + "px;opacity:" + n[e].alpha + ";transform:scale(" + n[e].scale + "," + n[e].scale + ") rotate(45deg);background:" + n[e].color + ";z-index:99999");
        requestAnimationFrame(r)
    }
    //存放页面心的数组
    var n = [];
    //对于不同浏览器做兼容处理
    e.requestAnimationFrame =
        e.requestAnimationFrame || 
        e.webkitRequestAnimationFrame || 
        e.mozRequestAnimationFrame || 
        e.oRequestAnimationFrame || 
        e.msRequestAnimationFrame || 
        function(e) {
            setTimeout(e, 1e3 / 60)
    },
    //创建style标签并写入css样式
    function(e) {
        var a = t.createElement("style");
        a.type = "text/css";
        try {
            a.appendChild(t.createTextNode(e))
        } catch(t) {
            a.styleSheet.cssText = e
        }
        t.getElementsByTagName("head")[0].appendChild(a)
    }(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"),
    //将用户点击操作产生的心push进n数组之内
    function() {
        var a = "function" == typeof e.onclick && e.onclick;
        e.onclick = function(e) {
            a && a(),
            function(e) {
                var a = t.createElement("div");
                a.className = "heart", 
                n.push({
                    el: a,
                    x: e.clientX - 5,
                    y: e.clientY - 5,
                    scale: 1,
                    alpha: 1,
                    color: "rgb(" + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + ")"
                    }), 
                    t.body.appendChild(a)
                }(e)
            }
        }(), 
    r()
}(window, document);


几个注意点:


  • 自执行函数的几种写法:
  • (function{}())()
  • (function(){}())
  • !function(){}()
  • +function(){}()
  • -function(){}()
  • ~function(){}()


微信图片_20220610084319.jpg


  • 几个API

  • requestAnimationFrame : 接受一个回调函数作为参数,当浏览器下次要执行动画时会调用该函数执行动画
  • createTextNode : 接受字符串作为参数,并将其放入节点中


  • 源代码中是咋写的


  • 最外层是!function(e,t,a){/内层代码块/}(window,document)
  • 内层代码块中的部分通过,—逗号运算符,并列了四个函数,requestAnimationFrame,创建style标签并写入样式的函数,初始化并将产生的心push进数组的函数,r函数的调用.



微信图片_20220610084326.jpg


重点解释一下 :


1. function(){/*code*/}()
   function fn(){/*code*/}()
   以上两种写法并不是自调用函数的正确写法,而且会报错的呢~
2. var fn ='aaa',function(a){alert(a)}(1)
   YY想出来该行代码的执行结果应该是弹出1,但是毫无意外的又报错了~
3. fn = 'aaa',function(a){alert(a)}(1)/*弹出1*/
   fn = function(a){alert(a)}(1),function(b){alert(b)(2)/*先弹1在弹2*/
   function r (){alert(1)}
   fn = function(a){alert(a)}(2),r()
   /*先弹2在弹1*/


ok,事先准备工作就算做完了,来干正事:


首先,对内部代码做下说明,根据函数功能将其分为5部分:


  1. function r(){/code/} : 对当前页面由用户点击产生的心进行操作,若产生的心的透明度小于零了,则移除该元素,若不小于零,则该心继续向上移动,并慢慢放大
  2. e.requestAnimationFrame = /code/, : 对于不同浏览器做兼容处理
  3. e.requestAnimationFrame = function(e){/code/}() : 创建style标签并写入css样式
  4. e.requestAnimationFrame = function(){/code/}() : 初始化,并将用户点击操作产生的心push进n数组之内
  5. r() : 简单的函数调用


分别在如下图中位置打断点:


微信图片_20220610084331.png



   首先,里面是5个并列的函数,它们的执行效果等同于自执行函数的执行效果(但这不是自执行函数),其次onclick回调函数会监听用户的点击事件,当用户点击页面时,函数会进入39行的断点处,然后逐步执行并初始化页面中原始的心形,执行至51行,初始化完毕,后续执行r函数,根据当前的心形的透明度是否小于0决定该心形是否需要从当前页面移除.其实function r(){/code/}这个函数有一丝递归函数的意思:当第一次执行全部代码的时候,r函数会被初步调用,之后进入r函数内部逐行执行代码, 只要当前页面中有心形元素,即数组n.length>0,慢慢向上移动并且伴随着面积的增大,当且仅当该当前元素的透明度小于0时,才会从数组中移除该元素,此时跳出for循环,进而执行requestAnimationFrame函数,该函数将r函数作为参数,无限循环下去.


 ok,这部分代码的讲解就结束了,建议大家在看懂代码的基础上,推荐使用debug调试的方法,对这部分代码进行一下调试,在调试的过程中你会了解到:动态打断点、错误预估、判断函数的下步执行位置等知识点,这部分才是重点,由于该部分内容不好用语言描述,所以大家自行调试,若在调试的过程中遇到问题,欢迎contact我~

相关文章
|
13天前
|
监控 网络协议 Java
Tomcat源码解析】整体架构组成及核心组件
Tomcat,原名Catalina,是一款优雅轻盈的Web服务器,自4.x版本起扩展了JSP、EL等功能,超越了单纯的Servlet容器范畴。Servlet是Sun公司为Java编程Web应用制定的规范,Tomcat作为Servlet容器,负责构建Request与Response对象,并执行业务逻辑。
Tomcat源码解析】整体架构组成及核心组件
|
1天前
|
开发工具
Flutter-AnimatedWidget组件源码解析
Flutter-AnimatedWidget组件源码解析
|
20天前
|
测试技术 Python
python自动化测试中装饰器@ddt与@data源码深入解析
综上所述,使用 `@ddt`和 `@data`可以大大简化写作测试用例的过程,让我们能专注于测试逻辑的本身,而无需编写重复的测试方法。通过讲解了 `@ddt`和 `@data`源码的关键部分,我们可以更深入地理解其背后的工作原理。
18 1
|
1月前
|
开发者 Python
深入解析Python `httpx`源码,探索现代HTTP客户端的秘密!
深入解析Python `httpx`源码,探索现代HTTP客户端的秘密!
62 1
|
1月前
|
开发者 Python
深入解析Python `requests`库源码,揭开HTTP请求的神秘面纱!
深入解析Python `requests`库源码,揭开HTTP请求的神秘面纱!
108 1
|
26天前
|
算法 安全 Java
深入解析Java多线程:源码级别的分析与实践
深入解析Java多线程:源码级别的分析与实践
|
28天前
|
JavaScript 前端开发 定位技术
云解析地图作业问题之在搭建页面中简化数据筛选的过程如何解决
云解析地图作业问题之在搭建页面中简化数据筛选的过程如何解决
21 0
|
1月前
|
存储 NoSQL Redis
redis 6源码解析之 object
redis 6源码解析之 object
52 6
|
3月前
|
XML Java 数据格式
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
深度解析 Spring 源码:从 BeanDefinition 源码探索 Bean 的本质
76 3
|
2月前
|
负载均衡 Java Spring
@EnableFeignClients注解源码解析
@EnableFeignClients注解源码解析
56 14

热门文章

最新文章

推荐镜像

更多