/ 技术 / 352浏览

Farallon 主题美化之代码高亮与复制

文章目录
  • 代码高亮
  • 复制按钮
  • 最近给博客换了个比较轻量的主题,是博主 bigfa 的 Farallon 主题,很是简洁轻盈美观。但是原主题代码显示比较简陋,代码没有高亮且在小屏幕上会自动换行,阅读有些费力。我尝试使用了一些第三方插件但是没有效果,于是我在不破坏原主题的基础上进行高亮美化和增加复制代码的功能。

    这个方法不仅适用于 Farallon 主题,理论上任何主题都可以这样修改。

    代码高亮

    代码高亮我使用的是 highlight.js 这个库,样式我选择的是 vs2015 ,个人比较喜欢这个效果。

    首先到 highlightJS 官网下载 highlightJS 的文件:https://highlightjs.org/download

    当然也可以使用外部链接的方式引入脚本和样式,这里先以本地为例进行使用。

    下载完 highlightJS 的文件。在主题的目录下创建 /assets/js 和 /assets/css 文件夹,用于存放要加载的 js 和css 资源文件。将 highlightJS 的 highlight.min.js 文件存放到主题的 /assets/js 目录下,将 vs2015.css 文件存放到主题的 /assets/css 目录下。

    打开主题的 functions.php 文件,添加一下代码引入样式和脚本:

    //代码高亮设置
    function add_code_highlight() {
        // 引入样式
        wp_enqueue_style(
            'highlightjs-style',
            get_template_directory_uri() . '/assets/css/vs2015.css'
        );
        
        // 引入脚本
        wp_enqueue_script(
            'highlightjs',
            get_template_directory_uri() .'/assets/js/highlight.min.js',
            array(),
            true 
        );
        
        wp_add_inline_script('highlightjs', 'hljs.highlightAll();');
    }
    add_action('wp_enqueue_scripts', 'add_code_highlight');

    修改完成后就可以看到高亮效果了,但是小屏幕上显示是比较乱的。对于一行比较长的代码会自动换行,观感不是很好。在wp的自定义的额外css里添加以下代码可以强制代码不换行和增加滚动条样式。

    /* 强制代码块不换行 */
    pre code {
        white-space: pre !important;
        overflow-x: auto !important;
        display: block;
    }
    
    /* 为横向滚动条添加样式 */
    pre::-webkit-scrollbar {
        height: 8px;
        background-color: #f5f5f5;
    }
    
    pre::-webkit-scrollbar-thumb {
        background: #888;
        border-radius: 4px;
    }
    

    注意:如果要使用外部链接的方式引入资源文件,那么删掉 functions 里的 get_template_directory_uri() . 代码,把相对路径里的内容改成链接。

    //从主题目录下引入
    get_template_directory_uri() .'/assets/js/highlight.min.js'
    //从外部链接引入
    ‘https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js’

    复制按钮

    大多数网站支持一键复制代码块里的代码,我觉得这个功能很有必要,所以就加上了。

    为了不破坏原主题的样式,我使用 JavaScript 脚本对主题进行添加按钮。所以同样需要 js 和 css 文件。分别在 assets 目录的对应的路径创建 js 和 css 文件。

    创建 code-copy.js

    document.addEventListener('DOMContentLoaded', () => {
        const createButton = () => {
            const btn = document.createElement('button');
            btn.className = 'code-copy-btn';
            btn.textContent = '复制代码';
            btn.setAttribute('aria-label', '复制代码到剪贴板');
            return btn;
        };
    
        const showFeedback = () => {
            const existing = document.querySelector('.copy-success');
            if (existing) existing.remove();
    
            const feedback = document.createElement('div');
            feedback.className = 'copy-success';
            feedback.textContent = '✓ 已复制到剪贴板!';
    
            document.body.appendChild(feedback);
            setTimeout(() => feedback.remove(), 2000);
        };
    
        document.addEventListener('click', async (e) => {
            if (!e.target.closest('.code-copy-btn')) return;
    
            const btn = e.target;
            const pre = btn.closest('pre');
            const code = pre?.querySelector('code');
    
            if (!code) return;
    
            try {
                const decoded = code.textContent.replace(/\u00A0/g, ' ').trim();
                await navigator.clipboard.writeText(decoded);
                showFeedback();
               
                btn.disabled = true;
                setTimeout(() => btn.disabled = false, 1500);
            } catch (err) {
                console.error('复制失败:', err);
                alert('复制失败,请手动选择代码复制');
            }
        });
    
        const observer = new MutationObserver(mutations => {
            mutations.forEach(({ addedNodes }) => {
                addedNodes.forEach(node => {
                    if (node.nodeType === 1 && node.matches('pre')) {
                        if (!node.querySelector('.code-copy-btn')) {
                            node.prepend(createButton());
                        }
                    }
                });
            });
        });
    
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    
        document.querySelectorAll('pre').forEach(pre => {
            if (!pre.querySelector('.code-copy-btn')) {
                pre.prepend(createButton());
            }
        });
    });
    

    创建 code-copy.css

    pre {
        position: relative !important;
        margin: 1.5em 0;
        padding-top: 2em !important;
    }
    
    .code-copy-btn {
        --btn-bg: rgba(40, 40, 40, 0.8);
        --btn-hover-bg: rgba(60, 60, 60, 0.9);
        
        position: absolute;
        right: 12px;
        top: 8px;
        padding: 4px 12px;
        background: var(--btn-bg);
        color: #fff;
        border: 1px solid rgba(255,255,255,0.1);
        border-radius: 4px;
        cursor: pointer;
        opacity: 0;
        transition: 
            opacity 0.25s ease,
            background 0.2s ease;
        backdrop-filter: blur(2px);
        z-index: 10;
    }
    
    pre:hover .code-copy-btn,
    .code-copy-btn:focus {
        opacity: 1;
        background: var(--btn-hover-bg);
    }
    
    /* 优化移动端显示 */
    @media (hover: none) {
        .code-copy-btn {
            opacity: 0.8 !important;
        }
    }
    
    
    .copy-success {
        position: fixed;
        bottom: 20px;
        right: 20px;
        background: #4CAF50;
        color: white;
        padding: 15px;
        border-radius: 4px;
        animation: fadeOut 2s forwards;
        animation-delay: 1s;
    }
    
    @keyframes fadeOut {
        from { opacity: 1; }
        to { opacity: 0; }
    }

    functions.php 中添加功能

    // 添加复制按钮功能
    function register_code_copy_assets() {
        wp_register_style('code-copy-style', 
            get_theme_file_uri('/assets/css/code-copy.css'),
            array(),
            '1.1'
        );
        
        wp_register_script('code-copy-script',
            get_theme_file_uri('/assets/js/code-copy.js'),
            array(),
            '1.2',
            true
        );
        
        wp_enqueue_style('code-copy-style');
        wp_enqueue_script('code-copy-script');
    }
    add_action('wp_enqueue_scripts', 'register_code_copy_assets');

    至此,就完成了代码块的功能修改,看看效果。当鼠标点击代码块时会出现 复制代码 的按钮,复制时在右下角会有临时的弹窗小提示。

    这里荒芜寸草不生 后来你来这走了一遭 奇迹般万物生长 这里是我的心

    0

    1. This post has no comment yet

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注