patternjavascriptMinor
Add timeline link to questions and answers on Stack Exchange
Viewed 0 times
addtimelinestackanswersexchangequestionsandlink
Problem
The following script is meant to be a user script, but it should work on the console. It takes the id of the question and adds the corresponding
I'm not sure if it's convenient to abstract the logic that create and adds the link, as I'm afraid it could introduce needless complexity. My naming sense could be better.
/posts/id/timeline link to the post-menu element, just besides others. It's meant to not have problem with other scripts. The same as above for the answers, just that in this case it should loop through all the answers and add its corresponding timeline link.let question = document.getElementById("question");
let qid = question.dataset.questionid;
if (qid) {
let span = document.createElement("span");
let alink = document.createElement("a");
alink.class = "userscript-timeline";
alink.href = "/posts/" + Number(qid) + "/timeline";
alink.title = "timeline for this question";
alink.textContent = "timeline";
span.appendChild(alink);
question.getElementsByClassName("post-menu")[0].appendChild(span);
}
let answers = document.getElementsByClassName("answer");
if (answers) {
for (let i = 0; i < answers.length; i += 1) {
let aid = answers[i].dataset.answerid;
let answer = document.getElementById("answer-" + aid);
let span = document.createElement("span");
let alink = document.createElement("a");
alink.class = "userscript-timeline";
alink.href = "/posts/" + Number(aid) + "/timeline";
alink.title = "timeline for this answer";
alink.textContent = "timeline";
span.appendChild(alink);
answer.getElementsByClassName("post-menu")[0].appendChild(span);
}
}I'm not sure if it's convenient to abstract the logic that create and adds the link, as I'm afraid it could introduce needless complexity. My naming sense could be better.
Solution
Direct per-attribute DOM building belongs to the '00s but, since you're using ES2015's
Notes:
Of course the former is faster but it doesn't matter in our case.
let, let's use multiline template strings and make the final result of our code instantly readable:let question = document.getElementById("question");
if (question) {
question.querySelector(".post-menu").insertAdjacentHTML('beforeend', `
timeline
`);
}
for (let answer of document.getElementsByClassName("answer")) {
answer.querySelector(".post-menu").insertAdjacentHTML('beforeend', `
timeline
`);
}Notes:
.getElementsByClassName("abc")[0]———>.querySelector(".abc")
Of course the former is faster but it doesn't matter in our case.
getElementsByClassNamecan never be null, it's a live HTMLCollection, so we can directly use it in a loop.
insertAdjacentHTMLspeed is about the same or faster than manual node building.
Code Snippets
let question = document.getElementById("question");
if (question) {
question.querySelector(".post-menu").insertAdjacentHTML('beforeend', `
<span>
<a class="userscript-timeline" title="timeline for this question"
href="/posts/${question.dataset.questionid}/timeline">timeline</a>
</span>
`);
}
for (let answer of document.getElementsByClassName("answer")) {
answer.querySelector(".post-menu").insertAdjacentHTML('beforeend', `
<span>
<a class="userscript-timeline" title="timeline for this answer"
href="/posts/${answer.dataset.answerid}/timeline">timeline</a>
</span>
`);
}Context
StackExchange Code Review Q#138773, answer score: 2
Revisions (0)
No revisions yet.