MENU

魔改 Mirages 主题

July 21, 2021 • Read: 929 • 默认分类

本站所用主题来源于Hran
本文主要搬运大佬LOGI的教程以及隔壁小胡的分享感恩!

1.首页大图内描述打字特效

如果是博主同款主题,在控制台->外观->网站公告 复制到首页大图内描述框内即可

<div id="chakhsu"></div> <script> var chakhsu = function (r) { function t() { return b[Math.floor(Math.random() * b.length)] } function e() { return String.fromCharCode(94 * Math.random() + 33) } function n(r) { for (var n = document.createDocumentFragment(), i = 0; r > i; i++) { var l = document.createElement("span"); l.textContent = e(), l.style.color = t(), n.appendChild(l) } return n } function i() { var t = o[c.skillI]; c.step ? c.step-- : (c.step = g, c.prefixP < l.length ? (c.prefixP >= 0 && (c.text += l[c.prefixP]), c.prefixP++) : "forward" === c.direction ? c.skillP < t.length ? (c.text += t[c.skillP], c.skillP++) : c.delay ? c.delay-- : (c.direction = "backward", c.delay = a) : c.skillP > 0 ? (c.text = c.text.slice(0, -1), c.skillP--) : (c.skillI = (c.skillI + 1) % o.length, c.direction = "forward")), r.textContent = c.text, r.appendChild(n(c.prefixP < l.length ? Math.min(s, s + c.prefixP) : Math.min(s, t.length - c.skillP))), setTimeout(i, d) } /*以下内容自定义修改*/ var l = "", o = ["当你凝视网页的时候,网页也在凝视着你!", ].map(function (r) { return r + "" }), a = 2, g = 1, s = 5, d = 75, b = ["rgb(110,64,170)", "rgb(150,61,179)", "rgb(191,60,175)", "rgb(228,65,157)", "rgb(254,75,131)", "rgb(255,94,99)", "rgb(255,120,71)", "rgb(251,150,51)", "rgb(226,183,47)", "rgb(198,214,60)", "rgb(175,240,91)", "rgb(127,246,88)", "rgb(82,246,103)", "rgb(48,239,130)", "rgb(29,223,163)", "rgb(26,199,194)", "rgb(35,171,216)", "rgb(54,140,225)", "rgb(76,110,219)", "rgb(96,84,200)"], c = {text: "", prefixP: -s, skillI: 0, skillP: 0, direction: "forward", delay: a, step: g}; i() }; chakhsu(document.getElementById('chakhsu')); </script> <div>

QQ截图20210721235301.png

中间的 var l = "" 与文字是可根据需求修改的参数喔!

展示

QQ截图20210721234117.png

2.炫彩鼠标特效

展示

shubiao.gif

此效果可以由HoerMouse插件实现
点此下载插件
将插件解压后的文件夹放入主题的/usr/plugins/目录,然后控制台启用插件并设置自己喜欢的特效就OK啦!

3.添加网站运行时间

引入 JS

将以下代码加入到 <head> 标签中。对于本主题,依次进入 控制台 - 外观 - 设置外观 - 主题自定义扩展,加入到 自定义 HTML 元素拓展 - 标签: head 头部 (meta 元素后),也可直接加入到主题对应的 header.php 中的 </head> 标签前。开始时间和中文提示可自定义。

<script>
    document.addEventListener('DOMContentLoaded', initLiveDay);
    function initLiveDay() {
        const birthTime = '2021/3/20 20:00:06';
        const template = (A, B, C, D) => `本站已风雨无阻地运行了 ${A}d ${B}h ${C}m ${D}s.`;

        /* 锚点开始 */
        const container = footer.querySelector('.container');
        const p = document.createElement('p');
        container.insertBefore(p, container.firstElementChild);
        /* 锚点结束*/

        const msoad = 24 * 60 * 60 * 1000;
        const warp = n => n > 9 ? n : '0' + n;
        const toInt = n => warp(Math.floor(n));
        setInterval(() => {
            const lived = new Date() - new Date(birthTime);
            const days = lived / msoad;
            const intDays = toInt(days);
            const hours = (days - intDays) * 24;
            const intHours = toInt(hours);
            const minutes = (hours - intHours) * 60;
            const intMinutes = toInt(minutes);
            const seconds = (minutes - intMinutes) * 60;
            const intSeconds = toInt(seconds);
            p.innerHTML = template(intDays, intHours, intMinutes, intSeconds);
        }, 1000);
    }
</script>

4.为Typecho评论框加入七彩打字动画

最终效果

dasjaBzVXaK.gif

使用步骤

对于 本主题,依次进入 控制台 - 外观 - 设置外观 - 主题自定义扩展,将以下代码加入到 自定义 HTML 元素拓展 - 在 body 标签结束前。其他主题,加入到主题对应的 footer.php 中 </body> 标签结束前。

