注:该blog配置文章中涉及的代码以及演示效果非当前站点效果。在2023-11-28,我将blog的框架更改为halo,并着手开始迁移工作。

搭这个博客还是费了一番心思,在原有主题的基础上,添加了很多自定义的内容。每次更新都在这里记下来:

  • 鼠标点击特效

  • 浏览器右侧滚动条

  • 背景动调线条

  • 鼠标指针的替换

  • 浏览器标签恶搞

  • 网站计时器

  • 鼠标移动的特效

  • 去除banner图

  • 设置背景固定的图

前言·准备工作

Fluid主题是一款完整度比较高的主题了,一般不要修改源代码,不然导致后面更新时会很麻烦(如果你不打算更新,当我没说)

如果你懂html知识,你随意,如果你是纯小白,那么完全按照我的来,也是可以完成你想要的特效的。

首先我们要引入js和css文件,这里一般在自己的主题里面都是可以找的相应位置的,引入外来文件,不动源代码,才是最稳妥的办法。

这里Fluid主题配置文件里就有,在这里就可以引入自己的文件了,这里的相对路径则是你blog文件夹下面的source,在这里你还能看到你的文章,配图……其他自定义的配置文件(如果有的话)。

这里我是把js和css都放在一个文件夹里面,方便找到和修改

如果你没有这两个文件,自己创建就好,完成之后就可以正式开始了,在下面选取喜欢的样式复制进代码就好,有特殊修改的我会特别说明。CSS和js别弄错了。

0x00 CSS

0x01 浏览器右侧滚动条

找了很多教程,看了很多博客,最后总结出最简单的替换原来滚动条的方法

