威言威语
我愿像茶,苦涩留心,清香予人。
威言威语
当前位置: 首页 > 网络 > 正文

纯代码实现WordPress多级文章目录索引

在Wordpress文章中合理的使用文章目录这个功能,可以有效帮助访客快速了解文章的内容结构,提升阅读体验。本文通过代码方式将h2-h6标题自动生成文章目录索引,并可实现多层级展示。
纯代码实现WordPress多级文章目录索引
目录
文章目录隐藏
  1. 效果预览
  2. 核心代码
  3. CSS代码
  4. jQuery代码
  5. 这里是演示标题

在写文章的时候,为了结构更加清晰,我们会添加h2-h6标签来展示段落标题,我们把这些段落标题整合起来做成文章目录并加上锚点,可以有效帮助访客快速了解文章的内容结构,提升阅读体验。

本文分享一段免插件生成WordPress文章目录的代码,可以将h2-h6标签自动生成文章目录索引,并可实现多层级展示。

效果预览

WordPress多级文章目录

核心代码

将下面代码添加到当前主题函数模板functions.php中,通过代码中注释可以知道文章目录是获取h2-h6的标题,同时h标签的个数大于2才生效,也就是文章中要有3个及以上才展示,当然你也可以自行修改数量。


// 构建文章多级目录索引
function buildDirectory($titleIndexArr, $titleContentArr, &$index, &$html)
{
	$size = sizeof($titleIndexArr);
	$flag = $index == 0;
	$html .= $flag ? '<ol id="index-ol">' : '<ul id="index-ul">';
	while ($index < $size) {
		$title = trim(strip_tags($titleContentArr[$index])); // 标题内容
		$h = $titleIndexArr[$index]; // 几级标题
		$html .= '<li><a href="#title-' . $index . '" title="' . $title . '">' . $title . "</a></li>";
		if ($index == $size - 1) { //最后一个
			$index++;
			break;
		}
		$next_h = $titleIndexArr[++$index]; // 下个标题是几级标题
		if ($h < $next_h) { // 子标题递归
			buildDirectory($titleIndexArr, $titleContentArr, $index, $html);
			if ($index >= $size || $h > $titleIndexArr[$index]) {
				break;
			}
		} else if ($h > $next_h) {
			break;
		}
	}
	$html .= $flag ? '</ol>' : '</ul>';
}
function article_index($content)
{
	$html = '';
	$matches = array();
	// 当前设置 [2-6]即 h2 到 h6 可以自己修改下面正则
	$r = '/<h([2-6])(.*?)>(.*?)<\/h[2-6]>/is';
	// preg_match_all 函数用于执行一个全局正则表达式匹配。$r=正则,$content=文章内容,$matches=作为输出参数输出所有匹配结果
	preg_match_all($r, $content, $matches);
	$num_match = count($matches[0]);
	// 用于文章页,同时h标签个数大于2个才生效
	if ( is_single() && ($num_match > 2) ) {
		foreach ($matches[1] as $key => $value) {
			// strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签
			$title = trim(strip_tags($matches[3][$key])); //文章标题
			// 文章原标题添加锚点
			$content = str_replace($matches[0][$key], '<h' . $value . ' id="title-' . $key . '"' . $matches[2][$key] . '>' . $title . '</h' . $value . '>', $content);
		}
		$titleIndexArr = $matches[1];
		$titleContentArr = $matches[3];
		$index = 0;
		$html .= "\n".'<div id="article-index-show">目录</div><div id="article-index"><div id="article-index-top"><strong>文章目录</strong><span id="article-index-hide">隐藏</span></div>';
		buildDirectory($titleIndexArr, $titleContentArr, $index, $html);
		$html .= '</div>'."\n";
	}
	return $html. $content;
}
add_filter('the_content', 'article_index');

CSS代码

将文章目录固定在浏览器左侧中间,这样外观比较独立,不容易受原主题样式的影响,按钮颜色可以根据自己使用的主题颜色调整,保持统一。