<script>
(function webpackUniversalModuleDefinition(a,b){if(typeof exports==="object"&&typeof module==="object"){module.exports=b()}else{if(typeof define==="function"&&define.amd){define([],b)}else{if(typeof exports==="object"){exports["POWERMODE"]=b()}else{a["POWERMODE"]=b()}}}})(this,function(){return(function(a){var b={};function c(e){if(b[e]){return b[e].exports}var d=b[e]={exports:{},id:e,loaded:false};a[e].call(d.exports,d,d.exports,c);d.loaded=true;return d.exports}c.m=a;c.c=b;c.p="";return c(0)})([function(c,g,b){var d=document.createElement("canvas");d.width=window.innerWidth;d.height=window.innerHeight;d.style.cssText="position:fixed;top:0;left:0;pointer-events:none;z-index:999999";window.addEventListener("resize",function(){d.width=window.innerWidth;d.height=window.innerHeight});document.body.appendChild(d);var a=d.getContext("2d");var n=[];var j=0;var k=120;var f=k;var p=false;o.shake=true;function l(r,q){return Math.random()*(q-r)+r}function m(r){if(o.colorful){var q=l(0,360);return"hsla("+l(q-10,q+10)+", 100%, "+l(50,80)+"%, "+1+")"}else{return window.getComputedStyle(r).color}}function e(){var t=document.activeElement;var v;if(t.tagName==="TEXTAREA"||(t.tagName==="INPUT"&&t.getAttribute("type")==="text")){var u=b(1)(t,t.selectionStart);v=t.getBoundingClientRect();return{x:u.left+v.left,y:u.top+v.top,color:m(t)}}var s=window.getSelection();if(s.rangeCount){var q=s.getRangeAt(0);var r=q.startContainer;if(r.nodeType===document.TEXT_NODE){r=r.parentNode}v=q.getBoundingClientRect();return{x:v.left,y:v.top,color:m(r)}}return{x:0,y:0,color:"transparent"}}function h(q,s,r){return{x:q,y:s,alpha:1,color:r,velocity:{x:-1+Math.random()*2,y:-3.5+Math.random()*2}}}function o(){var t=e();var s=5+Math.round(Math.random()*10);while(s--){n[j]=h(t.x,t.y,t.color);j=(j+1)%500}f=k;if(!p){requestAnimationFrame(i)}if(o.shake){var r=1+2*Math.random();var q=r*(Math.random()>0.5?-1:1);var u=r*(Math.random()>0.5?-1:1);document.body.style.marginLeft=q+"px";document.body.style.marginTop=u+"px";setTimeout(function(){document.body.style.marginLeft="";document.body.style.marginTop=""},75)}}o.colorful=false;function i(){if(f>0){requestAnimationFrame(i);f--;p=true}else{p=false}a.clearRect(0,0,d.width,d.height);for(var q=0;q<n.length;++q){var r=n[q];if(r.alpha<=0.1){continue}r.velocity.y+=0.075;r.x+=r.velocity.x;r.y+=r.velocity.y;r.alpha*=0.96;a.globalAlpha=r.alpha;a.fillStyle=r.color;a.fillRect(Math.round(r.x-1.5),Math.round(r.y-1.5),3,3)}}requestAnimationFrame(i);c.exports=o},function(b,a){(function(){var d=["direction","boxSizing","width","height","overflowX","overflowY","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderStyle","paddingTop","paddingRight","paddingBottom","paddingLeft","fontStyle","fontVariant","fontWeight","fontStretch","fontSize","fontSizeAdjust","lineHeight","fontFamily","textAlign","textTransform","textIndent","textDecoration","letterSpacing","wordSpacing","tabSize","MozTabSize"];var e=window.mozInnerScreenX!=null;function c(k,l,o){var h=o&&o.debug||false;if(h){var i=document.querySelector("#input-textarea-caret-position-mirror-div");if(i){i.parentNode.removeChild(i)}}var f=document.createElement("div");f.id="input-textarea-caret-position-mirror-div";document.body.appendChild(f);var g=f.style;var j=window.getComputedStyle?getComputedStyle(k):k.currentStyle;g.whiteSpace="pre-wrap";if(k.nodeName!=="INPUT"){g.wordWrap="break-word"}g.position="absolute";if(!h){g.visibility="hidden"}d.forEach(function(p){g[p]=j[p]});if(e){if(k.scrollHeight>parseInt(j.height)){g.overflowY="scroll"}}else{g.overflow="hidden"}f.textContent=k.value.substring(0,l);if(k.nodeName==="INPUT"){f.textContent=f.textContent.replace(/\s/g,"\u00a0")}var n=document.createElement("span");n.textContent=k.value.substring(l)||".";f.appendChild(n);var m={top:n.offsetTop+parseInt(j["borderTopWidth"]),left:n.offsetLeft+parseInt(j["borderLeftWidth"])};if(h){n.style.backgroundColor="#aaa"}else{document.body.removeChild(f)}return m}if(typeof b!="undefined"&&typeof b.exports!="undefined"){b.exports=c}else{window.getCaretCoordinates=c}}())}])});
POWERMODE.colorful=true;POWERMODE.shake=false;document.body.addEventListener("input",POWERMODE);
</script>

5.为Typecho的Code Block添加Copy按钮

之前为了隐藏无意义内容写了 Typecho 简单实现点击复制,方式是创建隐藏内容的复制按钮。今天无意间看到某大佬的 JS 代码块复制按钮,发现也是我需要的,于是把它移植到了 Typecho 上,下面就介绍 Mirages 主题的使用步骤,其他主题改改选择器名称就行了。

引入 JS

将以下代码添加到主题 header.php 中的 </head> 标签前,或前往 控制台 - 设置外观 - 主题自定义扩展,将它添加到 自定义 HTML 元素拓展 - 标签: head 头部 (meta 元素后)。

<script>
    // 在代码块右上角添加复制按钮
    document.addEventListener('DOMContentLoaded', initCodeCopyButton);
    function initCodeCopyButton() {
        function initCSS(callback) {
            const css = `
                .btn-code-copy {
                    position: absolute;
                    line-height: .6em;
                    top: .2em;
                    right: .2em;
                    color: rgb(87, 87, 87);
                }
                .btn-code-copy:hover {
                    color: rgb(145, 145, 145);
                    cursor: pointer;
                }
                `;
            const styleId = btoa('btn-code-copy').replace(/[=+\/]/g, '');
            const head = document.getElementsByTagName('head')[0];
            if (!head.querySelector('#' + styleId)) {
                const style = document.createElement('style');
                style.id = styleId;
                if (style.styleSheet) {
                    style.styleSheet.cssText = css;
                } else {
                    style.appendChild(document.createTextNode(css));
                }
                head.appendChild(style);
            }
            callback();
        };
        function copyTextContent(source) {
            let result = false;
            const target = document.createElement('pre');
            target.style.opacity = '0';
            target.textContent = source.textContent;
            document.body.appendChild(target);
            try {
                const range = document.createRange();
                range.selectNode(target);
                window.getSelection().removeAllRanges();
                window.getSelection().addRange(range);
                document.execCommand('copy');
                window.getSelection().removeAllRanges();
                result = true;
            } catch (e) { console.log('copy failed.'); }
            document.body.removeChild(target);
            return result;
        };
        function initButton(pre) {
            const code = pre.querySelector('code');
            if (code) {
                const preParent = pre.parentElement;
                const newPreParent = document.createElement('div');
                newPreParent.style = 'position: relative';
                preParent.insertBefore(newPreParent, pre);
                const copyBtn = document.createElement('div');
                copyBtn.innerHTML = 'copy';
                copyBtn.className = 'btn-code-copy';
                copyBtn.addEventListener('click', () => {
                    copyBtn.innerHTML = copyTextContent(code) ? 'success' : 'failure';
                    setTimeout(() => copyBtn.innerHTML = 'copy', 250);
                });
                newPreParent.appendChild(copyBtn);
                newPreParent.appendChild(pre);
            }
        };
        const pres = document.querySelectorAll('pre');
        if (pres.length !== 0) {
            initCSS(() => pres.forEach(pre => initButton(pre)));
        }
    };
</script>

如果你开启了 PJAX,则需单独加入回调函数。对于本主题,依次进入 控制台 - 外观 - 设置外观 - PJAX(BETA) - PJAX RELOAD,将 initCodeCopyButton(); 添加进入即可。

6.Typecho 简单实现点击复制

在文章中插入大量无意义内容一不美观,二不便复制,不如使用 js 创建隐藏内容的复制按钮吧。

引入 JS

依次进入 控制台 - 外观 - 设置外观 - 主题自定义扩展,将以下代码加入到 自定义 HTML 元素拓展 - 标签: head 头部 (meta 元素后),也可直接加入到主题对应的 header.php 中的 </head> 标签前。

