<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Thanos Kolovos</title>
    <description>The latest articles on Forem by Thanos Kolovos (@codegaze).</description>
    <link>https://forem.com/codegaze</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3989%2Fe8684ece-756e-4e65-8949-6741cda206f1.jpg</url>
      <title>Forem: Thanos Kolovos</title>
      <link>https://forem.com/codegaze</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/codegaze"/>
    <language>en</language>
    <item>
      <title>The Bait, the Switch &amp; the Loop</title>
      <dc:creator>Thanos Kolovos</dc:creator>
      <pubDate>Thu, 16 Mar 2023 18:20:54 +0000</pubDate>
      <link>https://forem.com/codegaze/the-bait-the-switch-the-loop-297c</link>
      <guid>https://forem.com/codegaze/the-bait-the-switch-the-loop-297c</guid>
      <description>&lt;h2&gt;
  
  
  The Bait
&lt;/h2&gt;

&lt;p&gt;You find yourself on a call with three people on a Wednesday afternoon.&lt;/p&gt;

&lt;p&gt;One is the hiring manager, one HR representative and another person they introduced as “Page, a member of one of our teams”. They all look tired, but you notice they are trying to smile. It’s evident that this is a routine call for them. It could have been the third or fourth similar call for the day, and it looked like this one was outside their usual working hours. Or not.&lt;/p&gt;

&lt;p&gt;Sheila, the hiring manager, describes how the teams work and that there is always an opportunity to grow and experiment. She then starts talking a lot about herself, but you choose to ignore that for now because the offer in the initial stage was impressive. A 35% raise to what you are getting in your current gig. This will be an excellent boost to being closer to your wish list.&lt;/p&gt;

&lt;p&gt;After the diversion, she talks about the teams again and their achievements. A relief. Your mind strategically blocked the previous discussion.&lt;/p&gt;

&lt;p&gt;The HR representative lists some of the perks, the growth plan they have in place that is carefully tailored to each individual, and how every day is a chance to learn something new. He seems proud of the work and process they have in place. He gave some well-thought answers to your questions.&lt;/p&gt;

&lt;p&gt;Page only speaks when you mention day-to-day work. She seems happy with the result overall, which is a good sign. She asks about previous experience and some easy technical questions. This isn’t supposed to be a technical interview, but you are happy to answer.&lt;/p&gt;

&lt;p&gt;That last session comes to an end after one and a half hours. Something feels slightly off, but you’ve done your due diligence. Glassdoor reviews seem high and legit, and overall the company has a good reputation. You managed to talk to someone that was working three years ago in the company, and he didn’t have anything bad to say.&lt;/p&gt;

&lt;p&gt;Based on this, it’s “go” time. The money is good, and you need a change. You have been looking for some time now, so you do it. You are excited and ready to join.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Switch
&lt;/h2&gt;

&lt;p&gt;Two months into the gig, you haven’t done a 1:1 yet and haven’t seen the people from the interview again. You heard that Page, the “member of one of our teams”, resigned. These things happen. The hiring manager is usually lost somewhere in a meeting, &lt;a href="https://codegazerants.com/2022/09/05/the-five-minutes-talk/"&gt;being busy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Your peers are amazing at their job, but they are disoriented most of the time, like no one knows why they do the things they do, and the team’s last project didn’t make it to production because of “reasons”. Four months of design and implementation are out of the window. You have no idea about the next steps. Someone will tell you, but not knowing what is coming is not your strong suit.&lt;/p&gt;

&lt;p&gt;That week, Thursday would be a “come to the office” day - remote wasn’t really remote - and mid-day, an angry person you haven’t seen before walked into the open office space and screamed, “Who pushed the ‘a4e9c’ commit? WHO DID THAT?!?”.&lt;/p&gt;

&lt;p&gt;You had no idea who that person was, but who behaves like that in a professional environment, and how doesn’t he know he can check the contributor for the commit in the following line? Later you learn that this was the VP of Engineering…&lt;/p&gt;

