How to create ascending-numbers (1,2,3...) CSS IDs and corresponding hrefs with JavaScript?

I am trying to create an efficient frontend alternative to the backend footnotes mechanism of MediaWiki.
By combining MediaWiki templates and JavaScript I can create lists of footnotes in some articles as well as representative footnote numbers in body text:

footnotes_list template

<includeonly><ol id="footnotes_list"></ol></includeonly><noinclude>

[[category:templates]]
</noinclude>

footnote template

<includeonly><span class="footnote"><sup class="footnote_inner">{{{1}}}</sup></span></includeonly><noinclude>

[[category:templates]]
</noinclude>

JavaScript

I use the following JavaScript to put all footnotes in the footnotes_list chapter and to represent each footnote with a number adjacent to the relevant text in the article body:

document.querySelectorAll(".footnote>sup").forEach((element, i) => {
    const li = document.createElement("li"); // Create <li> items of the <ol> to represent each footnote's text numbered;
    li.append(...element.childNodes); // Append to <li> elements, all the childNodes of all footnotes (which includes all <sup> texts);
    element.textContent = i + 1; // Starting from first <sup> text → give it number 1 and add +1 for each <li> representative;

    const footnotes_list = document.querySelector("#footnotes_list"); // Select the HTML element for creating a footnotes list;
    footnotes_list.appendChild(li); // Append all relevant <li> elements to the list in the selected HTML element;
});

Credit for user trincot of stackexchange to originally develop the code.

My problem

While the above works fine (footnotes are created and sorted in a list and footnote numbers are also created), my problem is that footnote numbers aren’t clickable in the sense that each footnote number would lead the user to each footnote in the list.

I have tried to solve that problem with the following JavaScript, but failed:

document.querySelectorAll("#footnotes_list>li").forEach( (element)=>{
    element.createAttribute(`#${i}`)
});

document.querySelectorAll(".footnote_inner").forEach( (element)=>{
    element.createAttribute(`href="${i}"`)
});

My question

How would you solve the problem?
If I define it correctly, the direct question should be:
How to create ascending-numbers (1,2,3…) CSS IDs and corresponding hrefs with JavaScript?

I would solve the problem by first ignoring the JavaScript. Instead, create an HTML-only version of the page that used named links on both the number and the footnote in the list that refer to each other.

Only when you have that properly working, should you then return back to JavaScript, for you will then have a known working set of HTML that you are attempting to recreate using JavaScript.

3 Likes

If it helps to speed things up I have a very old CSS example here that you may be able to use for testing.:slight_smile:

(I also had this jquery version but is very basic and probably the wrong approach).

1 Like

Paul, if I understood you correctly you tried to clue that in my example, a <li> object won’t even appear in DOM as a list because it will be created later (after parsing and rendering).

PaulOB, thanks;

Because I didn’t find JavaScript in the example, I don’t understand how it should help me solve the JavaScript problem that I tried to solve but failed.

Perhaps I missed something - if so, I am sorry for that.

No worries I’m probably more of a hindrance here than a help anyway :slight_smile:

The first example I posted was in answer to what @Paul_Wilkins said above about having a working version in CSS and html (no JS) first so that you can then work out what code you would need to produce that result.

The second example uses jquery and basically produces the html for the first example. If you look at the second example’s html there are no ids or hrefs in order to link to and from the footnotes. The jquery iterates through the footnote numbers and applies ids and hrefs to them and vice versa for the actual footnotes.

I thought it may help in your quest to do something in vanilla JS if you could see a basic version :slight_smile:

No worries if its no use but as Paul said above it would help if you post the generated html that your code produces so that at least there is something solid to work with :slight_smile:

2 Likes

Indeed I missed; I totally passed on the jQuery example due to a cognitive bias of wanting to do everything vanilla.

I found a vanilla way to do what I want on an HTML document I already have (created by MediaWiki) but from some reason the number, which appears in DOM as an anchor link and should be clickable, just isn’t clickable.

