CSS+JS轻松实现自定义黑幕效果

引入

什么是“黑幕效果”呢?

[heimu]像这样[/heimu],正常状态下被一个黑条遮挡,只有当鼠标放在上面(移动端是长按)后才显示出内容的,富有交互性的有趣功能样式,就被成为“黑幕效果”。它可以让文章更加活泼,内容更加有趣,[heimu]以及表达一些特殊的语气~[/heimu]

这样,你就对黑幕效果有了一个基本的认知[heimu],阅读气氛也活跃起来了[/heimu],下面我们就来看一看小黑条的背后有哪些核心技术。

CSS部分

虽然大家都知道了,但还是简单提一句,CSS(Cascading Style Sheets,层叠样式表)是现代互联网技术中一个重要的组成部分,在前端开发中有着至关重要的地位。通过这种东西,我们可以方便地为网页中的内容添加丰富多彩的样式。

黑幕效果需要哪些样式呢?

我们再来看一下黑幕效果的呈现:[heimu]我是小黑条~[/heimu]

它的背景是黑色的,文字颜色与背景相同,所以正常状态下看不见文字内容。背景颜色在CSS中通过background-color属性控制,而前景色(也就是文字颜色啦)通过color属性控制,为了方便,我们定义一个.heimu类,这样所有class="heimu"的元素都可以自动获得我们规定的这些属性。就像这样:(现在请暂时不要记笔记,需要记笔记的时候我会提醒你哦)

.heimu {
    background-color: #000;
    color: #000;
}

这个东西怎么用呢?我们写一个测试页面看看:

<!doctype html>
<html>
<head>
<title>heimu test</title>
<style>
.heimu {
    background-color: #000;
    color: #000;
}
</style>
</head>
<body>
<p>This is <span class="heimu">heimu text</span>.</p>
</body>
</html>

测试页面的结果

(蓝色部分是我用鼠标选中造成的)还行,有那种感觉了,但是黑幕效果怎么变成了刮刮乐啊?

这是因为我们还没有处理鼠标移入(或移动端长按)时这个样式的变化。这部分我们使用:hover伪类实现,这个伪类将会在鼠标放上去的时候起作用,改变样式。

.heimu:hover, .heimu:active {
    color: #FFF;
}

实际使用时,我还使用了:active伪类,但它在此处作用不明显[heimu],仅仅是我出于心理安慰加上的[/heimu]。在测试页面中加入这部分内容,我们就基本完成啦~

实际使用时,不一定要用完完全全的黑色,只需要前景色与背景色一致即可;我们还可以加入渐变(用transition实现)。下面放出我使用的CSS部分内容,同学们可以记笔记啦~

.heimu:active, .heimu:hover {
    color: #fff
}

.heimu {
    background-color: #252525;
    color: #252525;
    text-shadow: none;
    transition: color 0.3s;
}

JS部分

通过前面的样式准备工作,我们已经可以通过<span class="heimu" title="你知道的太多了">小黑条~</span>这样的方式来调用我们的黑幕效果了,但是这样未免冗长,而且大部分都是重复内容。

我们规定一个自定义语法[heimu]xxx[/heimu],把一对这样的闭合标记解析为<span class="heimu" title="你知道的太多了">xxx</span>,中间内容不变,这样就可以大大降低我们调用时的工作量。这个工作可以交给插件实现,也可以交给js实现。出于性能考虑,我用js写了一个不算完整的实现。

用js进行替换的原理是正则匹配,在整个文章内容中按照DOM树遍历一次,完成整个替换。之所以没有直接替换是因为要规避一些特殊标记内的关键文本,例如数学公式和<code>元素。这样同时带来了一个缺陷,即黑幕效果只能覆盖简单文本,复杂文本(例如有链接的情况)当前版本是无法解析的。这里直接给出代码如下:

function icore_init() {
    var t = new RegExp("\\[heimu\\](.*?)\\[/heimu\\]","g");
    $("div.entry-content,div#morphing-content>div.page").children("p,blockquote,div.tip").each(function() {
        var n = "";
        $(this).contents().each(function() {
            var i = this.outerHTML;
            null == i && (i = $(this).text()),
            null != i && ((1 === this.nodeType || 3 === this.nodeType) && "IMG" != this.tagName && "PRE" != this.tagName && "CODE" != this.tagName && "SCRIPT" != this.tagName && "BR" != this.tagName ? -1 != $.inArray("light-link", this.classList) || function(t=this.classList) {
                if (null == t || null == t)
                    return !1;
                for (var n = 0; n < t.length; n++)
                    if (-1 != t[n].indexOf("MathJax"))
                        return !0;
                return !1
            }() ? n += i : (i = i.replace(t, function() {
                return '<span class="heimu" title="\u4f60\u77e5\u9053\u7684\u592a\u591a\u4e86">' + arguments[1] + "</span>"
            }),
            n += i) : n += i)
        }),
        $(this).html(n)
    });
}
icore_init();

[heimu]可以看到内容极其紊乱,其实是我混淆后找不到原文件了(悲[/heimu]

只对handsome主题5.x系列版本做了适配,不保证不出现未知问题,如有情况可以评论联系我,但不保证解决。

如果开启pjax,请在pjax回调函数中加入icore_init();,否则无刷新加载后不会进行解析。(handsome主题的该配置项位于“PJAX->PJAX回调函数”中,如果其中已经有代码,加入在末尾即可)

title属性可以自定义,该属性规定的是鼠标放上去后显示的文本。

至此,黑幕效果背后的黑科技已经完全呈现在你眼前了~

顺便说一句,这部分内容也包括在我的自定义增强效果iCore(不过暂时没有开源,因为内容太少了)中哦~

最后修改:2019 年 12 月 07 日 11 : 53 AM
欢迎投食喵 ~

发表评论

6 条评论

  1. luyipao

    跟大佬贴贴ヾ(•ω•`)o

  2. 成人之美

    有空试试。

  3. Akara

    大佬,icore的插件什么时候来

  4. ForkKILLET

    实际上 使用自(纯)定(脑)义(补)的「新标签」可以更为简洁地实现「自定义语法」的功能。
    具体来说:<heimu>一些不可告人的文字</heimu>
    我们先用 JQ 添加 title:$("heimu").attr("title", "你知道的太多了"); 这样就不用进行正则匹配了!
    CSS 的部分用 heimu { ... } 就好啦!

    ForkKILLET 每日朝拜 UCW 已完成 %%% (1/1)

  5. 蝉時雨

    单纯用 CSS 好像也可以实现,只是针对可以自定义内容解析的博客主题~

  6. UCW是苣佬

    UCW苣佬牛批!