<script>
    // 创建隐藏内容的复制按钮
    document.addEventListener('DOMContentLoaded', initCopyButton);
    function initCopyButton() {
        const util = {
            newButton: function (cp) {
                cp.style.display = '0';
                let text = cp.getAttribute('text');
                text = text[0] === '\n' ? text.slice(1) : text;
                const button = document.createElement('a');
                button.href = '#'
                button.innerHTML = cp.getAttribute('name');
                button.className = 'btn btn-primary';
                button.onclick = () => {
                    const originName = button.innerHTML;
                    const actionResult = this.copy(text) ? '成功' : '失败';
                    button.innerHTML = '复制' + actionResult;
                    setTimeout(() => button.innerHTML = originName, 250);
                    return false;
                };
                cp.parentNode.insertBefore(button, cp);
            },
            copy: function (text) {
                let result = false;
                const target = document.createElement('pre');
                target.style.opacity = '0';
                target.textContent = text;
                document.body.appendChild(target);
                try {
                    const range = document.createRange();
                    range.selectNode(target);
                    window.getSelection().removeAllRanges();
                    window.getSelection().addRange(range);
                    document.execCommand('copy');
                    window.getSelection().removeAllRanges();
                    result = true;
                } catch (e) {
                    console.log('copy failed.');
                }
                document.body.removeChild(target);
                return result;
            }
        };
        document.querySelectorAll('cp').forEach(cp => util.newButton(cp));
    }
</script>

如果你开启了 PJAX,可能需要单独加入回调函数。对于本主题,依次进入 控制台 - 外观 - 设置外观 - PJAX(BETA) - PJAX RELOAD,将 initCopyButton(); 添加进入即可。

添加按钮

以 html 形式将以下内容写入文章中,即可创建复制按钮。

    !!!
    <cp name="复制静夜思" text="
           静夜思
    床前明月光,疑是地上霜。
    举头望明月,低头思故乡。
    "></cp>
    !!!

7.主题相邻文章默认头图去重

代码逻辑在/path/to/typecho/usr/themes/Mirages/lib/Content.php文件的loadDefaultThumbnailForArticle 函数:

public static function loadDefaultThumbnailForArticle($cid) {
    $defaultThumbs = self::exportThumbnails();
    $length = count($defaultThumbs);
    if ($length > 0) {
        $index = abs(intval($cid)) % count($length);
        $thumb = $defaultThumbs[$index];
    } else {
        $thumb = NULL;
    }
    return $thumb;
}

可以看到,作者根据文章 cid 对图片数量取余选取图片。尽管 cid 不同,运算后的结果也可能相同,这就可能导致上述问题。

简单起见,我直接让静态变量每次加 1,更改后的代码如下:

private static $defaultThumbs;
private static $defaultThumbsLength;
private static $nextThumbnailIndex; 

public static function loadDefaultThumbnailForArticle($cid) {
    if (self::$defaultThumbs == NULL) {
        // 这些变量存活于当前页
        self::$defaultThumbs = self::exportThumbnails();
        self::$defaultThumbsLength = count(self::$defaultThumbs);
        self::$nextThumbnailIndex = rand(0, abs(self::$defaultThumbsLength - 1));
    }
    if (self::$defaultThumbsLength > 0) {
        $index = self::$nextThumbnailIndex++ % self::$defaultThumbsLength;
        $thumb = self::$defaultThumbs[$index];
    } else {
        $thumb = NULL;
    }
    return $thumb;
}

文章默认图片的添加位置为 控制台 - 外观 - 设置外观 - 配图和图片管理 - 卡片式文章列表的默认背景图列表。现在刷新下主页,感觉稍微好了一点。

8.在文章中插入视频

引入 JS

对于 本主题,依次进入 控制台 - 外观 - 设置外观 - 主题自定义扩展,将代码加入到 自定义 HTML 元素拓展 - 标签: head 头部 (meta 元素后)。其他主题,加入到主题对应的 header.php 中的 </head> 标签前。

<script>
    // DPlayer API
    document.addEventListener('DOMContentLoaded', initDplayer);
    function initDplayer() {
        const common = {
            loadResource: function (id, resource, type, callback) {
                let loaded = document.head.querySelector('#' + id);
                if (loaded) {
                    callback();
                    return;
                }
                const element = document.createElement(type);
                element.onload = element.onreadystatechange = () => {
                    if (!loaded && (!element.readyState || /loaded|complete/.test(element.readyState))) {
                        element.onload = element.onreadystatechange = null;
                        loaded = true;
                        callback();
                    }
                }
                if (type === 'link') {
                    element.rel = 'stylesheet';
                    element.href = resource;
                } else {
                    element.src = resource;
                }
                element.id = id;
                document.getElementsByTagName('head')[0].appendChild(element);
            },
            loadResources: function (callback) {
                const cdn = '//s0.pstatp.com/cdn/expire-1-M';
                const resources = [
                    '/dplayer/1.25.0/DPlayer.min.css',
                    '/dplayer/1.25.0/DPlayer.min.js',
                    '/hls.js/0.12.4/hls.light.min.js',
                    '/flv.js/1.5.0/flv.min.js'
                ];
                let unloadedResourceCount = resources.length;
                resources.forEach(resource => {
                    this.loadResource(btoa(resource).replace(/[=+\/]/g, ''), cdn + resource,
                        ({
                            'css': 'link',
                            'js': 'script'
                        })[resource.split('.').pop()],
                        () => --unloadedResourceCount ? null : callback()
                    );
                });
            },
            createDplayers: function (sources, callback) {
                for (let i = 0; i < sources.length; i++) {
                    const child = document.createElement('div');
                    const src = sources[i].getAttribute('src');
                    sources[i].parentNode.insertBefore(child, sources[i]);
                    sources[i].style.display = 'none';
                    const type = src.split('.').pop();
                    const option = { url: src };
                    type === 'flv' ? option.type = type : null;
                    const dplayer = new DPlayer({ container: child, preload: 'none', autoplay: false, screenshot: false, video: option });
                }
                if (typeof callback === 'function') callback();
            }
        };
        const mirages = {
            isMirages: function () { return window.Mirages || false },
            fixVideoSize: function (length) {
                let outerTimer = false;
                const outerInterval = setInterval(() => {
                    if (outerTimer) return;
                    const videos = document.getElementsByTagName('video');
                    if (videos.length === length) {
                        const dplayerWraps = document.querySelectorAll('.dplayer-video-wrap');
                        for (let i = 0; i < length; i++) {
                            const videoContainers = dplayerWraps[i].querySelectorAll('.video-container.video-4-3');
                            if (videoContainers.length) {
                                videoContainers[0].style = 'position: initial;';
                                videoContainers[0].className = 'video-container video-16-9';
                                console.log('video-4-3 fixed.');
                            } else {
                                const videoContainer = document.createElement('div');
                                videoContainer.style = 'position: initial;';
                                videoContainer.className = 'video-container video-16-9';
                                videoContainer.appendChild(videos[i]);
                                dplayerWraps[i].appendChild(videoContainer);
                                console.log('video-16-9 inserted.');
                                const targetNode = videoContainer;
                                const config = { childList: true };
                                const callback = (mutationsList, observer) => {
                                    const newVideoContainers = videoContainer.querySelectorAll(
                                        '.video-container.video-4-3');
                                    if (newVideoContainers.length) {
                                        newVideoContainers[0].className = '';
                                        console.log('auto inserted video-4-3 fixed.');
                                        observer.disconnect();
                                    }
                                };
                                const observer = new MutationObserver(callback);
                                observer.observe(targetNode, config);
                                setTimeout(() => observer.disconnect(), 1000 * 120);
                            }
                        }
                        outerTimer = true;
                        clearInterval(outerInterval);
                    }
                }, 500);
            }
        };
        const dps = document.getElementsByTagName('dp');
        if (dps.length !== 0) {
            common.loadResources(() => common.createDplayers(dps, () => {
                // 修正 Mirages 视频比例错误
                mirages.isMirages() ? mirages.fixVideoSize(dps.length) : null;
            }));
        }
    };