html { 
    overflow-y: scroll; /* 设置自定义滚动条 这样做会强制显示滚动条*/
    /*overflow-y: auto; /* 可以更换为auto,自动显示模式,就不会强制显示*/
/* 滚动栏本身的背景 此项必须有 */
html::-webkit-scrollbar { 
    width: 6px;
    background-color: rgba(0, 0, 0, 0.0);
/*滚动栏下方的空白区域*/
html::-webkit-scrollbar-track {
    background: rgba(255, 85, 127, 0.0); /* 设置透明,就会随主题变化 */
/* 可拖动滚动元素的大小取决于可滚动元素的大小 */
html::-webkit-scrollbar-thumb{
    background: #252d38;
    border-radius: 6px;
/* 可滚动元素的底角,两个滚动条在此相交。 */
html::-webkit-scrollbar-corner {
    background:#82AFFF;
}

关于 -webkit-scrollbar 伪元素更多的用法,自行百度

:这里应该支持大部分浏览器,但是火狐是不支持的,想搞得用插件。

同时我还替换了代码下面的滚动条

.markdown-body table {
    overflow-x: scroll; /* 设置自定义滚动条 */
/* 滚动栏本身的背景 此项必须有 */
.markdown-body table::-webkit-scrollbar { 
    height: 8px;
    background-color: rgba(0, 0, 0, 0.0);
/*滚动栏下方的空白区域*/
.markdown-body table::-webkit-scrollbar-track {
    background-color: rgba(255, 85, 127, 0.0);
/* 可拖动滚动元素的大小取决于可滚动元素的大小 */
.markdown-body table::-webkit-scrollbar-thumb{
    background: #ffaaff;
    border-radius: 2px;
}

你可能会在其他地方看到更为简略的写法,那就是没有 :: 之前的内容直接写成这样:

::-webkit-scrollbar { 
    height: 8px;
    background-color: rgba(0, 0, 0, 0.0);
}

在只替换一处的情况下,可以那样做没有毛病,但是果然替换多处,最好还是按照我的方法写。或者宁是这方面的专业人士,有更好更优的写法与处理逻辑的话,希望宁不吝赐教,可以邮箱发给我。

最终效果如下

0x02 替换鼠标指针

很多博主都是简单的几行代码,主要是修改cursor属性

html { 
    cursor: url(/img/Arrow.cur),auto;/* url地址可以是链接,相对位置,绝对位置 */
    background-color: @theme_background;  /* 写成透明就行 */
}

这个时候运行就会发现有很多地方没有替换,在网页使用F12打开开发者功能选中元素就行,再用选择器修改对应的cursor属性即可

/* 封面大图 */
.banner {
    cursor: url(/img/Arrow.cur),auto;
    background-color: @theme_background;
/* 封面向下 */
.scroll-down-bar {
    cursor: url(/img/Hand2.cur),auto; /* 一个小手 */
    background-color: @theme_background;
}

最不好处理的就是链接,这个时候光标就会变成一个单指点击的小手,我用上面的方法修改了一个多小时,直到我发现了 属性选择器 ……

/* 所有可跳转链接 */
a[href] {
    cursor: url(/img/Hand2.cur),auto !important;
    background-color: @theme_background;
}

这个时候就完美解决(增加评论后进行了优化,添加!important属性后可以应用大部分场景,对下方补充进行了删减)

再看看其他地方,做做补充

/* 搜索框关闭按钮  */
#local-search-close.close {
    cursor: url(/img/Hand2.cur),auto;
    background-color: @theme_background;
/* 搜索框、输入框 */
input,textarea {
    cursor: url(/img/IBeam.cur),auto;    /* 这里应该是竖条光标 */
    background-color: @theme_background;
/* 代码复制键 按钮键增加!important属性后可删 */
.copy-btn.copy-btn-light {
    cursor: url(/img/Hand2.cur),auto;
    background-color: @theme_background;
/* 按钮 */
button[class] {
    cursor: url(/img/Hand2.cur),auto !important;
    background-color: @theme_background;
/* 补充按钮 */
svg {
    cursor: url(/img/Hand2.cur),auto !important;
    background-color: rgba(0, 0, 0, 0.0);
/* 图片放大 */
.fancybox-image {
    cursor: url(/img/SizeAll.cur),auto;
    background-color: @theme_background;
/* 回到顶部   a标签添加!important属性后此处可删*/
#scroll-top-button {
    cursor: url(/img/Hand2.cur),auto;
    background-color: @theme_background;
}

最后,如果你喜欢我的鼠标指针,直接在我的 仓库 下载即可,他们都是开源的。

0x03 去除banner图

这里的banner图有两层,一层是图片,然后在图片上层还有一层半透明的蒙版,目的是更好的副标题文字显示,我们去掉banner图就不需要了,所以两层都要去掉。但是我们还是需要banner的位置在那,这样才有一个封面,才美观,而不是直接看到文章列表。

这里修改主题配置文件 _config.fluid.yml

banner图我试过了,没有好的方法去除,所以直接载入一张透明的图片即可这里的相对位置也是 yourblog/source/ ,将蒙版不透明度调到0,完全透明就好。

这只是首页,还有另外几页,也是同样的修改(也是配置文件里)。

0x04 添加固定背景图

没有了banner图,此时博客页面上就没有图片了,所以可以添加固定的背景图,方法如下:

/* 设置背景图片 */
body {
  background: url(/img/10.jpg);
  background-attachment: fixed;
  background-size: cover;  
}

效果如下

无论什么滑动都是不会变。

0x10 JS

0x11 鼠标点击特效

在一篇博客里找到了博主直接给了js链接,但是我害怕失效了,所以直接把源码偷过来了(≖ᴗ≖)✧

(代码太长占地方,进行了压缩,编辑器是可以恢复的,不恢复直接使用也可以。)

//花花特效
//onload=function(){var click_cnt=0,$html=document.getElementsByTagName("html")[0],$body=document.getElementsByTagName("body")[0];$html.onclick=function(e){var $elem=document.createElement("b");$elem.style.color="#FFC0CB",$elem.style.zIndex=9999,$elem.style.position="absolute",$elem.style.select="none";var x=e.pageX,y=e.pageY;switch($elem.style.left=x-10+"px",$elem.style.top=y-20+"px",clearInterval(anim),++click_cnt){case 10:$elem.innerText="OωO";break;case 20:$elem.innerText="(๑•́ ∀ •̀๑)";break;case 30:$elem.innerText="(๑•́ ₃ •̀๑)";break;case 40:$elem.innerText="(๑•̀_•́๑)";break;case 50:$elem.innerText="( ̄へ ̄)";break;case 60:$elem.innerText="(╯°口°)╯(┴—┴";break;case 70:$elem.innerText="૮( ᵒ̌皿ᵒ̌ )ა";break;case 80:$elem.innerText="╮(。>口<。)╭";break;case 90:$elem.innerText="( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃";break;case 100:case 101:case 102:case 103:case 104:case 105:$elem.innerText="(ꐦ°᷄д°᷅)";break;default:$elem.innerText="🌸"}$elem.style.fontSize=10*Math.random()+8+"px";var increase=0,anim;setTimeout((function(){anim=setInterval((function(){150==++increase&&(clearInterval(anim),$body.removeChild($elem)),$elem.style.top=y-20-increase+"px",$elem.style.opacity=(150-increase)/120}),8)}),70),$body.appendChild($elem)}};
//社会主义核心价值观
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; var x = e.pageX, y = e.pageY; let scrolly = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop; y = y - scrolly; $i.css({ "z-index": 999, "top": y - 20, "left": x, "position": "fixed", "font-weight": "bold", "color": "#ff6651" /*随机颜色写法:"rgb(" + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + ")"*/ }); $("body").append($i); $i.animate({ "top": y - 180, "opacity": 0 }, 1500, function() { $i.remove(); });  }); });
//引入小心心特效
//!function (e, t, a) {function r() {for (var e = 0; e < s.length; e++) s[e].alpha <= 0 ? (t.body.removeChild(s[e].el), s.splice(e, 1)) : (s[e].y--, s[e].scale += .004, s[e].alpha -= .013, s[e].el.style.cssText = "left:" + s[e].x + "px;top:" + s[e].y + "px;opacity:" + s[e].alpha + ";transform:scale(" + s[e].scale + "," + s[e].scale + ") rotate(45deg);background:" + s[e].color + ";z-index:99999");requestAnimationFrame(r)}function n() {var t = "function" == typeof e.onclick && e.onclick;e.onclick = function (e) {t && t(), o(e)}}function o(e) {var a = t.createElement("div");a.className = "heart", s.push({el: a,x: e.clientX - 5,y: e.clientY - 5,scale: 1,alpha: 1,color: c()}), t.body.appendChild(a)}function i(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)}function c() {return "rgb(" + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + "," + ~~(255 * Math.random()) + ")"}var s = [];e.requestAnimationFrame = e.requestAnimationFrame || e.webkitRequestAnimationFrame || e.mozRequestAnimationFrame || e.oRequestAnimationFrame || e.msRequestAnimationFrame || function (e) {setTimeout(e, 1e3 / 60)}, i(".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;}"), n(), r()}(window, document);

这里我只用了二十四字核心价值观的特效,还对他进行了修改。

起因:原定位方式为absolute,导致我点击目录的时候,页面会快速上线跳转,特效就跟着页面跑了……跑了……了……

修改方法:将定位absolute改为fixed,y的值改为 y - scrolly(滚动条滚动的高度) ,(注:这里24字核心价值观已经修改好了,直接用即可,另外两个也是一样,小白对照着修改就好。或者你直接修改那二十四字的内容,也是可以的。)

然后就有了完美的点击特效。

新增:文本不能被选中,原来的效果中,如果你喜欢玩那个特效,那么连续的点击就会导致前面的字会被选中,极其不美观

找到代码中的css属性(在js文件中),添加代码

"-webkit-user-select": "none",
"-moz-user-select": "none",
"-o-user-select": "none",
"user-select": "none",

在鼠标移动特效也适用,添加在相应的位置即可。例如我的星星特效:

0x12 背景动态线条

<!--动态线条背景--> var color_dark = "255,255,255"; var color_light = "0,0,0"; var opacity = '0.8'; var zIndex = "-2"; var count = "200"; var Line_act = function(color) { function o(w, v, i) { return w.getAttribute(v) || i }  function j(i) { return document.getElementsByTagName(i) }  function l() { var i = j("script"), w = i.length, v = i[w - 1]; return { l: w, z: o(v, "zIndex", -1), o: o(v, "opacity", 0.8), c: o(v, "color", color), n: o(v, "count", 100) } }  function k() { r = u.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, n = u.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight }  function b() { e.clearRect(0, 0, r, n); var w = [f].concat(t); var x, v, A, B, z, y; t.forEach(function(i) { i.x += i.xa, i.y += i.ya, i.xa *= i.x > r || i.x < 0 ? -1 : 1, i.ya *= i.y > n || i.y < 0 ? -1 : 1, e.fillRect(i.x - 0.5, i.y - 0.5, 1, 1); for (v = 0; v < w.length; v++) { x = w[v]; if (i !== x && null !== x.x && null !== x.y) { B = i.x - x.x, z = i.y - x.y, y = B * B + z * z; y < x.max && (x === f && y >= x.max / 2 && (i.x -= 0.03 * B, i.y -= 0.03 * z), A = (x.max - y) / x.max, e.beginPath(), e.lineWidth = A / 2, e.strokeStyle = "rgba(" + s.c + "," + (A + 0.2) + ")", e.moveTo(i.x, i.y), e.lineTo(x.x, x.y), e.stroke()) } } w.splice(w.indexOf(i), 1) }), m(b) } var u = document.createElement("canvas"), s = l(), c = "c_n" + s.l, e = u.getContext("2d"), r, n, m = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(i) { window.setTimeout(i, 1000 / 45) }, a = Math.random, f = { x: null, y: null, max: 20000 }; u.id = c; u.style.cssText = "position:fixed;top:0;left:0;z-index:" + s.z + ";opacity:" + s.o; j("body")[0].appendChild(u); k(), window.onresize = k; window.onmousemove = function(i) { i = i || window.event, f.x = i.clientX, f.y = i.clientY }, window.onmouseout = function() { f.x = null, f.y = null }; for (var t = [], p = 0; s.n > p; p++) { var h = a() * r, g = a() * n, q = 2 * a() - 1, d = 2 * a() - 1; t.push({ x: h, y: g, xa: q, ya: d, max: 6000 }) } setTimeout(function() { b() }, 100) };  /* 以下是我自己改的,将上述函数改为声明,在下面选择调用 */ var lord = document.getElementById("color-toggle-icon").getAttribute('data'); if(lord == "light"){ Line_act(color_dark); } else{ Line_act(color_light); }

因为我的博客是有两个主题模式(白天和黑夜)可切换的。所以就需要两个线条的颜色。

本来我是想做到颜色的变化随主题动态变换的,奈何技术不够硬,只能做成这样(载入时就是最优效果),切换暗色亮色后需刷新才能变化……

这里我确认主题的方法则是通过我的切换按钮,通过 getElementById() 找到该标签,再通过 getAttribute() 获取属性的值

这里我得感谢我的大佬同学的帮助,因此,我学到了 getAttribute() 方法

如果你和不是同款主题,应该会报错,将最后的代码(从注释哪里开始)修改为一下内容即可

//分别对应亮色和暗色的线条,二选一即可。或者根据需求自行修改参数,在最开始的位置。
Line_act(color_dark);
Line_act(color_light);

Fluid主题里的文章页目录的z-index值貌似很低,线条对目录进行了遮挡,导致不能点击目录,在css里添加一下代码即可

/* 提高目录的z轴坐标,否则会被动态线挡住 */
	z-index: 10;
}

0x13 标签恶搞

这个是比较有意思的东西

当你浏览其他标签时,他就会变成这个样子

如果你以为它真的崩溃了,那就……大错特错……

就搞怪,就和你玩,诶嘿(ಥ_ಥ) ,这个还是比较简单了。

// 浏览器搞笑标题
var OriginTitle = document.title;
var titleTime;
document.addEventListener('visibilitychange', function() {
	if (document.hidden) {
		$('[rel="icon"]').attr('href', "/funny.ico");
		document.title = '╭(°A°`)╮ 页面崩溃啦 ~';
		clearTimeout(titleTime);
	} else {
		$('[rel="icon"]').attr('href', "/img/newtubiao.png");
		document.title = '(ฅ>ω<*ฅ) 噫又好啦 ~' + OriginTitle;
		titleTime = setTimeout(function() {
			document.title = OriginTitle;
		}, 2000);
});

0x14 鼠标移动特效

当你的鼠标移动的时候,会有小心心冒出来

// 鼠标移动星星特效
(function() { function t() { i(), a() }  function i() { document.addEventListener("mousemove", o), document.addEventListener("touchmove", e), document.addEventListener( "touchstart", e), window.addEventListener("resize", n) }  function n(t) { d = window.innerWidth, window.innerHeight }  function e(t) { if (t.touches.length > 0) for (var i = 0; i < t.touches.length; i++) s(t.touches[i].clientX, t.touches[i].clientY, r[Math.floor(Math.random() * r.length)]) }  function o(t) { u.x = t.clientX, u.y = t.clientY, s(u.x, u.y, r[Math.floor(Math.random() * r.length)]) }  function s(t, i, n) { var e = new l; e.init(t, i, n), f.push(e) }  function h() { for (var t = 0; t < f.length; t++) f[t].update(); for (t = f.length - 1; t >= 0; t--) f[t].lifeSpan < 0 && (f[t].die(), f.splice(t, 1)) }  function a() { requestAnimationFrame(a), h() }  function l() { this.character = "*", this.lifeSpan = 120, this.initialStyles = { position: "fixed", top: "0", display: "block", pointerEvents: "none", "z-index": "10000000", fontSize: "20px", "will-change": "transform" }, this.init = function(t, i, n) { this.velocity = { x: (Math.random() < .5 ? -1 : 1) * (Math.random() / 2), y: 1 }, this.position = { x: t - 10, y: i - 20 }, this.initialStyles.color = n, this.element = document.createElement("span"), this.element.innerHTML = this.character, c(this.element, this.initialStyles), this.update(), document.body.appendChild(this.element) }, this.update = function() { this.position.x += this.velocity.x, this.position.y += this.velocity.y, this.lifeSpan--, this.element.style.transform = "translate3d(" + this.position.x + "px," + this.position.y + "px,0) scale(" + this.lifeSpan / 120 + ")" }, this.die = function() { this.element.parentNode.removeChild(this.element) } }  function c(t, i) { for (var n in i) t.style[n] = i[n] } var r = ["#D61C59", "#E7D84B", "#1B8798", "#ffaaff", "#aaaaff"], d = window.innerWidth, u = (window.innerHeight, { x: d / 2, y: d / 2 }), f = []; t() })();

在颜色队列里可以替换你喜欢的颜色,它们会随机出现。

0x15 添加网站计时器

这个教程是最坑的,代码接入后就一直报错……最后找到了原因,先看代码再解释

//运行时间bynote.cn
var now = new Date(); 
function createtime() { 
    var grt= new Date("10/20/2021 01:18:00");//在此处修改你的建站时间,格式:月/日/年 时:分:秒
    now.setTime(now.getTime()+250); 
    days = (now - grt ) / 1000 / 60 / 60 / 24; dnum = Math.floor(days); 
    hours = (now - grt ) / 1000 / 60 / 60 - (24 * dnum); hnum = Math.floor(hours); 
    if(String(hnum).length ==1 ){hnum = "0" + hnum;} minutes = (now - grt ) / 1000 /60 - (24 * 60 * dnum) - (60 * hnum); 
    mnum = Math.floor(minutes); if(String(mnum).length ==1 ){mnum = "0" + mnum;} 
    seconds = (now - grt ) / 1000 - (24 * 60 * 60 * dnum) - (60 * 60 * hnum) - (60 * mnum); 
    snum = Math.round(seconds); if(String(snum).length ==1 ){snum = "0" + snum;} 
    document.getElementById("timeDate").innerHTML = "本站已夹缝中生存 "+ dnum +" 天 "; 
    document.getElementById("times").innerHTML = hnum + " 小时 " + mnum + " 分 " + snum + " 秒"; 
setInterval("createtime()",250);

运行之后会对 document.getElementById 方法报错,为什么?(因为我本身也是个半吊子,这种东西也不是很熟悉)我一直在想为什么,突然我就想明白了,他娘的压根就没有那两个标签(一个id为 timeDate ,一个为 times 。不懂?没关系!照做就行!)。所以就得自己在源代码里添加,加入这两个标签,我是那种改源码的人吗?显然不是,所以我找了这个地方(在配置文件 _config,fluid.yml 里)

添加在页脚 hexo❤Fluid那行之后,网站的PV、UV统计之前,就是上面展示的样式。同时害修饰了hexo和fluid显示内容。

<br><span id="timeDate">天数载入中</span><span id="times">...</span><br>

添加完这行代码就能运行了。如果字体大小不符合你的要求,都可以通过 css 修改:

#timeDate {
	font-size: 12px;
#times {
	font-size: 12px;
}

完结……

在2023-11-28,我将blog框架更改为halo,并着手开始迁移工作,所以这个系列到此完结。