const numbers = Array.from(Array(100)).map((e,i)=>i+1)
document.querySelectorAll(".footnote").forEach( (element, i)=>{
    element.setAttribute("href", `#${numbers[i]}`)
});
document.querySelectorAll("#footnotes_list>li").forEach( (element, i)=>{
    element.setAttribute("id", numbers[i]);
});

Any idea why numbers such as[1] aren’t clickable would be most welcome.

You didn’t show your html but as long as the elements are anchors they will work. I added your code to suit my example and it worked straight away.

Note that even though html allows you to start ids with digits CSS does not allow you to style them so its best not to start ids with a number. If you look at my jquery example I made the ids #fn1, #fn2, #fn3 etc.

Notice that in my example I also reversed the procedure so that the footnote descriptions will link you right back to the point you left it. There’s nothing worse than jumping to the bottom of the page to read a footnote and then not being able to go back to where you started easily :slight_smile:

2 Likes

The reason to start with plain HTML and no JavaScript, is so that you have a map of where you need to go. Sometimes we keep that map in our head, but in this case it will be much easier for you when that map to exist as a separate HTML file.

Start with the map, then program your way to success.

Well, because the webpages are in Hebrew and the JavaScript-constructed HTML doesn’t appear fully at the quite large source code (CTRL+U), I can’t figure out how to put here a good HTML example.

So, I think that the only option I have left is to link to a webpage that examples the problem directly:

https://seo-wiki.org/index.php?title=אחסון_לינוקס

Right-click on the HTML content for the context-sensitive menu, and select Inspect (bottom option in Chrome).

I also needed to copy the entire DOM by “copy element” <html> which I never thought about before and I have also learnt that HTML source code and DOM are not the same thing (I find these facts of great didactic importance).

Here is the full HTML of the page (DOM).

For every footnote number, I now use note_anchor_NUMBER ID, and for every corresponding footnote, I now use href="note_anchor_NUMBER".

The purpose here is for you to update the HTML code to add named anchors to where the footnotes came from, and ended up going to.

What I get either when checking the source code (CTRL+U) or when I copy <html> tag from DOM to a file, is different than what I get on the screen while surfing website.

As I am not a frontend expert, I cannot explain this and assume it might be a CMS bias.

Okay, it might be time for show and tell, using PaulOB’s example code.

The second paragraph (I’ve added a superscript number because CSS was used in his example to do that), ends up having the following HTML code:

<p>Tunguska event, made in the interiors of collapsing stars! Galaxies 
intelligent beings not a sunrise but a galaxyrise the ash of stellar alchemy 
from which we spring tingling of the spine preserve and 
cherish <a href="#fn3" class="fnote" id="fnote3"><sup>3</sup></a> that pale blue dot 
Apollonius of Perga, a still more glorious dawn</p>

And the footnotes section has the following footnote as reference:

<li id="fn3">Footnote <b></b>: lorem ipsum dolor sit 
amet <a class="back" href="#fnote3">Back to text</a></li>

Do you see how the HTML code has a link down to the footnote?
Do you see how the footnote has a link back up to the text?

That is what we are wanting you to do for yourself on your own HTML code. Get the idea working first, with no JavaScript code.

Get it working in HTML on your own test page and after that you can then move on to doing other things, like automatically generating some of it from scripting instead.

1 Like

I saw both algorithms but I cannot control the HTML in MediaWiki freely like this because it automatically creates my HTML from its templates and PHP, hence I think that my only option is to use JavaScript directly.

But, if my JavaScript is ineffective (in the sense that the numbers aren’t clickable), than I might need to find a MediaWiki extension and templates solution which is something I wanted to avoid so far.

You don’t need to use mediawiki at all when putting together some test HTML code.

Yes, but I don’t understand why such a testing is relevant to the problem I am having were similar HTML appears in DOM but is practically ineffective.

Because, it helps you to precisely understand the HTML code that’s needed, to show the desired end result to users viewing the page.

But I already know what I want to achieve with HTML and have created that HTML indirectly as I have exampled above and yet from some reason it’s ineffective in the CMS and I only ask here what might cause it to be ineffective.