</script>

如果你开启了 PJAX,可能需要单独加入回调函数。对于本主题,依次进入 控制台 - 外观 - 设置外观 - PJAX(BETA) - PJAX RELOAD,将 initDplayer(); 添加进入即可。

添加播放器

在文章所需位置以 html 形式插入代码,即可添加播放器,支持 m3u8、mp4,flv 和 mkv 格式,不过编码必须是 H.264 AAC。

    !!!
    <dp src="demo.mp4"></dp>
    !!!

9.博客评论显示 UserAgent (UA)

本功能可替代 UserAgent 插件,更美观、简洁且好看

引入 CSS

将下面的样式表外链加入到 /usr/themes/Mirages/component/header.php 的 head 部分,当然也可通过主题设置界面添加。

<link rel="stylesheet" href="//code.bdstatic.com/npm/logicdn@1.0.0/logi.im/usr/themes/Mirages/usr/logi.css" />

引入 PHP

将以下代码加入到 /usr/themes/Mirages/function.php 末尾。

// 获取浏览器信息
function getBrowser($agent)
{
    if (preg_match('/MSIE\s([^\s|;]+)/i', $agent, $regs)) {
        $outputer = '<i class="ua-icon icon-ie"></i>&nbsp;&nbsp;Internet Explore';
    } else if (preg_match('/FireFox\/([^\s]+)/i', $agent, $regs)) {
      $str1 = explode('Firefox/', $regs[0]);
$FireFox_vern = explode('.', $str1[1]);
        $outputer = '<i class="ua-icon icon-firefox"></i>&nbsp;&nbsp;FireFox';
    } else if (preg_match('/Maxthon([\d]*)\/([^\s]+)/i', $agent, $regs)) {
      $str1 = explode('Maxthon/', $agent);
$Maxthon_vern = explode('.', $str1[1]);
        $outputer = '<i class="ua-icon icon-edge"></i>&nbsp;&nbsp;MicroSoft Edge';
    } else if (preg_match('#360([a-zA-Z0-9.]+)#i', $agent, $regs)) {
$outputer = '<i class="ua-icon icon-360"></i>&nbsp;&nbsp;360极速浏览器';
    } else if (preg_match('/Edge([\d]*)\/([^\s]+)/i', $agent, $regs)) {
        $str1 = explode('Edge/', $regs[0]);
$Edge_vern = explode('.', $str1[1]);
        $outputer = '<i class="ua-icon icon-edge"></i>&nbsp;&nbsp;MicroSoft Edge';
    } else if (preg_match('/UC/i', $agent)) {
              $str1 = explode('rowser/',  $agent);
$UCBrowser_vern = explode('.', $str1[1]);
        $outputer = '<i class="ua-icon icon-uc"></i>&nbsp;&nbsp;UC浏览器';
    }  else if (preg_match('/QQ/i', $agent, $regs)||preg_match('/QQBrowser\/([^\s]+)/i', $agent, $regs)) {
                  $str1 = explode('rowser/',  $agent);
$QQ_vern = explode('.', $str1[1]);
        $outputer = '<i class= "ua-icon icon-qq"></i>&nbsp;&nbsp;QQ浏览器';
    } else if (preg_match('/UBrowser/i', $agent, $regs)) {
              $str1 = explode('rowser/',  $agent);
$UCBrowser_vern = explode('.', $str1[1]);
        $outputer = '<i class="ua-icon icon-uc"></i>&nbsp;&nbsp;UC浏览器';
    }  else if (preg_match('/Opera[\s|\/]([^\s]+)/i', $agent, $regs)) {
        $outputer = '<i class= "ua-icon icon-opera"></i>&nbsp;&nbsp;Opera';
    } else if (preg_match('/Chrome([\d]*)\/([^\s]+)/i', $agent, $regs)) {
$str1 = explode('Chrome/', $agent);
$chrome_vern = explode('.', $str1[1]);
        $outputer = '<i class="ua-icon icon-chrome"></i>&nbsp;&nbsp;Google Chrome';
    } else if (preg_match('/safari\/([^\s]+)/i', $agent, $regs)) {
         $str1 = explode('Version/',  $agent);
$safari_vern = explode('.', $str1[1]);
        $outputer = '<i class="ua-icon icon-safari"></i>&nbsp;&nbsp;Safari';
    } else{
        $outputer = '<i class="ua-icon icon-chrome"></i>&nbsp;&nbsp;Google Chrome';
    }
    echo $outputer;
}
// 获取操作系统信息
function getOs($agent)
{
    $os = false;
 
    if (preg_match('/win/i', $agent)) {
        if (preg_match('/nt 6.0/i', $agent)) {
            $os = '&nbsp;&nbsp;<i class= "ua-icon icon-win1"></i>&nbsp;&nbsp;Windows Vista&nbsp;/&nbsp;';
        } else if (preg_match('/nt 6.1/i', $agent)) {
            $os = '&nbsp;&nbsp;<i class= "ua-icon icon-win1"></i>&nbsp;&nbsp;Windows 7&nbsp;/&nbsp;';
        } else if (preg_match('/nt 6.2/i', $agent)) {
            $os = '&nbsp;&nbsp;<i class="ua-icon icon-win2"></i>&nbsp;&nbsp;Windows 8&nbsp;/&nbsp;';
        } else if(preg_match('/nt 6.3/i', $agent)) {
            $os = '&nbsp;&nbsp;<i class= "ua-icon icon-win2"></i>&nbsp;&nbsp;Windows 8.1&nbsp;/&nbsp;';
        } else if(preg_match('/nt 5.1/i', $agent)) {
            $os = '&nbsp;&nbsp;<i class="ua-icon icon-win1"></i>&nbsp;&nbsp;Windows XP&nbsp;/&nbsp;';
        } else if (preg_match('/nt 10.0/i', $agent)) {
            $os = '&nbsp;&nbsp;<i class="ua-icon icon-win2"></i>&nbsp;&nbsp;Windows 10&nbsp;/&nbsp;';
        } else{
            $os = '&nbsp;&nbsp;<i class="ua-icon icon-win2"></i>&nbsp;&nbsp;Windows X64&nbsp;/&nbsp;';
        }
    } else if (preg_match('/android/i', $agent)) {
    if (preg_match('/android 9/i', $agent)) {
            $os = '&nbsp;&nbsp;<i class="ua-icon icon-android"></i>&nbsp;&nbsp;Android Pie&nbsp;/&nbsp;';
        }
    else if (preg_match('/android 8/i', $agent)) {
            $os = '&nbsp;&nbsp;<i class="ua-icon icon-android"></i>&nbsp;&nbsp;Android Oreo&nbsp;/&nbsp;';
        }
    else{
            $os = '&nbsp;&nbsp;<i class="ua-icon icon-android"></i>&nbsp;&nbsp;Android&nbsp;/&nbsp;';
    }
    }
    else if (preg_match('/ubuntu/i', $agent)) {
        $os = '&nbsp;&nbsp;<i class="ua-icon icon-ubuntu"></i>&nbsp;&nbsp;Ubuntu&nbsp;/&nbsp;';
    } else if (preg_match('/linux/i', $agent)) {
        $os = '&nbsp;&nbsp;<i class= "ua-icon icon-linux"></i>&nbsp;&nbsp;Linux&nbsp;/&nbsp;';
    } else if (preg_match('/iPhone/i', $agent)) {
        $os = '&nbsp;&nbsp;<i class="ua-icon icon-apple"></i>&nbsp;&nbsp;iPhone&nbsp;/&nbsp;';
    } else if (preg_match('/mac/i', $agent)) {
        $os = '&nbsp;&nbsp;<i class="ua-icon icon-mac"></i>&nbsp;&nbsp;MacOS&nbsp;/&nbsp;';
    }else if (preg_match('/fusion/i', $agent)) {
        $os = '&nbsp;&nbsp;<i class="ua-icon icon-android"></i>&nbsp;&nbsp;Android&nbsp;/&nbsp;';
    } else {
        $os = '&nbsp;&nbsp;<i class="ua-icon icon-linux"></i>&nbsp;&nbsp;Linux&nbsp;/&nbsp;';
    }
    echo $os;
}

