代码高亮组件

一个基于highlight.js的代码高亮组件,支持多种编程语言的语法高亮显示

组件简介

本代码高亮组件基于highlight.js构建,支持HTML、CSS、JavaScript和PHP四种常用编程语言的语法高亮。组件具有响应式设计、支持代码复制功能、可切换的主题样式以及行号显示等特性,为开发者提供美观、实用的代码展示体验。

组件特性

  • 支持HTML、CSS、JavaScript和PHP四种编程语言的语法高亮
  • 响应式设计,适配各种屏幕尺寸
  • 提供多种主题样式选择
  • 自动生成行号,支持行号显示/隐藏
  • 代码复制功能,一键复制代码内容
  • 支持代码折叠/展开功能
  • 支持暗色/亮色模式切换
  • 支持代码搜索和高亮功能

HTML代码示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>代码高亮组件示例</title>
    <link rel="stylesheet" href="/static/css/codes.css">
</head>
<body>
    <div class="container">
        <header class="page-header">
            <h1>欢迎使用代码高亮组件</h1>
        </header>
        
        <main class="main-content">
            <div class="code-example">
                <pre><code class="language-javascript">// 这里是JavaScript代码示例
function helloWorld() {
    console.log('Hello, world!');
}</code></pre>
            </div>
        </main>
    </div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
    <script>
        hljs.highlightAll();
    </script>
</body>
</html>

CSS代码示例

/* CSS代码示例 */
.code-container {
    position: relative;
    margin: 20px 0;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

pre {
    margin: 0;
    background-color: #f5f5f5;
    padding: 20px;
    overflow-x: auto;
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
    font-size: 14px;
    line-height: 1.5;
}

code {
    background: none;
    padding: 0;
    font-size: inherit;
}

.copy-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    padding: 5px 10px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 12px;
    opacity: 0;
    transition: opacity 0.3s;
}

.code-container:hover .copy-btn {
    opacity: 1;
}

@media (max-width: 768px) {
    pre {
        padding: 15px;
        font-size: 13px;
    }
}

JavaScript代码示例

/**
 * JavaScript代码示例
 * 一个简单的代码高亮组件实现
 */
class CodeHighlight {
    constructor(options = {}) {
        this.options = {
            selector: '.code-example pre code',
            theme: 'github',
            lineNumbers: true,
            copyable: true,
            ...options
        };
        
        this.init();
    }
    
    init() {
        // 初始化highlight.js
        if (typeof hljs !== 'undefined') {
            this.highlightAll();
            
            // 添加行号
            if (this.options.lineNumbers) {
                this.addLineNumbers();
            }
            
            // 添加复制功能
            if (this.options.copyable) {
                this.addCopyButtons();
            }
        } else {
            console.error('highlight.js is not loaded');
        }
    }
    
    highlightAll() {
        hljs.highlightAll();
    }
    
    addLineNumbers() {
        const codeBlocks = document.querySelectorAll(this.options.selector);
        
        codeBlocks.forEach(block => {
            const lines = block.textContent.split('\n').length;
            const lineNumbers = document.createElement('div');
            lineNumbers.className = 'line-numbers';
            
            for (let i = 1; i <= lines; i++) {
                const line = document.createElement('span');
                line.textContent = i;
                lineNumbers.appendChild(line);
            }
            
            block.parentElement.classList.add('with-line-numbers');
            block.parentElement.appendChild(lineNumbers);
        });
    }
    
    addCopyButtons() {
        const preElements = document.querySelectorAll(`${this.options.selector.split(' ')[0]}`);
        
        preElements.forEach(pre => {
            const copyBtn = document.createElement('button');
            copyBtn.className = 'copy-btn';
            copyBtn.textContent = '复制代码';
            copyBtn.addEventListener('click', () => {
                const code = pre.querySelector('code').textContent;
                navigator.clipboard.writeText(code).then(() => {
                    copyBtn.textContent = '已复制!';
                    setTimeout(() => {
                        copyBtn.textContent = '复制代码';
                    }, 2000);
                });
            });
            
            pre.parentElement.appendChild(copyBtn);
        });
    }
    
    changeTheme(theme) {
        // 移除当前主题样式
        const existingTheme = document.querySelector('link[href*="highlight.js"]');
        if (existingTheme) {
            document.head.removeChild(existingTheme);
        }
        
        // 添加新主题样式
        const themeLink = document.createElement('link');
        themeLink.rel = 'stylesheet';
        themeLink.href = `https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/${theme}.min.css`;
        document.head.appendChild(themeLink);
        
        this.options.theme = theme;
    }
}

// 使用示例
// document.addEventListener('DOMContentLoaded', () => {
//     const codeHighlight = new CodeHighlight({
//         lineNumbers: true,
//         copyable: true
//     });
// });

PHP代码示例

<?php
/**
 * PHP代码示例
 * 一个简单的代码高亮组件类
 */
class CodeHighlightComponent {
    /**
     * @var array 配置选项
     */
    protected $options = [];
    
    /**
     * @var array 支持的语言
     */
    protected $supportedLanguages = ['html', 'css', 'javascript', 'php'];
    
    /**
     * 构造函数
     * 
     * @param array $options 配置选项
     */
    public function __construct(array $options = []) {
        $this->options = array_merge([
            'theme' => 'github',
            'lineNumbers' => true,
            'copyable' => true,
            'language' => 'php'
        ], $options);
    }
    
