CodePudding user response:
The Javascript that I used from the link you provided didn't return the counter values indeed.
From what I read I think there is no way you can access the css counter values: How can I read the applied CSS-counter value?
What you could do is recreate the outline of the document (TOC) with Javascript including the css numbering. I guess that's what you're asking, right?
Does this code fit the bill?
const elems = Array.from(document.querySelectorAll('body > *'))
let ch1 = 0
let ch2 = 0
let ch3 = 0
let s = ''
elems
.filter(el =>
el.tagName.toLowerCase() == 'h1'
|| el.tagName.toLowerCase() == 'h2'
|| el.tagName.toLowerCase() =='h3')
.forEach(el => {
if(el.tagName.toLowerCase() == 'h1') {
ch1
ch2 = 0
ch3 = 0
}
if(el.tagName.toLowerCase() == 'h2') {
ch2
ch3 = 0
}
if(el.tagName.toLowerCase() == 'h3') ch3
if(ch2 == 0 && ch3 == 0) {
s = `<div>${ch1}. ${el.textContent}</div>`
}
else if (ch3 == 0) {
s = `<div>${ch1}.${ch2}. ${el.textContent}</div>`
}
else {
s = `<div>${ch1}.${ch2}.${ch3}. ${el.textContent}</div>`
}
})
let toc = document.createElement('div');
toc.innerHTML = s;
document.body.appendChild(toc)
<h1 >H1: D...</h1>
<h2 >H2: Z...</h2>
<p >D...</p>
<ul >
<li >B...</li>
<li >U...</li>
</ul>
<p >D...</p>
<h2 >H2: C...</h2>
<p >D...</p>
<p >A...</p>
<h2 >H2: E...</h2>
<h3 >H3: S...</h3>
<p >U...</p>
<h3 >H3: R...</h3>
<p >S...</p>
<h3 >H3: L...</h3>
<p >S...</p>
<h1 >H1: W...</h1>
<p >N...</p>
CodePudding user response:
Just as an exercise and for the fun of it I made another version using recursion.
Anyway, user romellem made a good point about using css counters in the toc too so maybe that's a better solution.
const el = document.querySelector('body > *')
let nums = []
let tocArr = []
const buildToc = (el, nums, tocArr) => {
if(el == null) return
const secondChar = el.tagName.charAt(1)
const isHeading = (secondChar != '' && !isNaN(secondChar))
if(!isHeading) {
buildToc(el.nextElementSibling, nums, tocArr)
return
}
const index = parseInt(secondChar)
nums = nums.slice(0, index)
while(nums.length < index) {
nums.push(0)
}
nums[index - 1]
nums.length = index
tocArr.push({
content: el.textContent,
nums: nums.join('.')
})
buildToc(el.nextElementSibling, nums, tocArr)
}
buildToc(el, nums, tocArr)
tocArr.forEach(el => {
let tocItem = document.createElement('div');
tocItem.textContent = el.nums ' ' el.content
document.body.appendChild(tocItem)
})
<h1 >H1: D...</h1>
<h2 >H2: Z...</h2>
<p >D...</p>
<ul >
<li >B...</li>
<li >U...</li>
</ul>
<p >D...</p>
<h2 >H2: C...</h2>
<p >D...</p>
<p >A...</p>
<h2 >H2: E...</h2>
<h3 >H3: S...</h3>
<p >U...</p>
<h2 >H3: R...</h3>
<p >S...</p>
<h3 >H3: L...</h3>
<p >S...</p>
<h1 >H3: W...</h1>
<h3>test</h3>
<h2>test</h2>
<h9>test</h9>
<p >N...</p>
<h3>test</h3>
<h3>test</h3>