引入 HTML

将以下代码添加到 /usr/themes/Mirages/lib/comments.php 中 122 行所在的 div 中。

<span class="comment-ua">
    <?php getOs($this->agent); ?>
    <?php getBrowser($this->agent); ?>
</span>

10.SEO插件

Typecho-AMP-MIP

自动生成 Google AMP百度MIP 页面
生成 AMP / MIP 的站点地图,方便提交
后台批量提交 AMP/MIP 网址到百度,可选手动或自动

BaiduSubmit

生成适用于百度的站点地图,并显示搜索引擎请求情况
后台批量提交批量网址到百度,可选手动或自动

ShortLinks

把博客中的外部链接转换为网站内链,据说有利于搜索引擎收录
具体可以看下篇Typecho 开启外链转内链

11.Typecho 开启外链转内链

把博客中的外部链接转换为网站内链,据说有利于搜索引擎收录。

食用方法

下载地址
https://github.com/benzBrake/ShortLinks/releases
将下载解压好的文件夹放到 Plugins 目录(注意:文件夹名必须是ShortLinks)

启用插件

在插件设置中外链转内链转换评论者链接都要开启 > 跳转页面开关开启(不开启则不显示跳转动画)> 跳转延时填 2 秒 ==> 保存设置。

修复冲突

实测插件与本主题冲突,需做如下修改,当然若链接可正常转换则无需操作。打开Typecho根目录/usr/plugins/ShortLinks/Plugin.php,分别搜索如下内容并做相应修改,最后禁用再启用插件
冲突1
搜索

Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx

更改为

Typecho_Plugin::factory('Mirages_Plugin')->contentEx

冲突2
搜索

Typecho_Plugin::factory('Widget_Abstract_Contents')->excerptEx

更改为

Typecho_Plugin::factory('Mirages_Plugin')->excerptEx

修改模板

左岸大佬为项目提供了四套跳转模板,将喜欢的模板重命名为 go.html 即可食用,效果如下。

新页打开

插件设置里有新标签页打开文章外链的选项,实测评论区并不可以,临时方法是打个 JS 补丁。将以下代码加入到<head>标签中。对于本主题,依次进入控制台-外观-设置外观-主题自定义扩展,将代码加入到自定义HTML元素拓展-标签:head 头部(meta 元素后),也可直接加入到主题对应的header.php中的</head>标签前。

<script>
    // 评论区外链在新窗口打开
    document.addEventListener('DOMContentLoaded', initOuterLinkInComment);
    function initOuterLinkInComment() {
        document.querySelectorAll('.comment-list a[href*="/go/"]').forEach(a => a.target = '_blank');
    }
</script>

如果你开启了PJAX,可能需要单独加入回调函数。对于本主题,依次进入控制台-外观-设置外观-PJAX(BETA)-PJAX RELOAD,将initOuterLinkInComment();添加进入即可。

12. Mirages 主题自定义公告样式

效果展示

QQ截图20210725213007.png

使用步骤

将以下代码加入到<head>标签中。对于本主题,依次进入控制台 - 外观 - 设置外观 - 主题自定义扩展,将代码加入到自定义HTML元素拓展 - 标签: head 头部 (meta 元素后),也可直接加入到主题对应的header.php中的</head>标签前。