&lt;p&gt;Perks magically disappear, and bureaucracy and hidden agendas are a thing.&lt;br&gt;
Six months passed - during which similar not-so-good things happened - and you are on an interview call again. The team seems great, and there is no weird gut feeling this time. As a precautionary measure this time, you found two people on LinkedIn still working there to ask about the company. The money is not that good, but the whole thing seems more human-oriented.&lt;/p&gt;

&lt;p&gt;Of course, you take the job.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Loop
&lt;/h2&gt;

&lt;p&gt;Bait and Switch it’s a known sales technique to get customers to buy in with low prices and then raise prices as you go towards the signing time or after you are bound with a contract. It’s used as a bad practice in UX, and It’s also used in interviews when an interviewee is not the person applying for work (who does that?!?).&lt;/p&gt;

&lt;p&gt;This is different. This is the case of a company overselling to the candidate. Not small things about setting priorities or gym perks. I’m talking about significant differences in culture. The things that might differentiate a healthy from a toxic environment.&lt;/p&gt;

&lt;p&gt;I used to wonder what is the purpose of hiding the truth in an interview?&lt;/p&gt;

&lt;p&gt;Every new hire is an investment. If you hire someone and they leave after a few months, you have spent time and energy onboarding them, making them part of a team and training them. Don’t they get that if a candidate sees BS in the first months in the company, they will just bail out?&lt;/p&gt;

&lt;p&gt;Then it hit me. They do know it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Take 1
&lt;/h3&gt;

&lt;p&gt;Once you are in, you are probably staying. Money and perks are the incentives. They depend on this being enough to retain people even if they are not completely happy. Even if a percentage of people leave, other people will stay.&lt;/p&gt;

&lt;h3&gt;
  
  
  Take 2
&lt;/h3&gt;

&lt;p&gt;In big organizations in a growth state, hiring becomes a number in someone’s OKRs, “Hire 70 people”. This person might be so up the chain that it is probably too difficult to understand the actual situation in the organization. They do believe they have an amazing culture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Take 3
&lt;/h3&gt;

&lt;p&gt;Big organizations, big stakes. Current goals in someone’s OKRs are more important than anything else. Again, “Hire 70 people”. Every month they don’t hit this number, it translates to lost opportunities and lost revenue (crazy, right?), so they do anything to cover this number no matter what. If people leave, this can be a problem for another quarter, another person.&lt;/p&gt;

&lt;p&gt;And this is the Loop. An endless Loop of new goals to cover the numbers of the previous goal. Every month, every quarter.&lt;/p&gt;



&lt;p&gt;This might come up as criticizing, but it’s really not. I get it. I don’t like it, but I get it. And, of course, this doesn’t apply to all organizations. There are teams out there, even with hundreds of people, that maintain a fantastic culture in which people can thrive.&lt;/p&gt;

&lt;p&gt;What is needed is extra caution. An interview is a two-way street. Ask questions so you can better understand what is going on. Reach out to people currently working there and make sure what you heard in the interview was legit. If you join, keep the organization accountable for their promises.&lt;/p&gt;

&lt;p&gt;Be vigilant and keep an eye out for the Bait and Switch!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally posted on &lt;a href="https://codegazerants.com/2023/03/16/the-bait-the-swith-and-the-loop/"&gt;https://codegazerants.com/2023/03/16/the-bait-the-swith-and-the-loop/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>interview</category>
      <category>career</category>
    </item>
    <item>
      <title>Create a New Jekyll Post with a Simple Shell Command</title>
      <dc:creator>Thanos Kolovos</dc:creator>
      <pubDate>Tue, 07 Feb 2023 18:36:38 +0000</pubDate>
      <link>https://forem.com/codegaze/create-a-new-jekyll-post-with-a-simple-shell-command-4921</link>
      <guid>https://forem.com/codegaze/create-a-new-jekyll-post-with-a-simple-shell-command-4921</guid>
      <description>&lt;p&gt;Let's build a shell command to automate the creation of a new post in Jekyll.&lt;/p&gt;

&lt;p&gt;This will be a short one.&lt;/p&gt;

&lt;p&gt;Jekyll has its quirks, and I always wondered why they don't have a simple command to create a new post. I used to copy/paste the previous one, but you know how things are... If you can automate something boring in a few minutes, just do it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Script
&lt;/h2&gt;

