javascript - 在某些元素上从内部 for 循环重新开始编号
问题描述
我有一个插件,可以根据用户设置的自定义起始编号对标题标签进行编号。
它创建的标题如下:
1. Heading level one
1.1. Heading level two
1.1.1. Heading level three
如果用户手动设置起始编号:
20. Heading level one
20.3. Heading level two
20.3.6. Heading level three
但是,当循环重复时,编号不会重置为1
,我似乎无法解决如何触发它:
20. Heading level one
20.3. Heading level two
20.3.6. Heading level three
20. Heading level one
20.4. Heading level two
20.4.6. Heading level three <-- this should renumber to 20.4.1
在第一个循环之后,我无法将以下代码段重置回1
。我尝试过的一切都重置了所有迭代,导致header[3]
设置为1
但不仅在第一次迭代之后。
if( levelNumber <= elementLevel ) {
numberText += startingNumbers[levelNumber] + ".";
}
测试代码
const header = [10, 20, 30, 40, 50, 60],
contentHeaders = document.querySelectorAll(
'h1, h2, h3, h4, h5, h6'
),
startingNumbers = [ 0, // null
header[0] - 1, // h1
header[1] - 1, // h2
header[2] - 1, // h3
header[3] - 1, // h4
header[4] - 1, // h5
header[5] - 1, // h6
];
for( var item in contentHeaders ) {
// this element from item number
var element = contentHeaders[item],
numberText = '';
// limit the heading tag number in search
const headingRegex = new RegExp('^H([1-6])$');
// does the element match a heading regex
if( !element || !element.tagName || !element.tagName.match( headingRegex ) ) {
// return to beginning of loop
continue;
}
// return the heading level number
var elementLevel = RegExp.$1;
// increment by 1
startingNumbers[elementLevel]++;
// loop through the headings
for( var levelNumber = 1; levelNumber <= 6; levelNumber++ ) {
// if the number is lt the element number
if( levelNumber <= elementLevel ) {
numberText += startingNumbers[levelNumber] + ".";
}
}
element.innerHTML = numberText + ' ' + element.innerText;
}
* { font-family: monospace; font-size: 16px !important; }
<h1>Heading 1</h1>
<p>I should be <code>10. Heading 1</code></p>
<h2>Heading 2</h2>
<p>I should be <code>10.20. Heading 2</code></p>
<h3>Heading 3</h3>
<p>I should be <code>10.20.30. Heading 3</code></p>
<h4>Heading 4</h4>
<p>I should be <code>10.20.30.40. Heading 4</code></p>
<h5>Heading 5</h5>
<p>I should be <code>10.20.30.40.50. Heading 5</code></p>
<h6>Heading 6</h6>
<p>I should be <code>10.20.30.40.50.60. Heading 6</code></p>
<hr>
<h2>Heading 2</h2>
<p>I should be <code>10.21. Heading 2</code></p>
<h3>Heading 3</h3>
<p>I should be <code>10.21.1 Heading 3</code></p>
<hr>
<h2>Heading 2</h2>
<p>I should be <code>10.22. Heading 2</code></p>
<h3>Heading 3</h3>
<p>I should be <code>10.22.1. Heading 3</code></p>
<h4>Heading 4</h4>
<p>I should be <code>10.22.1.1. Heading 4</code></p>
解决方案
您可以创建一个数组来跟踪每个标题级别的第一次运行。如果不是第一次运行,则重置所有以下级别。
const header = [10, 20, 30, 40, 50, 60],
contentHeaders = document.querySelectorAll(
'h1, h2, h3, h4, h5, h6'
),
startingNumbers = [ 0, // null
header[0] - 1, // h1
header[1] - 1, // h2
header[2] - 1, // h3
header[3] - 1, // h4
header[4] - 1, // h5
header[5] - 1, // h6
];
// track the first run
let first_run = [true, true, true, true, true, true, true];
for( var item in contentHeaders ) {
// this element from item number
var element = contentHeaders[item],
numberText = '';
// limit the heading tag number in search
const headingRegex = new RegExp('^H([1-6])$');
// does the element match a heading regex
if( !element || !element.tagName || !element.tagName.match( headingRegex ) ) {
// return to beginning of loop
continue;
}
// return the heading level number
var elementLevel = RegExp.$1;
// increment by 1
startingNumbers[elementLevel]++;
// reset all level below except for the first run
if (!first_run[elementLevel]) resetBelowLevels(elementLevel);
first_run[elementLevel] = false;
// loop through the headings
for( var levelNumber = 1; levelNumber <= 6; levelNumber++ ) {
// if the number is lt the element number
if( levelNumber <= elementLevel ) {
numberText += startingNumbers[levelNumber] + ".";
}
}
element.innerHTML = numberText + ' ' + element.innerText;
}
function resetBelowLevels(current_level) {
// current_level is string so need to convert it to number
for(let i = +current_level + 1; i <= 6; i++) {
startingNumbers[i] = 0;
}
}
* { font-family: monospace; font-size: 16px !important; }
<h1>Heading 1</h1>
<p>I should be <code>10. Heading 1</code></p>
<h2>Heading 2</h2>
<p>I should be <code>10.20. Heading 2</code></p>
<h3>Heading 3</h3>
<p>I should be <code>10.20.30. Heading 3</code></p>
<h4>Heading 4</h4>
<p>I should be <code>10.20.30.40. Heading 4</code></p>
<h5>Heading 5</h5>
<p>I should be <code>10.20.30.40.50. Heading 5</code></p>
<h6>Heading 6</h6>
<p>I should be <code>10.20.30.40.50.60. Heading 6</code></p>
<hr>
<h2>Heading 2</h2>
<p>I should be <code>10.21. Heading 2</code></p>
<h3>Heading 3</h3>
<p>I should be <code>10.21.1 Heading 3</code></p>
<hr>
<h2>Heading 2</h2>
<p>I should be <code>10.22. Heading 2</code></p>
<h3>Heading 3</h3>
<p>I should be <code>10.22.1. Heading 3</code></p>
<h4>Heading 4</h4>
<p>I should be <code>10.22.1.1. Heading 4</code></p>
推荐阅读
- bash - Pyenv-virtualenv 未正确加载到 shell & .zshrc (已解决)
- python - 如何在 Python 中以任意大小栅格化 SVG
- java - 如何使每 5 秒发送消息到 rabbitmq 中的队列?
- discord.js - Discord.js:说有消息的频道中没有消息
- amazon-web-services - AWS Lambda 可以进行跨账户活动吗?
- python - 在 Python 中使用静态地址和偏移量从进程中读取内存地址
- java - 如何唤醒 OP_WRITE 事件的选择器(java NIO)?
- javascript - 如何获取 Github 外部的 Github 文件夹以显示特定文件夹内的文件
- ruby - 是否可以单独将 Puma 作为网络服务器运行?
- linux - 由于地址已在使用中,dovecot 无法启动