<script>
    // 自定义公告显示
    document.addEventListener('DOMContentLoaded', initNotice2);
    document.head.append(document.createRange().createContextualFragment(
        `<style> 
            .blog-notice { 
                display: none; 
            }
            @media screen and (max-device-width: 767px) {
                .el-notification.right {
                    margin: 0 auto;
                    left: 0;
                    right: 0 !important;
                }
            }
        </style>`
    ).firstElementChild);
    function initNotice2() {
        const common = {
            loadResource: function (id, resource, type) {
                return new Promise(function (resolve, reject) {
                    let loaded = document.head.querySelector('#' + id);
                    if (loaded) {
                        resolve('success: ' + resource);
                        return;
                    }
                    const element = document.createElement(type);
                    element.onload = element.onreadystatechange = () => {
                        if (!loaded && (!element.readyState || /loaded|complete/.test(element.readyState))) {
                            element.onload = element.onreadystatechange = null;
                            loaded = true;
                            resolve('success: ' + resource);
                        }
                    }
                    element.onerror = function () {
                        reject(Error(resource + ' load error!'));
                    };
                    if (type === 'link') {
                        element.rel = 'stylesheet';
                        element.href = resource;
                    } else {
                        element.src = resource;
                    }
                    element.id = id;
                    document.getElementsByTagName('head')[0].appendChild(element);
                });
            },
            loadResources: function () {
                const initVue = this.initVue;
                const loadResource = this.loadResource;
                const host = '//s0.pstatp.com/cdn/expire-1-M/';
                const resources = [
                    'vue/2.6.10/vue.min.js',
                    'element-ui/2.8.2/index.js',
                    'element-ui/2.8.2/theme-chalk/index.css'
                ];
                const loadPromises = [];
                resources.forEach(resource => {
                    loadPromises.push(loadResource(btoa(resource).replace(/[=+\/]/g, ''), host + resource,
                        ({
                            'css': 'link',
                            'js': 'script'
                        })[resource.split('.').pop()]
                    ));
                });
                Promise.all(loadPromises).then(
                    function () {
                        let flag = false;
                        const waitVue = setInterval(() => {
                            if (!flag && typeof Vue === 'function') {
                                flag = true;
                                initVue();
                                clearInterval(waitVue);
                            }
                        }, 100);
                    }
                );
            },
            initVue: function () {
                var blog = new Vue({
                    el: document.createElement('div'),
                    created() {
                        this.sayHello();
                        if (this.notice) {
                            this.showNotice();
                        }
                        window.alert = this.alert;
                    },
                    computed: {
                        notice: function () {
                            const blgNotice = document.querySelector('.blog-notice p');
                            if (blgNotice) {
                                const oldNotice = localStorage.getItem('BLOG-NOTICE');
                                const newNotice = blgNotice.innerText;
                                if (!oldNotice || oldNotice !== newNotice) {
                                    return newNotice;
                                }
                            }
                            return ''
                        },
                        hello: function () {
                            var hours = (new Date()).getHours()
                            var t
                            if (hours < 5) {
                                t = '凌晨好,注意休息哦!'
                            } else if (hours >= 5 && hours < 8) {
                                t = '早上好,新的一天又是元气满满呢!'
                            } else if (hours >= 8 && hours < 12) {
                                t = '上午好!'
                            } else if (hours === 12) {
                                t = '中午好!'
                            } else if (hours > 12 && hours <= 18) {
                                t = '下午好!'
                            } else if (hours > 18 && hours <= 22) {
                                t = '晚上好!'
                            } else if (hours > 22 && hours < 24) {
                                t = '夜深了,注意休息哦!'
                            }
                            return t
                        }
                    },
                    methods: {
                        alert: function (message, title, type, duration, showClose, offset, onClose) {
                            if (duration !== 0) {
                                duration = 4500;
                            }
                            this.$notify({
                                message: message,
                                type: type || 'error',
                                title: title || '警告',
                                duration: duration,
                                showClose: showClose || false,
                                offset: offset || 0,
                                onClose: onClose
                            })
                        },
                        showNotice: function () {
                            setTimeout(() => {
                                const notice = this.notice;
                                this.alert(notice, '公告', 'info', 0, true, null, function () {
                                    localStorage.setItem('BLOG-NOTICE', notice);
                                });
                            }, 1000);
                        },
                        sayHello: function () {
                            setTimeout(() => {
                                this.alert('欢迎来到 谭先生 的博客!', this.hello, 'success');
                            }, 1000);
                        }
                    },
                })
            }
        };
        common.loadResources();
    }
</script>

13.Typecho主流音乐插件及YouduPlayer完全配置指南

主流的音频播放插件有APlayerYoudu Player,前者支持直接填写网易云歌单、歌手 ID,还支持歌词显示,而后者一开始也内置了网易云 API,但随着猪场 API 改变便不再支持了。所以方便起见选择前者,但如果你喜欢后者的界面,也就是本博客使用的,可以接着往下看。

生成网易云歌单配置

无需多言,首先要安装该插件,具体看作者主页介绍。接着你可以将歌曲上传到 CDN 或网站,然后按作者指定格式编写插件配置。

不过,我已经编写了 Youdu Player 配置生成器,你可以使用它直接生成网易云歌单配置。具体操作为:在网易云新建歌单,将想要展示的音乐加进去。接着选择分享,将分享链接在PC浏览器打开,随后复制浏览器地址,将其粘贴到配置生成器中点击生成,随后点击复制,最后将配置粘贴到插件后台

调整 Youdu Player 界面

插件默认风格可能与博客不符,不过它预留了自定义 CSS 接口。下面的我的 CSS 配置,主要调整了高度,进度条颜色,歌曲名称间隔以及长歌曲名不换行等。

/* 高度 */
#bgmpanel, span.bgmbuttom {
    height: 72px;
}

/* 进度条颜色 */
#jindu {
    background-color: red;
}

/* 歌名与作者间距 */
.artist {
    float: initial !important;
    margin-left: 5px;
}

/* Chrome 隐藏滚动条 */
.yd-lib::-webkit-scrollbar {
    display: none !important;
}

.yd-lib {
    /* 歌曲上下间距 */
    margin: 5px 0;

    /* 歌曲信息超出不换行 */
    white-space: nowrap;
    overflow-x: scroll;

    /* 火狐隐藏滚动条 */
    overflow: -moz-hidden-unscrollable;
    scrollbar-width: none;
    
    /* IE、EDGE 隐藏滚动条 */
    -ms-overflow-style: none !important;
}

14.Mirages主题非侵入式友链随机教程

2分钟实现Mirages主题友链随机,你可以刷新该页面查看效果。

使用方法

将以下代码粘贴到友链页文章末尾即可,其他主题,包括Wordpress, 改一下CSS 选择器应该也可以使用。

    !!!
    <script>
        (() => {
            const linkBox = document.querySelector('.link-box');
            const links = linkBox.children;
    
            let sequence = [...new Array(links.length).keys()];
            for (let i = links.length - 1; i > 0; i--) {
                const random = Math.floor(Math.random() * i);
                [sequence[i], sequence[random]] = [sequence[random], sequence[i]];
            }
    
            let innerHTML = '';
            sequence.forEach(value => innerHTML += links[value].outerHTML);
            linkBox.innerHTML = innerHTML;
        })();
    </script>
    !!!

15.代码颜色

一般情况下代码为灰底红字,而主题默认的不够鲜艳。只需在主题设置 - 高级选项 - 真 • 高级设置中填入codeColor = #f44242。注意自定义主色调必须使用Hex Color

