1. 前言
想给我的博客网站中的正文内容,增加一个自动生成目录的功能,当页面中有标题元素(h1\h2\h3)时,自动创建目录,然后固定在网页的左侧,方便导航和阅读。
2. 生成插件
2.1 js代码
我想基于jquery写一个插件,在web网页的正文中,读取h1、h2、h3标签的标题内容,自动生成目录,固定呈现于网页的左侧,点击目录中的节点,可以跳转到对应的标题
chatGPT:
(function($) {
$.fn.generateTableOfContents = function() {
var $this = $(this);
var $tocContainer = $('<div class="toc-container"></div>');
var $tocList = $('<ul class="toc-list"></ul>');
$this.find('h1, h2, h3').each(function() {
var $heading = $(this);
var tagName = $heading.prop('tagName').toLowerCase();
var title = $heading.text();
var $tocItem = $('<li></li>');
var $tocLink = $('<a></a>');
$tocLink.text(title);
$tocLink.attr('href', '#' + $heading.attr('id'));
$tocLink.on('click', function(event) {
event.preventDefault();
$('html, body').animate({ scrollTop: $heading.offset().top }, 'slow');
});
$tocItem.addClass('toc-' + tagName);
$tocItem.append($tocLink);
$tocList.append($tocItem);
});
$tocContainer.append($tocList);
$this.prepend($tocContainer);
};
})(jQuery);
$(document).ready(function() {
$('.content').generateTableOfContents();
});
2.2 CSS代码
.toc-container {
position: fixed;
left: 20px;
top: 50px;
background-color: #f1f1f1;
padding: 10px;
border-radius: 5px;
}
.toc-list {
list-style: none;
padding: 0;
}
.toc-list li {
margin-bottom: 5px;
}
.toc-h1 {
margin-left: 0;
}
.toc-h2 {
margin-left: 10px;
}
.toc-h3 {
margin-left: 20px;
}
.toc-list a {
text-decoration: none;
color: #333;
}
.toc-list a:hover {
color: #000;
}
优化上面的css,风格参考bootstrap,然后chat返回:
.toc-container {
position: fixed;
left: 20px;
top: 50px;
background-color: #f8f9fa;
padding: 10px;
border-radius: 5px;
width: 200px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.toc-list {
list-style: none;
padding: 0;
margin: 0;
}
.toc-list li {
margin-bottom: 5px;
}
.toc-h1 {
margin-left: 0;
}
.toc-h2 {
margin-left: 20px;
}
.toc-h3 {
margin-left: 40px;
}
.toc-list a {
text-decoration: none;
color: #212529;
display: block;
padding: 2px 0;
}
.toc-list a:hover {
color: #0d6efd;
}
.toc-list .active {
font-weight: bold;
color: #0d6efd;
}
3. 优化插件
3.1 优化1
修改一下插件的代码,增加如下逻辑:读取页面中是否存在id为wpadminbar的元素,如果存在,则获取这个元素高度,然后给$tocContainer的css的top属性增加该高度。
chatGPT:
(function($) {
$.fn.generateTableOfContents = function() {
var $this = $(this);
var $tocContainer = $('<div class="toc-container"></div>');
var $tocList = $('<ul class="toc-list"></ul>');
$this.find('h1, h2, h3').each(function() {
var $heading = $(this);
var tagName = $heading.prop('tagName').toLowerCase();
var title = $heading.text();
var $tocItem = $('<li></li>');
var $tocLink = $('<a></a>');
$tocLink.text(title);
$tocLink.attr('href', '#' + $heading.attr('id'));
$tocLink.on('click', function(event) {
event.preventDefault();
$('html, body').animate({ scrollTop: $heading.offset().top }, 'slow');
});
$tocItem.addClass('toc-' + tagName);
$tocItem.append($tocLink);
$tocList.append($tocItem);
});
$tocContainer.append($tocList);
$this.prepend($tocContainer);
var $wpAdminBar = $('#wpadminbar');
if ($wpAdminBar.length) {
var adminBarHeight = $wpAdminBar.outerHeight();
$tocContainer.css('top', adminBarHeight + 'px');
}
};
})(jQuery);
3.2 优化2
继续修改插件代码,一是如果页面宽度小于1440时,自动隐藏目录,二是如果没有找到h1、h2、h3,则不生成目录。
chatGTP:
(function($) {
$.fn.generateTableOfContents = function() {
var $this = $(this);
var $tocContainer = $('<div class="toc-container"></div>');
var $tocList = $('<ul class="toc-list"></ul>');
var headings = $this.find('h1, h2, h3');
if (headings.length === 0) {
return; // 没有找到标题,不生成目录
}
headings.each(function() {
var $heading = $(this);
var tagName = $heading.prop('tagName').toLowerCase();
var title = $heading.text();
var $tocItem = $('<li></li>');
var $tocLink = $('<a></a>');
$tocLink.text(title);
$tocLink.attr('href', '#' + $heading.attr('id'));
$tocLink.on('click', function(event) {
event.preventDefault();
$('html, body').animate({ scrollTop: $heading.offset().top }, 'slow');
});
$tocItem.addClass('toc-' + tagName);
$tocItem.append($tocLink);
$tocList.append($tocItem);
});
$tocContainer.append($tocList);
$this.prepend($tocContainer);
var $wpAdminBar = $('#wpadminbar');
if ($wpAdminBar.length) {
var adminBarHeight = $wpAdminBar.outerHeight();
$tocContainer.css('top', adminBarHeight + 'px');
}
var minWidth = 1440;
if ($(window).width() < minWidth) {
$tocContainer.hide();
}
$(window).resize(function() {
if ($(window).width() < minWidth) {
$tocContainer.hide();
} else {
$tocContainer.show();
}
});
};
})(jQuery);
4. 后记
复制代码到我的博客后端,简单调整了几个参数,即可运行,全程就10分钟的事情。
chatGPT辅助写代码,效率杠杠的!