    /**
     * 渲染代码高亮组件
     * 
     * @param string $code 要高亮的代码
     * @param string $language 代码语言
     * @return string 渲染后的HTML
     */
    public function render($code, $language = null) {
        $language = $language ?: $this->options['language'];
        
        // 检查语言是否受支持
        if (!in_array($language, $this->supportedLanguages)) {
            $language = 'php'; // 默认使用PHP语法高亮
        }
        
        $html = '<div class="code-container">';
        
        // 添加复制按钮
        if ($this->options['copyable']) {
            $html .= '<button class="copy-btn">复制代码</button>';
        }
        
        // 添加代码块
        $html .= '<pre';
        
        // 添加行号支持
        if ($this->options['lineNumbers']) {
            $html .= ' class="with-line-numbers"';
        }
        
        $html .= '><code class="language-' . $language . '">' . htmlspecialchars($code) . '</code></pre>';
        
        // 添加行号
        if ($this->options['lineNumbers']) {
            $lines = substr_count($code, "\n") + 1;
            $html .= '<div class="line-numbers">';
            for ($i = 1; $i <= $lines; $i++) {
                $html .= '<span>' . $i . '</span>';
            }
            $html .= '</div>';
        }
        
        $html .= '</div>';
        
        return $html;
    }
    
    /**
     * 获取支持的主题列表
     * 
     * @return array 主题列表
     */
    public function getAvailableThemes() {
        return [
            'github', 'atom-one-dark', 'github-gist', 'vs2015',
            'solarized-dark', 'monokai', 'dracula'
        ];
    }
    
    /**
     * 获取支持的语言列表
     * 
     * @return array 语言列表
     */
    public function getSupportedLanguages() {
        return $this->supportedLanguages;
    }
}

// 使用示例
// $codeHighlight = new CodeHighlightComponent([
//     'theme' => 'atom-one-dark',
//     'lineNumbers' => true
// ]);
// 
// $code = 'function hello() { echo "Hello, World!"; }';
// echo $codeHighlight->render($code, 'php');

使用指南

1. 基本使用

要在您的项目中使用代码高亮组件,首先需要引入highlight.js库和组件的CSS文件:

<!-- 引入highlight.js样式文件 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/github.min.css">

<!-- 引入组件CSS文件 -->
<link rel="stylesheet" href="/static/css/codes.css">

<!-- 引入highlight.js脚本 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>

<!-- 初始化highlight.js -->
<script>
    document.addEventListener('DOMContentLoaded', function() {
        hljs.highlightAll();
    });
</script>

2. HTML结构

使用以下HTML结构来创建代码高亮区块:

<div class="code-example">
    <div class="example-header">
        <h3>代码标题</h3>
        <div class="example-actions">
            <button class="copy-btn" data-target="code-id">复制代码</button>
            <button class="theme-btn" data-theme="github">GitHub主题</button>
            <button class="line-numbers-btn">切换行号</button>
        </div>
    </div>
    <div class="code-container">
        <pre><code id="code-id" class="language-html">HTML代码内容</code></pre>
    </div>
</div>

3. 支持的语言

本组件支持以下四种编程语言的语法高亮:

  • HTML - 使用 class="language-html"
  • CSS - 使用 class="language-css"
  • JavaScript - 使用 class="language-javascript"
  • PHP - 使用 class="language-php"

4. 主题切换

highlight.js提供了多种主题样式,您可以通过以下方式切换主题:

// 切换到暗色主题
function changeTheme(themeName) {
    // 移除当前主题样式
    const existingTheme = document.querySelector('link[href*="highlight.js"]');
    if (existingTheme) {
        document.head.removeChild(existingTheme);
    }
    
    // 添加新主题样式
    const themeLink = document.createElement('link');
    themeLink.rel = 'stylesheet';
    themeLink.href = `https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/${themeName}.min.css`;
    document.head.appendChild(themeLink);
}

5. 代码复制功能

组件内置了代码复制功能,可以通过以下JavaScript实现:

// 代码复制功能实现
function setupCopyButtons() {
    const copyButtons = document.querySelectorAll('.copy-btn');
    
    copyButtons.forEach(button => {
        button.addEventListener('click', () => {
            const targetId = button.getAttribute('data-target');
            const codeElement = document.getElementById(targetId);
            
            if (codeElement) {
                const code = codeElement.textContent;
                
                navigator.clipboard.writeText(code).then(() => {
                    const originalText = button.textContent;
                    button.textContent = '已复制!';
                    
                    setTimeout(() => {
                        button.textContent = originalText;
                    }, 2000);
                }).catch(err => {
                    console.error('复制失败:', err);
                });
            }
        });
    });
}

6. 行号显示

组件支持代码行号显示功能,可以通过以下CSS和JavaScript实现:

/* 行号样式 */
.code-container.with-line-numbers {
    position: relative;
    padding-left: 40px;
}

.line-numbers {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    width: 40px;
    background-color: #f1f1f1;
    border-right: 1px solid #ddd;
    text-align: right;
    padding: 20px 8px;
    font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
    font-size: 14px;
    line-height: 1.5;
    color: #999;
    user-select: none;
}

.line-numbers span {
    display: block;
}

响应式设计

代码高亮组件具有完全的响应式设计,在不同屏幕尺寸下都能良好显示:

  • 在桌面端显示完整的代码高亮效果,包括行号、复制按钮等
  • 在平板设备上自动调整布局,保持代码的可读性
  • 在移动设备上优化显示效果,确保代码可以横向滚动查看
  • 触摸设备上支持滑动手势,方便查看长代码

无障碍支持

代码高亮组件考虑了无障碍访问需求:

  • 所有交互元素都有适当的aria-属性
  • 支持键盘导航,可以使用Tab键聚焦并操作按钮
  • 高对比度模式下自动调整样式
  • 代码文本与背景的对比度符合WCAG AA标准