16.为 Typecho 评论添加邮件提醒

项目地址

Comment2Mail

QQ截图20210726000519.png

食用步骤

下载插件

上传到typecho根目录/usr/plugins,下载插件代码并将文件夹重命名为Comment2Mail

填写配置

依次进入控制台 -> 插件,启用 Comment2Mail,随后进入插件设置填写邮箱后保存。需要注意的是,如果使用 QQ 邮箱,密码栏应填写授权码,而非 QQ 密码。

QQ截图20210726002000.png

模板修改

默认模板比较简陋,分享一个reply.html模板,效果如下,请自行 DIY。

dsafV.jpg

<meta charset="utf-8">
<div style="position:relative;width:450px;height:auto;margin:0 auto;padding-bottom:5px;border:rgb(224, 221, 224) solid 1px;border-radius:10px">
    <div style="background-image:url(https://cdn.tandongtao.com/usr/uploads/images/UTB8uTIaPSnEXKJk43Ubq6zLppXaW.jpg);width:100%;height:300px;background-size:cover;background-repeat:no-repeat;border-radius:10px 10px 0px 0px"></div>
    <div style="width:40%;height:40px;background-color:rgb(231, 145, 145);margin-top:-20px;margin-left:20px;color:#fff;text-align:center;line-height:40px;border-radius:30px">
        亲爱的:{author} !
    </div>
    <div style="line-height:180%;padding:0 15px 12px;width:90%;margin:auto;margin-bottom:0px;font-size:12px">
        <div style="border-bottom:1px solid rgb(216, 213, 213);font-size:13px;margin:10px 0px;padding:10px 0px">
            <span style="color:#12ADDB;font-weight:bold">&gt;&nbsp;</span>
            <span>您在</span>
            <a style="text-decoration:none;color:#12ADDB;font-weight:bold;" href="{permalink}" target="_blank">《{title}》</a>
            <span>的评论有了新回复呢!</span>
        </div>
        <div style="padding:0 10px 0 10px;margin-top:18px">
            <p>您的评论:</p>
            <p style="padding:10px 15px;margin:18px 0;border-radius:30px;background-color:rgb(255, 240, 240);">{text}</p>
            <p><strong>{replyAuthor}</strong>&nbsp;给您的回复:</p>
            <p style="padding:10px 15px;margin:18px 0;border-radius:30px;background-color:rgb(240, 240, 255);">{replyText}</p>
        </div>
    </div>
    <div
        style="color:#8c8c8c;font-size:8px;width:93%;margin:auto;margin-top:-30px">
        <p style="padding:20px;">萤火虫消失之后,那光的轨迹仍久久地印在我的脑际。那微弱浅淡的光点,仿佛迷失方向的魂灵,在漆黑厚重的夜幕中彷徨。——《挪威的森林》村上春树</p>
    </div>
    <a style="text-decoration:none;background-color:rgb(155, 151, 221);color:#FFF;width:40%;text-align:center;height:40px;line-height:40px;box-shadow:5px 5px 5px rgba(0,0,0,0.2);margin:-10px auto;display:block;border-radius:30px" href="{commentUrl}" target="_blank">查看完整回复內容</a>
    <div style="color:#8c8c8c;font-size:8px;width:100%;text-align:center;margin-top:30px">
        <p>本邮件为系统自动发送,请勿直接回复哦!</p>
    </div>
    <div style="color:#8c8c8c;font-size:8px;width:100%;text-align:center">
        <p>Copyright © {blogName}. All Rights Reserved.</p>
    </div>
</div>

17.Typecho 网站添加复制提醒

这边使用的是 layer 的 web 弹层组件,详情查看layer官网
食用方法


依次进入控制台 - 外观 - 设置外观 - 主题自定义扩展,将以下代码加入到自定义 HTML 元素拓展 - 在 body 标签结束前

<!-- 引入layer.js,也可以替换成别的源 -->
<script src="https://cdn.staticfile.org/layer/3.1.1/layer.js"></script>
<!-- 复制提醒 -->
<script>document.body.oncopy = function() {layer.msg('复制成功,若要转载请务必保留原文链接!');};</script>

可将官方源更换为自己的源

  • 打开官网
  • 点击下载
  • 上传至服务器
    QQ截图20210727231626.png

QQ截图20210727231717.png

18.浏览统计和热门文章调用插件TePostViews

TePostViews是一款简单的 typecho 热门文章调用插件,通过该插件可以显示每篇文章的阅读次数,以及调用阅读次数最多或者评论数最多的文章作为热门文章调用,用户可以自由选择调用依据和调用文章的数量,使用相当简单。

插件使用方法:

1、把下载的压缩包解压,上传 TePostViews 文件夹到 usr/plugins/ 目录;

2、进入网站后台 —— 控制台 —— 插件中启用 TePostViews 插件;

3、在主题的 post.php 文件添加阅读次数调用代码:

阅读:<?php $this->viewsNum();?>

4、在主题的 sidebar.php 文件(或其它文件)添加热门文章调用代码:

<?php TePostViews_Plugin::outputHotPosts() ?>

5、保存文件即可。

插件设置:

进入后台 —— 控制台 —— 插件页面,点击 TePostViews 插件后面的【设置】可以对插件的参数进行配置

QQ截图20210730001500.png

需要注意的是【卸载设置】,如果选择删除数据,卸载插件可数据不可恢复!

19.Typecho防黑安全加固

删除安装文件

成功安装后删除install.php文件、install/文件夹。

修改后台地址

admin修改为黑客猜不到的名字,例如 pipixia,防止黑客穷举密码。

修改`admin`文件夹名称

修改admin文件夹名称为你喜欢的名称,例如 pipixia

修改配置文件以适配修改后的`admin`路径

修改config.inc.php
修改为以下代码,我就当修改为pipixia了。

/** 后台路径(相对路径) */
define('__TYPECHO_ADMIN_DIR__', '/pipixia/');

好了。现在你可以访问你的域名/pipixia/ 了。这就是你的新的后台地址,原来的你的域名/admin/ 已经不能访问了。

屏蔽 usr、var 目录下 php 文件的访问

屏蔽usrvar目录下php文件的访问可以阻止黑客访问到他上传的 php木马。
我们利用 Rewrite 伪静态机制来做。我这里以 Apache 服务器为例,大部分虚拟主机都是 Apache。LiteSpeed Web Server 也使用的是 Apache 的规则。
我们同时屏蔽 config.inc.php 和.htaccess 的访问。
屏蔽原理就是把要屏蔽的请求重定向到首页文件,首页文件会当成文章名来解析,没有同名文章就会返回 404 未找到。所以就算黑客上传了木马也只会得到 404 未找到的响应。
文件名:.htaccess

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php [E=PATH_INFO:$1]
    RewriteRule (var|usr)(.+ph*)$ index.php [E=PATH_INFO:$1]
    RewriteRule (config.inc.php|.htaccess)$ index.php [L,E=PATH_INFO:$1]