#article-index{position:fixed;top:50%;transform:translateY(-50%);left:0;width:156px;max-height:76%;padding:0 10px;font-size:14px;border-radius:0 6px 6px 0;background-color:#fff;box-shadow:0 0 5px rgba(0, 0, 0, .4);overflow:auto;z-index:99;display:none;}
#article-index-top{position:sticky;top:0;z-index:92;background:#fff;}
#article-index strong{display:block;font-size:16px;padding:10px 0 12px 5px;}
#index-ol{list-style:square;}
#index-ol li{padding:0;margin-left:16px;line-height:24px;position:relative;list-style-position:inherit;word-break:break-all;}
#index-ul{list-style:circle;margin:0;padding:5px 0 5px 8px;}
#index-ul li:before{display:none;}
#article-index-show{position:fixed;top:50%;transform:translateY(-50%);left:0;display:block;
width:50px;height:36px;line-height:36px;text-align:center;font-size:14px;border-radius:0 36px 36px 0;color:#fff;background-color:#0088dd;cursor:pointer;}
#article-index-hide{position:absolute;right:0;top:5px;display:block;
width:32px;height:32px;line-height:32px;text-align:center;font-size:12px;border-radius:100%;background-color:#d2ddff;cursor:pointer;}
#article-index-hide:hover{color:#fff;background-color:#0088dd;}

jQuery代码

需要加载jquery.js


//文章目录展示切换
jQuery(document).ready(function(){
	jQuery("#article-index-hide").click(function(){
		jQuery("#article-index").hide(100);
		jQuery("#article-index-show").show(200);
	});
	jQuery("#article-index-show").click(function(){
		jQuery("#article-index").show(200);
		jQuery("#article-index-show").hide(100);
	});
});

//文章目录锚点点击平滑滚动
jQuery(document).on('click', '#article-index a[href^="#"]', function(e) {
	var id = jQuery(this).attr('href');
	var $id = jQuery(id);
	if ($id.length === 0) {
		return;
	}
	e.preventDefault();
	var pos = $id.offset().top;
	jQuery('body, html').animate({scrollTop: pos});
});

这里是演示标题

这里是子标题一
这里是孙标题一
这里是孙标题二
这里是子标题二

您可能还会对这些文章感兴趣!

纯代码实现WordPress多级文章目录索引:目前有 10 条评论

  1. 等等
    6楼
    等等:Google Chrome 122.0.6261.95 Windows 10

    你好,我想问一下目录内容在目录中,按照你代码中像是居中对齐的样式,想改成像你现在这样靠左对齐应该改哪行代码呢

    2024-09-05 15:55 回复
    • William
      WilliamGoogle Chrome 128.0.0.0 Windows 11

      @等等我自己用的样式就和上面的基本一样,你的居中可能是被你原本的样式影响了。
      你可以试一下在样式第5行的 #index-ol li 里面加个 text-align: left;

      2024-09-05 21:11 回复
  2. 老宋
    5楼
    老宋:Google Chrome 109.0.0.0 Windows 10

    你们都是能写程序的,看这个似乎简单,对我这个不懂的,就有点难了,前两步做好了,最后一步jQuery代码是要插在哪个地方呢?

    2024-01-06 20:12 回复
    • William
      WilliamFirefox 121.0 Windows 10

      @老宋你可以加那段代码放在主题js文件夹的weisay.js的最后就行。

      2024-01-08 10:20 回复
  3. 微笑
    4楼
    微笑:Google Chrome 79.0.3945.130 Windows 10

    这种好像最好类似h3在文章前面,后面再出现h4、h5,不然假如文章先出现h5,后面再是h4,那么h4之后的标题就不展示在侧边的文章目录了。

    2020-02-03 14:14 回复
    • William
      William神马浏览器 3.5.10 Android 10

      @微笑是有这个问题,不过想来大家写h标签应该规范一些,数字从小到大。

      2020-05-11 15:10 回复
  4. 科学幻想
    地板
    科学幻想:Google Chrome 55.0.2883.87 Windows 7

    自己加到主题里面还是挺方便的。

    2017-12-16 17:08 回复
  5. 踏雪寻梅
    板凳
    踏雪寻梅:Google Chrome 57.0.2987.133 Windows 10

    看着效果挺不错的,网上其他的代码不支持大于3个才展示文章目录,这个有这个功能,不错。

    2017-05-29 23:22 回复
  6. 火星
    沙发
    火星:Google Chrome 58.0.3029.81 Mac OS X  10.12.4

    挺好的,我也来试试看。

    2017-05-27 21:51 回复

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

gravatar

question razz sad smile redface biggrin eek shock confused cool lol mad rolleyes wink cry