Home > Net >  How to (if possible) copy the value of `:before` content to another element via CSS or JavaScript?
How to (if possible) copy the value of `:before` content to another element via CSS or JavaScript?

Time:01-13

(Similar to Screenshot from Firefox

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>

  • Related