</IfModule>

新建.htaccess 文件添加以上内容,上传到你 typecho 博客的根目录就可以了。
经测试 Nginx 和 OpenResty 下可用。

 if (!-e $request_filename) {
        rewrite ^(.*)$ /index.php$1;
    }
    rewrite /(var|usr)(.+ph*)$ /index.php;
    rewrite /(config.inc.php|.htaccess)$ /index.php last;

20.文章标签选择器

插件名为 tagshelper(Typecho 插件)

作用:在 Typecho 文章编辑页面右下方标签位置的下方,会显示出你的博客所有的标签(常用标签会显示在前面),点击任意标签即可为当前文章添加选中的标签。
具体操作如下图:

1128734599.gif

插件下载地址

21.网站内容的禁止复制和粘贴

1、使右键和复制失效

方法 1:
在网页中加入以下代码:

<script language="Javascript">  
document.oncontextmenu=new Function("event.returnValue=false");  
document.onselectstart=new Function("event.returnValue=false");  
</script>  

方法 2:
在 <body> 中加入以下代码:

<body oncontextmenu="return false" onselectstart="return false">

<body oncontextmenu="event.returnValue=false" onselectstart="event.returnValue=false">

实质上,方法 2 与方法 1 是一样的。
方法 3:
如果只限制复制,可以在 <body> 加入以下代码:

<body oncopy="alert('对不起,禁止复制!');return false;">

2、使菜单 "文件"-"另存为" 失效

如果只是禁止了右键和选择复制,别人还可以通过浏览器菜单中的 "文件"-"另存为" 拷贝文件。为了使拷贝失效,可以在 <body> 与 </body> 之间加入以下代码:

<noscript>
<iframe src="*.htm"></iframe>
</noscript>

这样,用户在另存网页时,就会出现 "无法保存 Web 页" 的错误。

————————————————————————————————————

另外,也可以使用 event.preventDefault () 方法来阻止 oncontextmenu () 还有 onselectstart ()

document.oncontextmenu=function(evt){
  evt.preventDefault();
}

document.onselectstart=function(evt){
 evt.preventDefault();
};

既然可以禁止,那么当然也可以启用它,将事件重新赋值即可,可以赋值为 null,或字符串、布尔值都行。如:

document.oncontextmenu="";

document.onselectstart=true;

或者 禁用 js:打开谷歌浏览器,选择 “设置” – 选择 “隐私设置” – 选项 “内容设置” – 选择 “JavaScript” – 选择 “不允许任何网站运行 JavaScript”,设置完成刷新即可。

22.关于Font Awesome图标的使用 加入动态效果

1.引入CSS

本主题在控制台——>设置外观——>主题自定义扩展——>自定义 HTML 元素拓展-标签: head 尾部 (head 标签结束前)进行添加

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome-animation@0.2.1/dist/font-awesome-animation.min.css">

2.修改图标以及动画效果

<i class="fa fa-heartbeat faa-flash animated " aria-hidden="true" style="color: rgba(255, 0, 0, 0.9)"></i>

图标样式可参考【这里】
动态样式可参考【这里】
测试效果可参考我的主页【演示界面】

速度优化

1.GZIP加速网站

找到你的Typecho的网站根目录中的index.php,添加如下代码

/* 开启gzip压缩 */
ob_start('ob_gzhandler');

添加的位置

<?php
/**
 * Typecho Blog Platform
 *
 * @copyright  Copyright (c) 2008 Typecho team (http://www.typecho.org)
 * @license    GNU General Public License 2.0
 * @version    $Id: index.php 1153 2009-07-02 10:53:22Z magike.net $
 */
/**开启gzip */
ob_start('ob_gzhandler');

/** 载入配置支持 */
if (!defined('__TYPECHO_ROOT_DIR__') && !@include_once 'config.inc.php') {
    file_exists('./install.php') ? header('Location: install.php') : print('Missing Config File');
    exit;
}

/** 初始化组件 */
Typecho_Widget::widget('Widget_Init');

/** 注册一个初始化插件 */
Typecho_Plugin::factory('index.php')->begin();

/** 开始路由分发 */
Typecho_Router::dispatch();

/** 注册一个结束插件 */
Typecho_Plugin::factory('index.php')->end();

2.Gravatar头像国内源

找到Typecho的安装目录中的config.inc.php文件,添加一行代码更换为国内v2ex源

define('__TYPECHO_GRAVATAR_PREFIX__', 'https://cdn.v2ex.com/gravatar/');

更多镜像源
P.S 直接替换上边的地址就行了
http://gravatar.ihuan.me/avatar/
https://gravatar.proxy.ustclug.org/
https://cdn.v2ex.com/gravatar/
http://dn-qiniu-avatar.qbox.me/avatar
https://gravatar.loli.net/avatar/

3.网站预加载JS脚本instant.page

原理介绍及作用

插件名称为 instant.page,由国外大佬开发,基于 JS,作用是预加载网页。具体实现为鼠标悬停 65ms 后触发浏览器下载,宣称可让网站加载时间缩短到 1 分钟以内,并提高 1% 的转化率。效果咱不知道,使用倒是简单,往上怼就是了。

食用方法

一、使用官方提供的带有 Cloudflare 加速的脚本
建议服务器在国外的朋友使用。只要把这行代码添加到网站的 </body>标签之前即可。(一般都可以在后台直接添加)

<script src="//instant.page/1.2.2" type="module" integrity="sha384-2xV8M5griQmzyiY3CDqh1dn4z3llDVqZDqzjzcY+jCBCk/a5fXJmuZ/40JJAPeoU"></script>

二、自托管
建议服务器在国内的朋友使用。只需将下面这段 js 上传到自己服务器,然后在 </body>标签之前根据路径添加下面的代码即可。点击查看

<script src="`存放路径`/instantclick-1.2.2.js" type="module"></script>

- - - The END - - -
  • 文章作者:谭先生
  • 版权所有:文章转载时,注明出处即可!
  • 本站部分资源收集于网络,纯个人收藏,无商业用途,如有侵权请及时告知!
  • Last Modified: August 12, 2021
    Archives QR Code Tip
    QR Code for this page
    Tipping QR Code
    Leave a Comment

    2 Comments
    1. 隔壁小胡 隔壁小胡     Windows 10 /    Google Chrome

      赞一个,很实用!@(滑稽)

      1. 谭先生 谭先生     Windows 10 /    Google Chrome

        @隔壁小胡小胡同志,欢迎你的到来,要常来喔::quyin:1huaji::

    阅读:929