Hacker News new | ask | show | jobs
by chrismorgan 3091 days ago
You can change the colour of the logo with CSS filters, something like this:

  [href="https://news.ycombinator.com"] > img {
    filter: hue-rotate(-50deg) brightness(150%);
  }
… but that doesn’t fix the favicon.

Some of the other bits done in JS can be done in CSS; this snippet, for example:

  for (let i = 0; i < document.getElementsByTagName("font").length; i++) {
    if (document.getElementsByTagName("font")[i].getAttribute("color") === "#ff6600")
      document.getElementsByTagName("font")[i].setAttribute("color", "#FF83C6")
  }
This is very inefficient (though document.getElementsByTagName is probably O(1) due to its return type HTMLCollection being live, so the end result is probably still only O(n) on the number of <font> elements in the document; it’d be O(n²) with document.querySelectorAll); you should only get the <font> elements once, like this:

  const fontElements = document.getElementsByTagName("font");
  for (let i = 0; i < fontElements.length; i++) {
    if (fontElements[i].getAttribute("color") === "#ff6600")
      fontElements("font")[i].setAttribute("color", "#FF83C6")
  }
It can still be made more efficient, but all I wanted to do was rewrite it in CSS anyway:

  font[color="#ff6600"] {
    color: #ff83c6;
  }
Same deal on the table cells just above it:

  for (let i = 0; i < document.getElementsByTagName("TD").length; i++) {
    if (document.getElementsByTagName("TD")[i].getAttribute("bgcolor") === "#ff6600")
      document.getElementsByTagName("TD")[i].setAttribute("bgcolor", "#fbbfdf")
  }
Use this CSS instead:

  td[bgcolor="#ff6600"] {
    background-color: #fbbfdf;
  }
On the performance matter, a rule of thumb: don’t call getElementsByTagName, getElementsByClassName, querySelector and querySelectorAll more than you absolutely have to. Or anything, really. Cache things in temporary variables aggressively. Take these two lines, for example:

  document.getElementsByClassName("pagetop")[0].innerHTML = document.getElementsByClassName("pagetop")[0].innerHTML.split("|").join(" ")
  document.getElementsByClassName("pagetop")[1].innerHTML = document.getElementsByClassName("pagetop")[1].innerHTML.split("|").join(" ")
You’ve evaluated `document.getElementsByClassName("pagetop")` four times instead of once.

  const pagetops = document.getElementsByClassName("pagetop");
  pagetops[0].innerHTML = pagetops[0].innerHTML.split("|").join(" ")
  pagetops[1].innerHTML = pagetops[1].innerHTML.split("|").join(" ")
Even then, this indexes pagetops twice as often as is necessary, but that operation is quite a bit cheaper than getElementsByClassName. I’d say then to use for..of or forEach or similar, or assign temporaries.
1 comments

This is EXCELLENT, thank you so much for this. I'm absolutely going to implement these changes.