Reputation: 15
I want to put a number to each link selected from the DOM, using js.
For that, i have made a function using a map method in order to associate all the links with a key
function mapLinks(){
var links = document.querySelectorAll('a')
var listLinks = new Array(links.length);
for(i = 0; i <links.length; i++){
listLinks[i] = i;
}
var mapLink = new Map([[listLinks, links]])
return (mapLink)
}
var map = mapLinks();
I tried this code but it's not the best solution because in some case it distorts the structure of the web page
function linksNumber(){
for(var [key, value] of map){
for(var i = 0, j = 0; i < key.length, j < value.length; i++, j++){
value[j].textContent = value[j].textContent + key[i]
}
}
}
Upvotes: 0
Views: 138
Reputation: 64657
You could use the css ::before
or ::after
selector with content: attr(data-n)
to keep the page structure basically the same.
function mapLinks(){
var links = document.querySelectorAll('a')
var listLinks = new Array(links.length);
for(i = 0; i <links.length; i++){
links[i].setAttribute('data-n', i)
}
var mapLink = new Map([[listLinks, links]])
return (mapLink)
}
mapLinks()
a::after {
content: attr(data-n);
width: 10px;
height: 10px;
background: yellow;
display: inline;
font-size: 10px;
position: relative;
top: -6px;
}
<a href="test">Test</a>
<a href="hi">Hi</a>
If you can't add a css file, you can use JS to add an inline <style
> element:
var sheet = document.createElement('style');
sheet.innerHTML = `
a::after {
content: attr(data-n);
width: 10px;
height: 10px;
background: yellow;
display: inline;
font-size: 10px;
position: relative;
top: -6px;
}
`
(document.head || document.getElementsByTagName('head')[0]).appendChild(sheet);
Or, with no javascript except creating the stylesheet:
var sheet = document.createElement('style');
sheet.innerHTML = `
body { counter-reset: number -1; }
a::after {
content: counter(number);
counter-increment: number;
width: 10px;
height: 10px;
background: yellow;
display: inline;
font-size: 10px;
position: relative;
top: -6px;
}
`;
(document.head || document.getElementsByTagName('head')[0]).appendChild(sheet);
<a href="hello">Hello</a>
<a href="world">World</a>
Upvotes: 2
Reputation: 1409
Careful with this:
var links = document.querySelectorAll('a')
If you have more <a />
in the future, it will also take them. I recommend adding a class to the elements (<a/>
) that you want to mark.
Lets say we add the class "anchorTooltip" to all that you need.
var links = document.querySelectorAll('a.anchorTooltip')
This will take all anchors with the class "anchorTooltip"
Now you can do:
Array.from(links).map((link, index)=>link.setAttribute("title", index))
querySelectorAll()
returns a static (not live) NodeList representing a list of the document's elements that match the specified group of selectors. Use Array.from()
to convert NodeList to array then iterate through Array.map()
.
Tests:
var links = document.querySelectorAll('a.anchorTooltip')
Array.from(links).map((link, index)=>link.setAttribute("title", index))
<a class="anchorTooltip">test 1</a><br >
<a class="anchorTooltip">test 2</a><br >
<a class="anchorTooltip">test 3</a>
document.querySelectorAll('a.anchorTooltip').forEach((link, index)=>link.setAttribute("title", index+40))
Test:
document.querySelectorAll('a.anchorTooltip').forEach((link, index)=>link.setAttribute("title", index+10))
<a class="anchorTooltip">test 1</a><br >
<a class="anchorTooltip">test 2</a><br >
<a class="anchorTooltip">test 3</a>
Upvotes: 0
Reputation: 65796
The use of .map()
is redundant here. .querySelectorAll()
returns an array-like object which you can iterate using .forEach()
and get the index from.
All you really need to do in the loop is just create a new element that will hold the "badge" value. Most of the work is actually in the CSS, not the JavaScript.
See inline comments:
// Just loop over the collection returned by .querySelectorAll()
// with .forEach, which has a callback funciton that can provide
// you with the index.
document.querySelectorAll('a').forEach(function(link, index){
let badge = document.createElement("span");
badge.classList.add("badge");
// Just use the index of the item you are iterating over
badge.textContent = index + 1;
link.appendChild(badge);
});
/* Giving the new elements this class
will allow them to "float" above the
link element they correspond to. You
can tweak the top and left values for
better positioning. */
.badge {
position:absolute; /* puts in own layer */
display:inline-block; /* let's us style as a block */
border:1px solid #808080;
padding:2px;
background: #ff7;
border-radius:3px;
font-size:.7em;
top:-.8em; /* Moves the element relative to the parent <a> */
left:-.8em; /* Moves the element relative to the parent <a> */
}
/* Basic styling for the links */
a {
position:relative; /* doesn't move them, but puts them in their own layer */
text-decoration:none; /* no underline */
display:block;
margin:1em;
height:50px;
width:50px;
border:#e0e0e0;
background-color:#99f;
padding:5px;
}
<a href="#one">One</a>
<a href="#two">Two</a>
<a href="#three">Three</a>
Upvotes: 0