对vue生命周期/钩子函数的理解

对于实现页面逻辑交互等效果,我们必须知晓 vue 的生命周期,才能愉快的玩耍,知道我们写的东西应该挂载到哪里,vue 官方给出的 api 讲解的那叫一个简单啊,如下:

所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对属性和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法(例如 created: () => this.fetchTodos())。这是因为箭头函数绑定了父上下文,因此 this 与你期待的 Vue 实例不同,this.fetchTodos 的行为未定义。

下面附加一张生命周期图示

)

1 DOCTYPE html>
2
3
4 title><br>5 <meta charset="utf-8"><br>6 <script type="text/javascript" src="https://cdn.jsdelivr.net/vue/2.1.3/vue.js">script><br>7 head><br>8 <body><br>9<br>10 <div id="app"><br>11 <p>{ { message }}p><br>12 div><br>13<br>14 <script type="text/javascript"><br>15 var app = new Vue({ 16 el: '#app', 17 data: { 18 message: "this is a test"<br>19 }, 20 beforeCreate: function () { 21 console.group('beforeCreate 创建前状态===============》'); 22 console.log("%c%s", "color:red", "el : " + this.$el); //undefined<br>23 console.log("%c%s", "color:red", "data : " + this.$data); //undefined<br>24 console.log("%c%s", "color:red", "message: " + this.message) 25 }, 26 created: function () { 27 console.group('created 创建完毕状态===============》'); 28 console.log("%c%s", "color:red", "el : " + this.$el); //undefined<br>29 console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化<br>30 console.log("%c%s", "color:red", "message: " + this.message); //已被初始化<br>31 }, 32 beforeMount: function () { 33 console.group('beforeMount 挂载前状态===============》'); 34 console.log("%c%s", "color:red", "el : " + (this.$el)); //已被初始化<br>35 console.log(this.$el); 36 console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化<br>37 console.log("%c%s", "color:red", "message: " + this.message); //已被初始化<br>38 }, 39 mounted: function () { 40 console.group('mounted 挂载结束状态===============》'); 41 console.log("%c%s", "color:red", "el : " + this.$el); //已被初始化<br>42 console.log(this.$el); 43 console.log("%c%s", "color:red", "data : " + this.$data); //已被初始化<br>44 console.log("%c%s", "color:red", "message: " + this.message); //已被初始化<br>45 }, 46 beforeUpdate: function () { 47 console.group('beforeUpdate 更新前状态===============》'); 48 console.log("%c%s", "color:red", "el : " + this.$el); 49 console.log(this.$el); 50 console.log("%c%s", "color:red", "data : " + this.$data); 51 console.log("%c%s", "color:red", "message: " + this.message); 52 }, 53 updated: function () { 54 console.group('updated 更新完成状态===============》'); 55 console.log("%c%s", "color:red", "el : " + this.$el); 56 console.log(this.$el); 57 console.log("%c%s", "color:red", "data : " + this.$data); 58 console.log("%c%s", "color:red", "message: " + this.message); 59 }, 60 beforeDestroy: function () { 61 console.group('beforeDestroy 销毁前状态===============》'); 62 console.log("%c%s", "color:red", "el : " + this.$el); 63 console.log(this.$el); 64 console.log("%c%s", "color:red", "data : " + this.$data); 65 console.log("%c%s", "color:red", "message: " + this.message); 66 }, 67 destroyed: function () { 68 console.group('destroyed 销毁完成状态===============》'); 69 console.log("%c%s", "color:red", "el : " + this.$el); 70 console.log(this.$el); 71 console.log("%c%s", "color:red", "data : " + this.$data); 72 console.log("%c%s", "color:red", "message: " + this.message) 73 } 74 }) 75 script><br>76 body><br>77 html></p> <p>生命周期</p> <ol> <li><a href="https://cn.vuejs.org/v2/api/#beforeCreate" target="_blank" rel="noopener">beforeCreate</a></li> <li><a href="https://cn.vuejs.org/v2/api/#created" target="_blank" rel="noopener">created</a></li> <li><a href="https://cn.vuejs.org/v2/api/#beforeMount" target="_blank" rel="noopener">beforeMount</a></li> <li><a href="https://cn.vuejs.org/v2/api/#mounted" target="_blank" rel="noopener">mounted</a></li> <li><a href="https://cn.vuejs.org/v2/api/#beforeUpdate" target="_blank" rel="noopener">beforeUpdate</a></li> <li><a href="https://cn.vuejs.org/v2/api/#updated" target="_blank" rel="noopener">updated</a></li> <li><a href="https://cn.vuejs.org/v2/api/#activated" target="_blank" rel="noopener">activated</a></li> <li><a href="https://cn.vuejs.org/v2/api/#deactivated" target="_blank" rel="noopener">deactivated</a></li> <li><a href="https://cn.vuejs.org/v2/api/#beforeDestroy" target="_blank" rel="noopener">beforeDestroy</a></li> <li><a href="https://cn.vuejs.org/v2/api/#destroyed" target="_blank" rel="noopener">destroyed</a></li> </ol> <h3 id="详解:"><a href="#详解:" class="headerlink" title="详解:"></a>详解:</h3><ol> <li><p><code>beforeCreate</code><br><strong>官方说明:</strong>在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。<br><strong>解释:</strong>这个时期,this 变量还不能使用,在 data 下的数据,和 methods 下的方法,watcher 中的事件都不能获得到;</p> <pre><code> beforeCreate() { console.log(this.page); // undefined console.log{this.showPage); // undefined }, data() { return { page: 123 } }, methods: { showPage() { console.log(this.page); } }</code></pre></li> <li><p><code>created</code><br><strong>官方说明:</strong>实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。<br><strong>解释说明:</strong> 这个时候可以操作 vue 实例中的数据和各种方法,但是还不能对"dom"节点进行操作;</p> <pre><code> created() { console.log(this.page); // 123 console.log{this.showPage); // ... $('select').select2(); // jQuery插件需要操作相关dom,不会起作用 }, data() { return { page: 123 } }, methods: { showPage() { console.log(this.page); } }</code></pre></li> <li><p><code>beforeMounte</code><br><strong>官方说明:</strong>在挂载开始之前被调用:相关的 render 函数首次被调用。</p> </li> <li><p><code>mounted</code><br><strong>官方说明:</strong><code>el</code> 被新创建的 <code>vm.$el</code> 替换,并挂载到实例上去之后调用该钩子。如果<code>root</code>实例挂载了一个文档内元素,当 <code>mounted</code> 被调用时 <code>vm.$el</code> 也在文档内。<br><strong>解释说明:</strong>挂载完毕,这时<code>dom</code>节点被渲染到文档内,一些需要<code>dom</code>的操作在此时才能正常进行</p> <pre><code> mounted() { $('select').select2(); // jQuery插件可以正常使用 },</code></pre></li> </ol> <p>这时初始化插件没有问题,插件能正常运行,但是这并不代表万事大吉;下面思考一个问题:</p> <p><img src="//upload-images.jianshu.io/upload_images/2480162-963129596d325d26.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="select2"></p> <p>select2</p> <p>图中的<code>select</code>的<code>option</code>都是通过异步请求得到的,然后通过<code>v-for</code>渲染进去,到此一切看起来很正常。<strong>还有一个需求</strong>是当页面刷新后要保留上次一查询的条件。我通过<code>vue-router</code>来给<code>select</code>指定一个默认选项;</p> <p>那么问题就来了,<code>option</code>的获得是一个异步请求,那这个请求完成的时刻和<code>mounted</code>的顺序是什么?如果<code>mounted</code>在请求成功之前执行,那将很遗憾——默认选项会设置失败</p> <p><img src="//upload-images.jianshu.io/upload_images/2480162-5f3d7b05331886c6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="option有默认效果的是130,select中的值还是保持全部"></p> <p>option 有默认效果的是 130,select 中的值还是保持全部</p> <p>什么时候执行<code>$('select').select2()</code>,是解决这个问题的关键。大家肯定猜到了,mounted 的确是在请求成功之前执行的,所以这时的办法就是将<code>$('select').select2()</code>的执行放到请求成功的回调里执行:</p> <pre><code> $.getJSON(urls.agentAndCity, {pageType: this.pageType}, (res) => { const a = this.agentList, d = res.data; a.id = d.orgIds; a.name = d.orgNames; a.city = d.cityMap; $('select').select2(); });</code></pre><p>本以为这样就完美解决了,但是发现还是会出现和上图一样的效果;如何是好?这时轮到<a href="https://cn.vuejs.org/v2/api/#vm-nextTick-callback" target="_blank" rel="noopener">vm.$nextTick</a>登场了:<br><strong>说明:</strong> 将回调延迟到下次 <code>DOM</code> 更新循环之后执行。在修改数据之后立即使用它,然后等待 <code>DOM</code> 更新。<br>官方示例代码:</p> <pre><code> new Vue({ // ... methods: { // ... example: function () { // 修改数据 this.message = 'changed' // DOM 还没有更新 this.$nextTick(function () { // DOM 现在更新了 // `this` 绑定到当前实例 this.doSomethingElse() }) } } })</code></pre><p>所以我的解决办法如下:</p> <pre><code>$.getJSON(urls.agentAndCity, {pageType: this.pageType}, (res) => { const a = this.agentList, d = res.data; a.id = d.orgIds; a.name = d.orgNames; a.city = d.cityMap; this.$nextTick(() => { $('select').select2(); }); });</code></pre><p>至此这个问题才算比较满意的解决</p> </div> <hr/> <div class="reprint" id="reprint-statement"> <div class="reprint__author"> <span class="reprint-meta" style="font-weight: bold;"> <i class="fas fa-user"> 文章作者: </i> </span> <span class="reprint-info"> <a href="http://jixioakang.com" rel="external nofollow noreferrer">xkloveme</a> </span> </div> <div class="reprint__type"> <span class="reprint-meta" style="font-weight: bold;"> <i class="fas fa-link"> 文章链接: </i> </span> <span class="reprint-info"> <a href="http://jixioakang.com/2017/08/26/2017-08-26-dui-vue-sheng-ming-zhou-qi-gou-zi-han-shu-de-li-jie/">http://jixioakang.com/2017/08/26/2017-08-26-dui-vue-sheng-ming-zhou-qi-gou-zi-han-shu-de-li-jie/</a> </span> </div> <div class="reprint__notice"> <span class="reprint-meta" style="font-weight: bold;"> <i class="fas fa-copyright"> 版权声明: </i> </span> <span class="reprint-info"> 本博客所有文章除特別声明外,均采用 <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a> 许可协议。转载请注明来源 <a href="http://jixioakang.com" target="_blank">xkloveme</a> ! </span> </div> </div> <script async defer> document.addEventListener("copy", function (e) { let toastHTML = '<span>复制成功,请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>'; M.toast({html: toastHTML}) }); function navToReprintStatement() { $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800); } </script> <div class="tag_share" style="display: block;"> <div class="post-meta__tag-list" style="display: inline-block;"> <div class="article-tag"> <a href="/tags/vue/"> <span class="chip bg-color">vue</span> </a> </div> </div> <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;"> <link rel="stylesheet" type="text/css" href="/libs/share/css/share.min.css"> <div id="article-share"> <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享!</p>"></div> <script src="/libs/share/js/social-share.min.js"></script> </div> </div> </div> <style> #reward { margin: 40px 0; text-align: center; } #reward .reward-link { font-size: 1.4rem; line-height: 38px; } #reward .btn-floating:hover { box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2), 0 5px 15px rgba(0, 0, 0, 0.2); } #rewardModal { width: 320px; } #rewardModal .reward-title { margin: 15px auto; padding-bottom: 5px; } #rewardModal .modal-content { padding: 10px; } #rewardModal .close { position: absolute; right: 15px; top: 15px; color: rgba(0, 0, 0, 0.5); font-size: 1.3rem; line-height: 20px; cursor: pointer; } #rewardModal .close:hover { color: #ef5350; transform: scale(1.3); -moz-transform: scale(1.3); -webkit-transform: scale(1.3); -o-transform: scale(1.3); } #rewardModal .reward-tabs { margin: 0 auto; width: 210px; } .reward-tabs .tabs { height: 38px; margin: 10px auto; padding-left: 0; } .reward-content ul { padding-left: 0 !important; } .reward-tabs .tabs .tab { height: 38px; line-height: 38px; } .reward-tabs .tab a { color: #fff; background-color: #ccc; } .reward-tabs .tab a:hover { background-color: #ccc; color: #fff; } .reward-tabs .wechat-tab .active { color: #fff !important; background-color: #22ab38 !important; } .reward-tabs .alipay-tab .active { color: #fff !important; background-color: #019fe8 !important; } .reward-tabs .reward-img { width: 210px; } </style> <div id="reward"> <a href="#rewardModal" class="reward-link modal-trigger btn-floating btn-medium waves-effect waves-light red" >赏</a > <!-- Modal Structure --> <div id="rewardModal" class="modal"> <div class="modal-content"> <a class="close modal-close"><i class="fas fa-times"></i></a> <h4 class="reward-title">你的赏识是我前进的动力</h4> <div class="reward-content"> <div class="reward-tabs"> <ul class="tabs row"> <li class="tab col s6 alipay-tab waves-effect waves-light"> <a href="#alipay">支付宝</a> </li> <li class="tab col s6 wechat-tab waves-effect waves-light"> <a href="#wechat">微 信</a> </li> </ul> <div id="alipay"> <img src="/medias/reward/alipay.jpg" class="reward-img" alt="支付宝打赏二维码" /> </div> <div id="wechat"> <img src="/medias/reward/wechat.png" class="reward-img" alt="微信打赏二维码" /> </div> </div> </div> </div> </div> </div> <script> $(function() { $(".tabs").tabs(); }); </script> </div> </div> <link rel="stylesheet" href="https://cdn.bootcss.com/gitalk/1.6.2/gitalk.min.css"> <link rel="stylesheet" href="/css/my-gitalk.css"> <div class="card gitalk-card" data-aos="fade-up"> <div class="comment_headling" style="font-size: 20px; font-weight: 700; position: relative; left: 20px; top: 15px; padding-bottom: 5px;"> <i class="fas fa-comments fa-fw" aria-hidden="true"></i> <span>评论</span> </div> <div id="gitalk-container" class="card-content"></div> </div> <script src="https://cdn.bootcss.com/gitalk/1.6.2/gitalk.min.js"></script> <script> let gitalk = new Gitalk({ clientID: 'f1e60c7afa53a51926b5', clientSecret: '2430231be04e68f6ba8ccf331c537cc19f50a0bd', repo: 'xkloveme.github.io', owner: 'xkloveme', admin: "xkloveme", id: '2017-08-26T06-30-00', distractionFreeMode: false // Facebook-like distraction free mode }); gitalk.render('gitalk-container'); </script> <article id="prenext-posts" class="prev-next articles"> <div class="row article-row"> <div class="article col s12 m6" data-aos="fade-up"> <div class="article-badge left-badge text-color"> <i class="fas fa-chevron-left"></i> 上一篇</div> <div class="card"> <a href="/2017/08/27/2017-08-27-jie-jue-dao-hang-xia-tu-pian-bu-neng-an-xu-jia-zai-de-wen-ti-jian-shao-dui-zi-yuan-qing-qiu-shu-liang/"> <div class="card-image"> <img src="https://picsum.photos/600/300" class="responsive-img" alt="解决导航下图片不能按需加载的问题减少对资源请求数量"> <span class="card-title">解决导航下图片不能按需加载的问题减少对资源请求数量</span> </div> </a> <div class="card-content article-content"> <div class="summary block-with-text"> 问题描述:在一个三段式的 navbar 中,各段下面有一个长图(类似这样的) 在优化之前需要加载三张大图这无疑增加了资源请求数量 因此,我想到了将图片转换为背景以此减少请求没想到方案是可行的,上代码 <mt-navbar </div> <div class="publish-info"> <span class="publish-date"> <i class="far fa-clock fa-fw icon-date"></i>2017-08-27 </span> <span class="publish-author"> <i class="fas fa-bookmark fa-fw icon-category"></i> <a href="/categories/%E5%89%8D%E7%AB%AF/" class="post-category"> 前端 </a> </span> </div> </div> <div class="card-action article-tags"> <a href="/tags/%E6%8A%80%E6%9C%AF/"> <span class="chip bg-color">技术</span> </a> </div> </div> </div> <div class="article col s12 m6" data-aos="fade-up"> <div class="article-badge right-badge text-color"> 下一篇 <i class="fas fa-chevron-right"></i> </div> <div class="card"> <a href="/2017/08/24/2017-08-24-vuex-kuang-jia-yuan-li-yu-yuan-ma-fen-xi/"> <div class="card-image"> <img src="https://picsum.photos/600/300" class="responsive-img" alt="Vuex框架原理与源码分析"> <span class="card-title">Vuex框架原理与源码分析</span> </div> </a> <div class="card-content article-content"> <div class="summary block-with-text"> Vuex 是一个专为 Vue 服务,用于管理页面数据状态、提供统一数据操作的生态系统。它集中于 MVC 模式中的 Model 层,规定所有的数据操作必须通过 action - mutation - state change 的流程来进行 </div> <div class="publish-info"> <span class="publish-date"> <i class="far fa-clock fa-fw icon-date"></i>2017-08-24 </span> <span class="publish-author"> <i class="fas fa-bookmark fa-fw icon-category"></i> <a href="/categories/%E5%89%8D%E7%AB%AF/" class="post-category"> 前端 </a> </span> </div> </div> <div class="card-action article-tags"> <a href="/tags/%E6%8A%80%E6%9C%AF/"> <span class="chip bg-color">技术</span> </a> <a href="/tags/vue/"> <span class="chip bg-color">vue</span> </a> </div> </div> </div> </div> </article> </div> <script> $('#articleContent').on('copy', function (e) { // IE8 or earlier browser is 'undefined' if (typeof window.getSelection === 'undefined') return; var selection = window.getSelection(); // if the selection is short let's not annoy our users. if (('' + selection).length < Number.parseInt('120')) { return; } // create a div outside of the visible area and fill it with the selected text. var bodyElement = document.getElementsByTagName('body')[0]; var newdiv = document.createElement('div'); newdiv.style.position = 'absolute'; newdiv.style.left = '-99999px'; bodyElement.appendChild(newdiv); newdiv.appendChild(selection.getRangeAt(0).cloneContents()); // we need a <pre> tag workaround. // otherwise the text inside "pre" loses all the line breaks! if (selection.getRangeAt(0).commonAncestorContainer.nodeName === 'PRE') { newdiv.innerHTML = "<pre>" + newdiv.innerHTML + "</pre>"; } var url = document.location.href; newdiv.innerHTML += '<br />' + '来源: 小康之家<br />' + '文章作者: xkloveme<br />' + '文章链接: <a href="' + url + '">' + url + '</a><br />' + '本文章著作权归作者所有,任何形式的转载都请注明出处。'; selection.selectAllChildren(newdiv); window.setTimeout(function () {bodyElement.removeChild(newdiv);}, 200); }); </script> <!-- 代码块功能依赖 --> <script type="text/javascript" src="/libs/codeBlock/codeBlockFuction.js"></script> <!-- 代码语言 --> <script type="text/javascript" src="/libs/codeBlock/codeLang.js"></script> <!-- 代码块复制 --> <script type="text/javascript" src="/libs/codeBlock/codeCopy.js"></script> <!-- 代码块收缩 --> <script type="text/javascript" src="/libs/codeBlock/codeShrink.js"></script> <!-- 代码块折行 --> <style type="text/css"> code[class*="language-"], pre[class*="language-"] { white-space: pre !important; } </style> </div> <div id="toc-aside" class="expanded col l3 hide-on-med-and-down"> <div class="toc-widget"> <div class="toc-title"><i class="far fa-list-alt"></i>  目录</div> <div id="toc-content"></div> </div> </div> </div> <!-- TOC 悬浮按钮. --> <div id="floating-toc-btn" class="hide-on-med-and-down"> <a class="btn-floating btn-large bg-color"> <i class="fas fa-list-ul"></i> </a> </div> <script src="https://cdn.bootcss.com/tocbot/4.10.0/tocbot.min.js"></script> <script> $(function () { tocbot.init({ tocSelector: '#toc-content', contentSelector: '#articleContent', headingsOffset: -($(window).height() * 0.4 - 45), // headingsOffset: -205, headingSelector: 'h2, h3, h4' }); // modify the toc link href to support Chinese. let i = 0; let tocHeading = 'toc-heading-'; $('#toc-content a').each(function () { $(this).attr('href', '#' + tocHeading + (++i)); }); // modify the heading title id to support Chinese. i = 0; $('#articleContent').children('h2, h3, h4').each(function () { $(this).attr('id', tocHeading + (++i)); }); // Set scroll toc fixed. let tocHeight = parseInt($(window).height() * 0.4 - 64); let $tocWidget = $('.toc-widget'); $(window).scroll(function () { let scroll = $(window).scrollTop(); /* add post toc fixed. */ if (scroll > tocHeight) { $tocWidget.addClass('toc-fixed'); } else { $tocWidget.removeClass('toc-fixed'); } }); /* 修复文章卡片 div 的宽度. */ let fixPostCardWidth = function (srcId, targetId) { let srcDiv = $('#' + srcId); if (srcDiv.length === 0) { return; } let w = srcDiv.width(); if (w >= 450) { w = w + 21; } else if (w >= 350 && w < 450) { w = w + 18; } else if (w >= 300 && w < 350) { w = w + 16; } else { w = w + 14; } $('#' + targetId).width(w); }; // 切换TOC目录展开收缩的相关操作. const expandedClass = 'expanded'; let $tocAside = $('#toc-aside'); let $mainContent = $('#main-content'); $('#floating-toc-btn .btn-floating').click(function () { if ($tocAside.hasClass(expandedClass)) { $tocAside.removeClass(expandedClass).hide(); $mainContent.removeClass('l9'); } else { $tocAside.addClass(expandedClass).show(); $mainContent.addClass('l9'); } fixPostCardWidth('artDetail', 'prenext-posts'); }); }); </script> </main> <footer class="page-footer bg-color"> <div class="container row center-align"> <div class="col s12 m8 l8 copy-right"> Copyright © <span id="year">年份</span> <a href="http://jixioakang.com" target="_blank">xkloveme</a> | Powered by <a href="https://hexo.io/" target="_blank">Hexo</a> <br />  <i class="fas fa-chart-area" ></i > 站点总字数: <span class="white-color" >141.7k</span > 字 <span id="busuanzi_container_site_pv"> | <i class="far fa-eye"></i> 总访问量: <span id="busuanzi_value_site_pv" class="white-color" ></span > 次 </span> <span id="busuanzi_container_site_uv"> | <i class="fas fa-users"></i> 总访问人数: <span id="busuanzi_value_site_uv" class="white-color" ></span > 人 </span> <br /> <span id="sitetime">载入运行时间...</span> <script> function siteTime() { window.setTimeout("siteTime()", 1000); var seconds = 1000; var minutes = seconds * 60; var hours = minutes * 60; var days = hours * 24; var years = days * 365; var today = new Date(); var startYear = "2017"; var startMonth = "3"; var startDate = "13"; var startHour = "0"; var startMinute = "0"; var startSecond = "0"; var todayYear = today.getFullYear(); var todayMonth = today.getMonth() + 1; var todayDate = today.getDate(); var todayHour = today.getHours(); var todayMinute = today.getMinutes(); var todaySecond = today.getSeconds(); var t1 = Date.UTC( startYear, startMonth, startDate, startHour, startMinute, startSecond ); var t2 = Date.UTC( todayYear, todayMonth, todayDate, todayHour, todayMinute, todaySecond ); var diff = t2 - t1; var diffYears = Math.floor(diff / years); var diffDays = Math.floor(diff / days - diffYears * 365); var diffHours = Math.floor( (diff - (diffYears * 365 + diffDays) * days) / hours ); var diffMinutes = Math.floor( (diff - (diffYears * 365 + diffDays) * days - diffHours * hours) / minutes ); var diffSeconds = Math.floor( (diff - (diffYears * 365 + diffDays) * days - diffHours * hours - diffMinutes * minutes) / seconds ); if (startYear == todayYear) { document.getElementById("year").innerHTML = todayYear; document.getElementById("sitetime").innerHTML = "本站已安全运行 " + diffDays + " 天 " + diffHours + " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒"; } else { document.getElementById("year").innerHTML = startYear + " - " + todayYear; document.getElementById("sitetime").innerHTML = "本站已安全运行 " + diffYears + " 年 " + diffDays + " 天 " + diffHours + " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒"; } } setInterval(siteTime, 1000); </script> <br /> </div> <div class="col s12 m4 l4 social-link social-statis"> <a href="https://github.com/xkloveme" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50"> <i class="fab fa-github"></i> </a> <a href="mailto:xkloveme@gmail.com" class="tooltipped" target="_blank" data-tooltip="邮件联系我" data-position="top" data-delay="50"> <i class="fas fa-envelope-open"></i> </a> <a href="https://twitter.com/xkloveme" class="tooltipped" target="_blank" data-tooltip="关注我的Twitter: https://twitter.com/xkloveme" data-position="top" data-delay="50"> <i class="fab fa-twitter"></i> </a> <a href="/atom.xml" class="tooltipped" target="_blank" data-tooltip="RSS 订阅" data-position="top" data-delay="50"> <i class="fas fa-rss"></i> </a> </div> </div> </footer> <div class="progress-bar"></div> <!-- 搜索遮罩框 --> <div id="searchModal" class="modal"> <div class="modal-content"> <div class="search-header"> <span class="title"><i class="fas fa-search"></i>  搜索</span> <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字" class="search-input"> </div> <div id="searchResult"></div> </div> </div> <script src="/js/search.js"></script> <script type="text/javascript"> $(function () { searchFunc("/" + "search.xml", 'searchInput', 'searchResult'); }); </script> <!-- 回到顶部按钮 --> <div id="backTop" class="top-scroll"> <a class="btn-floating btn-large waves-effect waves-light" href="#!"> <i class="fas fa-arrow-up"></i> </a> </div> <script src="https://cdn.bootcss.com/materialize/1.0.0/js/materialize.min.js"></script> <script src="https://cdn.bootcss.com/masonry/4.0.0/masonry.pkgd.min.js"></script> <script src="https://cdn.bootcss.com/aos/3.0.0-beta.6/aos.js"></script> <script src="https://cdn.bootcss.com/scrollprogress/3.0.2/scrollProgress.min.js"></script> <script src="https://cdn.bootcss.com/lightgallery/1.6.11/js/lightgallery-all.min.js"></script> <script src="/js/matery.js"></script> <!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=UA-102352377-2"></script> <script> window.dataLayer = window.dataLayer || []; function gtag() { dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'UA-102352377-2'); </script> <!-- Baidu Analytics --> <!-- Baidu Push --> <script> (function () { var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> <script src="/libs/others/clicklove.js" async="async"></script> <script async src="/libs/others/busuanzi.pure.mini.js"></script> <script type="text/javascript" src="/libs/background/ribbon-dynamic.js" async="async"></script> <script src="/libs/instantpage/instantpage.js" type="module"></script> </body> </html>