&lt;p&gt;We first need to create a simple bash script to do the job for us.&lt;/p&gt;

&lt;p&gt;So, create a new file. I call mine &lt;code&gt;newjekyllpost.sh&lt;/code&gt; and add the following parts to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y-%m-%d-new-post.md&lt;span class="sb"&gt;`&lt;/span&gt;

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$filename&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
---
layout: post
title: A title
description: A description
categories: ["tag"]
social_image: add here
---
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's rubberduck this.&lt;/p&gt;

&lt;p&gt;The second line is a variable called &lt;code&gt;filename&lt;/code&gt;. This will be used for our file name with today's date and the following format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;YYYY-MM-DD-new-post.md #
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The third line will create the file with the contents we like. I chose to add the YAML front matter with the most used content for my posts. If I don't want something, I remove it.&lt;/p&gt;

&lt;p&gt;And that's it. Our script is that simple. Let's now try to execute it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making the Script Executable
&lt;/h2&gt;

&lt;p&gt;If you try to run it, you will get an error about permissions. There is one more step, which is to change the file's permissions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chmod u+x ./newjekyllpost.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, running &lt;code&gt;./newjekyllpost.sh&lt;/code&gt; will create a file in the specific folder with our contents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding an Alias
&lt;/h2&gt;

&lt;p&gt;Let's do one more last thing to make our lives easier.&lt;/p&gt;

&lt;p&gt;Right now, we have our script in a specific folder, so we need to write the path each time, which is also boring. Adding an alias for the script will work like magic.&lt;/p&gt;

&lt;p&gt;Move the script to any path you want. I keep a &lt;code&gt;scripts&lt;/code&gt; folder inside my &lt;code&gt;Users&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Open the profile your shell is using. I'm using ZSH, so I have this line in my &lt;code&gt;.zshrc&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;alias njp="~/scripts/newjekyllpost.sh"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every time I run &lt;code&gt;njp&lt;/code&gt; in a folder, the script creates a new file. You can choose any alias you want, of course.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;source pathoftheprofilefile&lt;/code&gt; to reload the new changes, and we are done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improving the Script
&lt;/h2&gt;

&lt;p&gt;As I was writing this, I though there is one more thing we could do to improve the script. If there are argguments to the script use them to postfix the filename.&lt;/p&gt;

&lt;p&gt;So our first part of the script becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if [ $# -gt 0 ]
then
  filename=`date +%Y-%m-%d-`
  filename+=`echo "$@" | sed -e 's/ /-/g'`.md
else
  filename=`date +%Y-%m-%d-new-post.md`
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the "bash" language what that means is:&lt;/p&gt;

&lt;p&gt;If I have arguments add the date in the filename. Then join with a space all the arguments as string with &lt;code&gt;"$@"&lt;/code&gt; and then replace the spaces with &lt;code&gt;-&lt;/code&gt; which is done by the &lt;code&gt;sed&lt;/code&gt; part.&lt;/p&gt;

&lt;p&gt;If I have no arguments, business as usual.&lt;/p&gt;

&lt;p&gt;If we run &lt;code&gt;njp this is my new post&lt;/code&gt; at 2022-12-30 the file will be create will have the following name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2022-12-30-this-is-my-new-post.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just remember, all of this can be achieved with any language. The logic is the same. I just chose to do it in a bash script because, why not?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally posted on &lt;a href="https://codegazerants.com/2023/01/01/create-new-jekyll-post-with-a-command/" rel="noopener noreferrer"&gt;https://codegazerants.com/2023/01/01/create-new-jekyll-post-with-a-command/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>jekyll</category>
      <category>bash</category>
      <category>shell</category>
      <category>automation</category>
    </item>
    <item>
      <title>Thoughts on feedback</title>
      <dc:creator>Thanos Kolovos</dc:creator>
      <pubDate>Tue, 31 Jan 2023 19:12:02 +0000</pubDate>
      <link>https://forem.com/codegaze/thoughts-on-feedback-30ih</link>
      <guid>https://forem.com/codegaze/thoughts-on-feedback-30ih</guid>
      <description>&lt;p&gt;Thoughts on feedback, the really short version.&lt;/p&gt;

&lt;p&gt;Feedback is difficult and needs a lot of practice. Why? Because emotions are involved.&lt;/p&gt;

&lt;p&gt;There are two parts to becoming better at it. The rules are simple, but it's hard to live by.&lt;/p&gt;

&lt;h2&gt;
  
  
  Receiving Feedback
&lt;/h2&gt;

&lt;p&gt;To get feedback, you need to be and also look open to feedback. If your face changes and you start being defensive - even if you have counter arguments - when someone gets out of their way to give you some feedback, there is a chance they won't do it again. And yes, we've all been there.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Listen to what the other person has to say, even if you disagree.&lt;/li&gt;
&lt;li&gt;Ask questions to understand more about the situation. Keep notes.&lt;/li&gt;
&lt;li&gt;Thank the person for the feedback. They've given some thought, time and care about you.&lt;/li&gt;
&lt;li&gt;Sleep on it.&lt;/li&gt;
&lt;li&gt;Act if needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yes, ask for direct feedback like hell! I usually mention to the people around me that even if their feedback "hurts" me, at the end of the day, if it's constructive, it will make me better. It's going to make me grow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Giving Feedback
&lt;/h2&gt;

&lt;p&gt;There is a strong possibility you have some feedback about people, but you are hesitant to share it because you are afraid of how the other person will feel and how it might make you look like not a good person.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be empathetic, respectful and direct.&lt;/li&gt;
&lt;li&gt;Try not to judge, but describe a situation and its effect.&lt;/li&gt;
&lt;li&gt;Be precise and provide examples, don't be vague.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'll let you in on a secret. Everything about providing feedback ends when you do it. After that, It's the other person's job to filter and evaluate the input. There is no need to convince or be convinced about anything.&lt;/p&gt;

&lt;p&gt;You can't imagine how fulfilling it is to hear an honest "Thank you for pointing this out. I wasn't aware of that" after providing hard feedback.&lt;/p&gt;

&lt;p&gt;One last note. I was lucky enough to be introduced to &lt;a href="https://www.radicalcandor.com/radical-candor-not-brutal-honesty/" rel="noopener noreferrer"&gt;Radical Candor&lt;/a&gt; and &lt;a href="https://www.ccl.org/articles/leading-effectively-articles/closing-the-gap-between-intent-vs-impact-sbii/" rel="noopener noreferrer"&gt;SBI (Situation Behaviour Impact) model&lt;/a&gt; a few years ago, which helped me improve the way I use feedback. So it's my turn now to urge some people to give these resources a try if they haven't already.&lt;/p&gt;

&lt;p&gt;Originally posted on &lt;a href="https://codegazerants.com/2022/10/15/thoughts-on-feedback/" rel="noopener noreferrer"&gt;https://codegazerants.com/2022/10/15/thoughts-on-feedback/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>feedback</category>
      <category>growth</category>
      <category>career</category>
    </item>
    <item>
      <title>Use JavaScript to Navigate Through a Table And Other Elements</title>
      <dc:creator>Thanos Kolovos</dc:creator>
      <pubDate>Wed, 25 Jan 2023 17:46:28 +0000</pubDate>
      <link>https://forem.com/codegaze/use-javascript-to-navigate-through-a-table-and-other-elements-26b6</link>
      <guid>https://forem.com/codegaze/use-javascript-to-navigate-through-a-table-and-other-elements-26b6</guid>
      <description>&lt;p&gt;The browser API has given us many tools to navigate through a webpage, and if done correctly, you will have a great result without the use of any Javascript.&lt;/p&gt;

&lt;p&gt;In some case though, you might need to enhance some of the navigation experience. Usually, this is a challenge in an application environment, or more specifically, on some elements of the application. And here is when JavaScript comes in handy.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Beautiful Table
&lt;/h2&gt;

&lt;p&gt;If you are using Gmail, then you probably have seen that you can navigate between the mail list with your up and down arrow keys. Gmail uses a table, and I have no idea what they are doing under the hood, but let's see how we can accomplish this.&lt;/p&gt;

&lt;p&gt;We will go through some sections of the code, but keep in mind that we can use this code for various HTML elements.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Basics
&lt;/h2&gt;

&lt;p&gt;Let's get the basic stuff out of the way. We will create an HTML file. Let's call it &lt;code&gt;index.html&lt;/code&gt;. Yes, we will do everything in a single file, no bundlers or anything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"IE=edge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Use JavaScript to Navigate Through a Table And Other Elements&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.is-active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inset&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"mytable"&lt;/span&gt; &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;One&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;Two&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;Three&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;Four&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;Five&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we have a simple file with a table and a CSS part with one class to visualise a selected table row.&lt;/p&gt;

&lt;p&gt;One small addition that makes the difference is the &lt;code&gt;tabindex&lt;/code&gt; attribute so we can focus on our table.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Key Navigation Backbone
&lt;/h2&gt;

&lt;p&gt;Let's design our navigation function. What could be the main parts of it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;navigateElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;elementID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;itemsTagName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;activeClass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scroller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleKeyboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have one main function here called &lt;code&gt;navigateElement&lt;/code&gt; - which I'm sure you can find a better name for it - that takes some parameters. We could have everything hardcoded, but you will probably reuse this in other elements in your application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;elementID&lt;/code&gt;: The element we are going to add our key capture event listener to and includes our list items. We need to have this in case we have more than one &lt;code&gt;navigateElement&lt;/code&gt; instance.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;itemsTagName&lt;/code&gt;: The element's tag name we will navigate through.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;activeClass&lt;/code&gt;: The active class we mentioned in our CSS part.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;scroller&lt;/code&gt;: The element that is responsible for our content overflow. More on that later. Secret sauce.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;handleKeyboard&lt;/code&gt; does what it promises. It will handle the navigation between items, and the &lt;code&gt;handleScroll&lt;/code&gt; will be responsible for always having in our viewport the selected element. This simple design is all we need for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Key Navigation Code
&lt;/h2&gt;

&lt;p&gt;Right now, our page doesn't do anything. Let's add what we promised.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"IE=edge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Use JavaScript to Navigate Through a Table And Other Elements&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.is-active&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inset&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"mytable"&lt;/span&gt; &lt;span class="na"&gt;tabindex=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;One&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;Two&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;Three&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;Four&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;Five&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;navigateElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;elementID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;itemsTagName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;activeClass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scroller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mainDOMElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;elementID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scrollElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scroller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mainDOMElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;itemsTagName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;itemsLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleKeyboard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;which&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;which&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activeClass&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;which&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;which&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;itemsLength&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;itemsLength&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activeClass&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mainDOMElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementsByClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activeClass&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;scrollIntoView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;smooth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;mainDOMElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyboard&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;mainDOMElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;focus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;handleKeyboard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;navigateElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mytable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tr&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;is-active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you copy/paste this code in an HTML file, should work out of the box.&lt;/p&gt;

&lt;p&gt;Focus on the element and navigate through your up and down arrow keys.&lt;/p&gt;

&lt;p&gt;But let's rubberduck the script in sections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;navigateElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;elementID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;itemsTagName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;activeClass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scroller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mainDOMElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;elementID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scrollElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scroller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mainDOMElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;itemsTagName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;itemsLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple things, we initiate some variables based on our parameters and set a &lt;code&gt;selection&lt;/code&gt; to &lt;code&gt;-1&lt;/code&gt;, which means that nothing is selected. If &lt;code&gt;scroller&lt;/code&gt; is not defined, we get the window as our element.&lt;/p&gt;

&lt;h3&gt;
  
  
  The navigation part
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleKeyboard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;which&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;which&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activeClass&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;which&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;which&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedIndex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;38&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;itemsLength&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nf"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;itemsLength&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nf"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activeClass&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For each event we capture, we prevent the default behaviour. This is used to avoid browser page or element scrolling, resulting in a weird user experience. We are going to handle it ourselves in &lt;code&gt;handleScroll&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our selected item is based on the &lt;code&gt;event.which&lt;/code&gt; or just a programmatically given &lt;code&gt;which&lt;/code&gt; we are utilising the first time someone is focusing the element. If both of these are not set, we just &lt;code&gt;return&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We remove the active class from all the items, then we have some logic checking if we are going up or down, and we decide to increase or decrease the selected. We also cover the first/last item case, and we go to the appropriate position.&lt;/p&gt;

&lt;p&gt;After we have the selected item, we apply the active class to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Scrolling Part
&lt;/h3&gt;

&lt;p&gt;Now let's explain a bit the scrolling part. This is one thing I see people forgetting when creating custom navigation in HTML elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleScroll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mainDOMElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementsByClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activeClass&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;scrollIntoView&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;behavior&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;smooth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each time we use our keys to navigate, two things can happen:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The browser will catch the key event and scroll any element that could be considered valid, like the screen scroll, for example, and not our element. This is the reason why we use &lt;code&gt;preventDefault&lt;/code&gt; in our previous code.&lt;/li&gt;
&lt;li&gt;Since the event is not bubbling up, there is no scrolling happening, and if the content exceeds the viewport, the user won't be able to see the selected item at some point.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is why we use the fantastic &lt;code&gt;scrollIntoView&lt;/code&gt;. Before this, we would try to calculate the scrolling position of the wrapper, the element height, offset, and things that sound boring. &lt;code&gt;scrollIntoView&lt;/code&gt; will solve this, and this is why we are calling it with each key press.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding the Event Listeners
&lt;/h3&gt;

&lt;p&gt;One more thing left. To add the listeners for the key event and choose the first item when the item is focused if no selection is set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mainDOMElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleKeyboard&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;mainDOMElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;focus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;handleKeyboard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are all set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;These small snippers are cool the first time you bump into them. After that, it gets a bit boring. You will want to make a helper for it. With some more work, it could include logic for the state if you want to combine it with a frontend framework like React, Vue or anything like that. But this is the basic logic.&lt;/p&gt;

&lt;p&gt;If I wasn't lazy, I could also add some checks and validations with some beautiful errors for the developer, but I'll leave this up to you.&lt;/p&gt;

&lt;p&gt;Once again, please don't forget to use &lt;code&gt;tab&lt;/code&gt; to focus on the table first.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally posted on &lt;a href="https://codegazerants.com/2022/08/18/use-javascript-to-navigate-through-table/" rel="noopener noreferrer"&gt;https://codegazerants.com/2022/08/18/use-javascript-to-navigate-through-table/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vanillajs</category>
      <category>navigation</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Chaos Engineering For Humans</title>
      <dc:creator>Thanos Kolovos</dc:creator>
      <pubDate>Sat, 21 Jan 2023 19:59:35 +0000</pubDate>
      <link>https://forem.com/codegaze/chaos-engineering-for-humans-32m0</link>
      <guid>https://forem.com/codegaze/chaos-engineering-for-humans-32m0</guid>
      <description>&lt;p&gt;If you came here about Chaos Engineering for your services, “it’s not what it looks like”.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chaos Engineering
&lt;/h2&gt;

&lt;p&gt;You might think I just said it’s not about Chaos Engineering, but I’m about to give some kind of definition of Chaos Engineering. Yes, I am.&lt;/p&gt;

&lt;p&gt;Our products have become, or maybe better say, have progressed to be, a sum of multiple services and not a monolith service that tries to do everything. Core application, auth service, user service, payments service, prospects service. Name your service here.&lt;/p&gt;

&lt;p&gt;The whole system should be resilient.&lt;/p&gt;

&lt;p&gt;Unit and end-to-end testing should be in place for each service, but these are done in a predictable way. What I mean by “predictable way” is that we provide a specific input and expect a specific output. And this is what we test.&lt;/p&gt;

&lt;p&gt;Don’t get me wrong, this is a great state. But what would be the next step?&lt;/p&gt;

&lt;p&gt;Here is where Chaos Engineering comes in. The essence is that you create a situation for your whole system, for example, latency or absence of a service. You observe what happens, and then you prioritize improvements.&lt;/p&gt;

&lt;p&gt;This helps increase confidence, have a more predictable system and protect customers from a total failure of your system if your 10th service down the road underperforms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Closer to A Point
&lt;/h2&gt;

&lt;p&gt;What is a team? A group of individuals that work together have an input (a goal), a throughput (their work, processes etc.) and an output (results).&lt;/p&gt;

&lt;p&gt;A team is a system.&lt;/p&gt;

&lt;p&gt;When all parts work, we have great results. When something is wrong with a part of the system, then the whole system starts to show signs of latency.&lt;/p&gt;

&lt;p&gt;Do you see where I’m going with this?&lt;/p&gt;

&lt;h2&gt;
  
  
  Teams as Systems
&lt;/h2&gt;

&lt;p&gt;This all began when I started thinking of what would happen if someone from my team left tomorrow or a new team was created, and we had to do an internal restructuring? What would happen if a manager had a sabbatical? What if someone was on medical leave for two weeks?&lt;/p&gt;

&lt;p&gt;Would that absence block the team? What could we do to remove some uncertainty? Can we get some ideas from Chaos Engineering and apply them to a team?&lt;/p&gt;

&lt;p&gt;The idea is to find a way to observe when limitations arise in a team and understand where we can optimize.&lt;/p&gt;

&lt;p&gt;Here are some simple metrics you can have, but of course, it varies based on each organization:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can the team groom a feature?&lt;/li&gt;
&lt;li&gt;Can the team deploy a feature?&lt;/li&gt;
&lt;li&gt;If specialization is missing, can the team find a way to bypass that?&lt;/li&gt;
&lt;li&gt;Are the initial milestones on track?&lt;/li&gt;
&lt;li&gt;Is team morale high?&lt;/li&gt;
&lt;li&gt;What are the main areas the team struggled with?&lt;/li&gt;
&lt;li&gt;Can the team self-organize and communicate with the stakeholders if leadership is absent?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Organic Way
&lt;/h2&gt;

&lt;p&gt;There is an easy and organic way to observe and draw some conclusions without changing anything in your team.&lt;/p&gt;

&lt;p&gt;Try to observe when someone has Paid Time Off or, for some reason, cannot contribute to the problem at hand. Is there sufficient documentation? Do you have a bus factor one? Having one person less, will reduce the capacity of a team, but is it in the danger zone?&lt;/p&gt;

&lt;p&gt;Note down the observations, share them with the team and create action items.&lt;/p&gt;

&lt;h2&gt;
  
  
  The More Creative Way
&lt;/h2&gt;

&lt;p&gt;Create the circumstances that will create some “planned turbulence” for the team.&lt;/p&gt;

&lt;p&gt;Once a quarter, throw all the team’s names in a randomizer, and the winner gets one or two weeks of having to work on a project they choose or join another team. During that time, they should not interact with the rest of the team.&lt;/p&gt;

&lt;p&gt;There are no secrets or sketchy areas here. The team should know the goals and the metrics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Notes
&lt;/h2&gt;

&lt;p&gt;Please remember that this is not a way to calculate individual impact, create mayhem or stress your team. It’s one more tool to create the circumstances for a team to observe and improve. Low impact initiatives might also be a good start.&lt;/p&gt;

&lt;p&gt;Keep your team in the loop if you want to try this out. If they don’t feel comfortable, abort.&lt;/p&gt;

&lt;p&gt;I would consider this suitable for an environment with a great culture. You need safety and team maturity. This is a next-level approach. You wouldn’t try Chaos Engineering for your system if you didn’t have a good system in place first, would you?&lt;/p&gt;

&lt;p&gt;And one last thing, in case this wasn’t clear. You can apply this to any kind of team, not just Engineering teams.&lt;/p&gt;

&lt;p&gt;Happy experimenting!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally posted on &lt;a href="https://codegazerants.com/2022/10/09/chaos-engineering-for-humans/" rel="noopener noreferrer"&gt;https://codegazerants.com/2022/10/09/chaos-engineering-for-humans/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>engineering</category>
      <category>management</category>
      <category>engineeringmanagement</category>
    </item>
  </channel>
</rss>
