0

Update: I've heavily edited this question because no one seemed to be grasping what I'm trying to accomplish. When a user is focused on a heading in the example below and presses the down arrow key, I want it to remove the "inert" attribute from the section below it, and I can't figure it out:

<script>
document.querySelectorAll('.h-trigger:focus').forEach(el => {
    el.addEventListener("keydown", e => {
      if (["ArrowDown"].includes(e.key)) {
       $(this).next(".section").removeAttr("inert","");
      }
    });
</script>

<h2 class="h-trigger" tabindex=0">Heading 1</h2>
<div class="section" inert>
Something here
</div>

<h3 class="h-trigger" tabindex=0">Heading 2</h3>
<div class="section" inert>
Something else here
</div>
5
  • 1
    Where is h-trigger in the HTML?
    – Barmar
    Commented Jul 8 at 19:59
  • Please provide a minimal reproducible example.
    – Twisty
    Commented Jul 8 at 20:11
  • h-trigger is applied dynamically to each heading: $(".axxs-accordion > :header").addClass("h-trigger static")
    – DeanH
    Commented Jul 8 at 20:38
  • And it is reproducible. All that code works except the arrow down part.
    – DeanH
    Commented Jul 8 at 20:52
  • Please revise the demo above so it shows your problem. There's no need to send us elsewhere.
    – isherwood
    Commented Jul 9 at 14:54

1 Answer 1

0

Be aware of the following note:

It can be attached to any element, but the event is only sent to the element that has the focus. Focusable elements can vary between browsers, but form elements can always get focus so are reasonable candidates for this event type.

With that in mind, an example like this can be created.

$(function() {
  $(".axxs-accordion > :header").addClass("h-trigger static").next().addClass("section collapsed").attr("inert", true);

  $('.h-trigger').each(function(i, el) {
    $(el).attr("tabindex", i);
    $(el).on("keydown", function(e) {
      console.log(e.key);
      switch (e.key.toLowerCase()) {
        case "enter":
        case " ":
          $(el).click();
          break;
        case "arrowdown":
          if ($(el).hasClass("active")) {
            $(el).click();
          }
          var i = $(el).attr("tabindex");
          $("h2[tabindex='" + ++i + "']").focus().click();
          break;
        case "arrowup":
          if ($(el).hasClass("active")) {
            $(el).click();
          }
          var i = $(el).attr("tabindex");
          $("h2[tabindex='" + --i + "']").focus().click();
          break;
      }
    });
  });

  $(".axxs-accordion").on("click", ".h-trigger.static", function() {
    $(this).closest(".axxs-accordion").find(".h-trigger.active").toggleClass("active static");
    $(this).closest(".axxs-accordion").find(".section.expanded").toggleClass("expanded collapsed").attr("inert", true);
    $(this).toggleClass("static active");
    $(this).next(".section.collapsed").toggleClass("collapsed expanded").attr("inert", false);
  });

  $(".axxs-accordion").on("click", ".h-trigger.active", function() {
    $(this).toggleClass("active static");
    $(this).next(".section.expanded").toggleClass("expanded collapsed").attr("inert", true);
  });

  $("h2[tabindex='0']").focus();
});
.collapsed {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="axxs-accordion">
  <h2>Heading</h2>
  <div>
    <p>Here is some content with text and an image</p>
    <p>Here is some more text</p>
  </div>
  <h2>Heading 2</h2>
  <section>
    <ul>
      <li>List item 1</li>
      <li>List item 2</li>
    </ul>
  </section>
</div>

Update

To prevent the Header from expanding, you can remove the Click events with the Arrow keys. Then only the Focus changes.

$(function() {
  $(".axxs-accordion > :header").addClass("h-trigger static").next().addClass("section collapsed").attr("inert", true);

  $('.h-trigger').each(function(i, el) {
    $(el).attr("tabindex", i);
    $(el).on("keydown", function(e) {
      console.log(e.key);
      switch (e.key.toLowerCase()) {
        case "enter":
        case " ":
          $(el).click();
          break;
        case "arrowdown":
          var i = $(el).attr("tabindex");
          $("h2[tabindex='" + ++i + "']").focus();
          break;
        case "arrowup":
          var i = $(el).attr("tabindex");
          $("h2[tabindex='" + --i + "']").focus();
          break;
      }
    });
  });

  $(".axxs-accordion").on("click", ".h-trigger.static", function() {
    $(this).closest(".axxs-accordion").find(".h-trigger.active").toggleClass("active static");
    $(this).closest(".axxs-accordion").find(".section.expanded").toggleClass("expanded collapsed").attr("inert", true);
    $(this).toggleClass("static active");
    $(this).next(".section.collapsed").toggleClass("collapsed expanded").attr("inert", false);
  });

  $(".axxs-accordion").on("click", ".h-trigger.active", function() {
    $(this).toggleClass("active static");
    $(this).next(".section.expanded").toggleClass("expanded collapsed").attr("inert", true);
  });

  $("h2[tabindex='0']").focus();
});
.collapsed {
  height: 1px;
  overflow: hidden
}

.expanded {
  height: auto;
  overflow: auto
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="axxs-accordion">
  <h2>Heading</h2>
  <div>
    <p>Here is some content with text and an image</p>
    <p>Here is some more text</p>
  </div>
  <h2>Heading 2</h2>
  <section>
    <ul>
      <li>List item 1</li>
      <li>List item 2</li>
    </ul>
  </section>
</div>

Update 2

It's unclear from your description or example exactly what you want. For some reason, adding and removing the inert attribute is important.

$(function() {

  function toggleHeader(e) {
    var header = $(e.target);
    var parent = header.closest(".axxs-accordion");
    if (header.hasClass("static")) {
      $(".h-trigger.active", parent).toggleClass("active static");
      $(".section.expanded", parent).toggleClass("expanded collapsed").attr("inert", '');
      header.toggleClass("static active");
      header.next(".section.collapsed").toggleClass("collapsed expanded").removeAttr("inert");
    } else {
      header.toggleClass("active static");
      header.next(".section.expanded").toggleClass("expanded collapsed").attr("inert", '');
    }
  }

  $(".axxs-accordion > :header").addClass("h-trigger static").next().addClass("section collapsed").attr("inert", '');

  $('.h-trigger').each(function(i, el) {
    $(el).attr("tabindex", i);
    $(el).on("keydown", function(e) {
      console.log(e.key);
      switch (e.key.toLowerCase()) {
        case "enter":
        case " ":
          $(el).click();
          break;
        case "arrowdown":
          var i = $(el).attr("tabindex");
          $("h2[tabindex='" + ++i + "']").next("section").removeAttr("inert");
          break;
      }
    });
  });

  $(".axxs-accordion").on("click", ".h-trigger", toggleHeader);

  $("h2[tabindex='0']").focus();
});
.collapsed {
  height: 1px;
  overflow: hidden
}

.expanded {
  height: auto;
  overflow: auto
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="axxs-accordion">
  <h2>Heading 1</h2>
  <div>
    <p>Here is some content with text and an image</p>
    <p>Here is some more text</p>
  </div>
  <h2>Heading 2</h2>
  <section>
    <ul>
      <li>List item 1</li>
      <li>List item 2</li>
    </ul>
  </section>
  <h2>Heading 3</h2>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tortor posuere ac ut consequat semper viverra nam libero justo. Parturient montes nascetur ridiculus mus mauris vitae ultricies
      leo. Maecenas accumsan lacus vel facilisis volutpat est velit. At tempor commodo ullamcorper a lacus vestibulum. Purus viverra accumsan in nisl nisi. Sed felis eget velit aliquet. Consequat nisl vel pretium lectus. Sed tempus urna et pharetra pharetra
      massa massa ultricies. Augue mauris augue neque gravida in fermentum et sollicitudin. Amet nisl suscipit adipiscing bibendum. Augue eget arcu dictum varius. Ultrices gravida dictum fusce ut placerat orci. Quam lacus suspendisse faucibus interdum.
      Lectus quam id leo in. Amet commodo nulla facilisi nullam vehicula ipsum a arcu. Molestie at elementum eu facilisis sed odio. Commodo viverra maecenas accumsan lacus.</p>
  </section>
  <h2>Heading 4</h2>
  <section>
    <p>Turpis massa sed elementum tempus egestas. Aliquet bibendum enim facilisis gravida neque. Elit ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at. Ultrices eros in cursus turpis. In hendrerit gravida rutrum quisque non tellus. Pharetra
      pharetra massa massa ultricies mi quis hendrerit. Lacus viverra vitae congue eu consequat ac felis donec. Ut faucibus pulvinar elementum integer enim. Fermentum posuere urna nec tincidunt praesent semper. Fermentum odio eu feugiat pretium nibh ipsum
      consequat nisl vel. Dictum non consectetur a erat nam at lectus urna. Enim lobortis scelerisque fermentum dui faucibus in ornare quam viverra. Arcu non sodales neque sodales ut etiam sit amet nisl. Blandit cursus risus at ultrices mi tempus imperdiet
      nulla malesuada. Pellentesque sit amet porttitor eget dolor morbi non arcu risus. Ultrices neque ornare aenean euismod elementum nisi quis eleifend quam.</p>
  </section>
  <h2>Heading 5</h2>
  <section>
    <p>Massa vitae tortor condimentum lacinia quis vel eros. Tortor pretium viverra suspendisse potenti nullam ac tortor vitae. Molestie nunc non blandit massa enim nec dui nunc. Vitae congue mauris rhoncus aenean vel. Sed euismod nisi porta lorem. Mauris
      augue neque gravida in fermentum. Faucibus nisl tincidunt eget nullam non nisi. Viverra nibh cras pulvinar mattis nunc sed blandit libero. Id neque aliquam vestibulum morbi blandit cursus risus at. Netus et malesuada fames ac turpis egestas integer
      eget. Ac tortor dignissim convallis aenean et. Elit sed vulputate mi sit amet mauris commodo quis imperdiet. Ut faucibus pulvinar elementum integer enim. Elit ut aliquam purus sit amet luctus. At tempor commodo ullamcorper a lacus vestibulum. Pellentesque
      elit ullamcorper dignissim cras. Vel turpis nunc eget lorem dolor. Aliquet risus feugiat in ante metus dictum at. Mauris pharetra et ultrices neque ornare aenean euismod elementum nisi.</p>
  </section>
</div>

Update 4

I was not understanding, and it's sort of an odd one, it is the Next Adjacent Selector (“prev + next”) that you need.

https://api.jquery.com/next-adjacent-selector/

Selects all next elements matching "next" that are immediately preceded by a sibling "prev".

$(function() {

  $(".axxs-accordion > :header").each(function(i, el) {
    if ($(el).next().is("section")) {
      $(el).addClass("h-trigger static").next("section").addClass("section collapsed").attr("inert", true);
    }
  });

  $(document).on("keydown", function(e) {
    console.log(e.key);
    if (e.key.toLowerCase() == "arrowdown") {
      $(".h-trigger.focused + section").removeAttr("inert");
    }
  });
  $(".axxs-accordion").on("click", ".h-trigger", function() {
    console.log("Header " + $(this).index() + " Clicked, has focus");
    console.log("This Section " + ($(this).next("section").attr("inert") ? "is Inert" : "is not Inert"));
    $(this).addClass("focused").focus();
  });
});
.collapsed {
  height: 1px;
  overflow: hidden
}

.expanded {
  height: auto;
  overflow: auto
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="axxs-accordion">
  <h2>Heading 1</h2>
  <div>
    <p>Click on a Header below to Focus upon it.</p>
  </div>
  <h2>Heading 2</h2>
  <section>
    <ul>
      <li>List item 1</li>
      <li>List item 2</li>
    </ul>
  </section>
  <h2>Heading 3</h2>
  <section>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tortor posuere ac ut consequat semper viverra nam libero justo. Parturient montes nascetur ridiculus mus mauris vitae ultricies
      leo. Maecenas accumsan lacus vel facilisis volutpat est velit. At tempor commodo ullamcorper a lacus vestibulum. Purus viverra accumsan in nisl nisi. Sed felis eget velit aliquet. Consequat nisl vel pretium lectus. Sed tempus urna et pharetra pharetra
      massa massa ultricies. Augue mauris augue neque gravida in fermentum et sollicitudin. Amet nisl suscipit adipiscing bibendum. Augue eget arcu dictum varius. Ultrices gravida dictum fusce ut placerat orci. Quam lacus suspendisse faucibus interdum.
      Lectus quam id leo in. Amet commodo nulla facilisi nullam vehicula ipsum a arcu. Molestie at elementum eu facilisis sed odio. Commodo viverra maecenas accumsan lacus.</p>
  </section>
  <h2>Heading 4</h2>
  <section>
    <p>Turpis massa sed elementum tempus egestas. Aliquet bibendum enim facilisis gravida neque. Elit ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at. Ultrices eros in cursus turpis. In hendrerit gravida rutrum quisque non tellus. Pharetra
      pharetra massa massa ultricies mi quis hendrerit. Lacus viverra vitae congue eu consequat ac felis donec. Ut faucibus pulvinar elementum integer enim. Fermentum posuere urna nec tincidunt praesent semper. Fermentum odio eu feugiat pretium nibh ipsum
      consequat nisl vel. Dictum non consectetur a erat nam at lectus urna. Enim lobortis scelerisque fermentum dui faucibus in ornare quam viverra. Arcu non sodales neque sodales ut etiam sit amet nisl. Blandit cursus risus at ultrices mi tempus imperdiet
      nulla malesuada. Pellentesque sit amet porttitor eget dolor morbi non arcu risus. Ultrices neque ornare aenean euismod elementum nisi quis eleifend quam.</p>
  </section>
  <h2>Heading 5</h2>
  <section>
    <p>Massa vitae tortor condimentum lacinia quis vel eros. Tortor pretium viverra suspendisse potenti nullam ac tortor vitae. Molestie nunc non blandit massa enim nec dui nunc. Vitae congue mauris rhoncus aenean vel. Sed euismod nisi porta lorem. Mauris
      augue neque gravida in fermentum. Faucibus nisl tincidunt eget nullam non nisi. Viverra nibh cras pulvinar mattis nunc sed blandit libero. Id neque aliquam vestibulum morbi blandit cursus risus at. Netus et malesuada fames ac turpis egestas integer
      eget. Ac tortor dignissim convallis aenean et. Elit sed vulputate mi sit amet mauris commodo quis imperdiet. Ut faucibus pulvinar elementum integer enim. Elit ut aliquam purus sit amet luctus. At tempor commodo ullamcorper a lacus vestibulum. Pellentesque
      elit ullamcorper dignissim cras. Vel turpis nunc eget lorem dolor. Aliquet risus feugiat in ante metus dictum at. Mauris pharetra et ultrices neque ornare aenean euismod elementum nisi.</p>
  </section>
</div>

14
  • Thanks, but this doesn't work. If I'm focused on the first heading and I hit the down arrow key, it expands the second section (not the first), and it doesn't remove the attribute in the first section. To clarify again: if focus is set on a heading, I want the arrow to remove the attr on the section directly below it only, and not expand it. It should only expand on enter/spacebar.
    – DeanH
    Commented Jul 8 at 21:07
  • PS: see the codepen I added to the question. I don't think you can remove an attribute on something that is display:none (though I could be incorrect). And if the collapsed sections are completely hidden, screenreader users can't access them. Hence the point of my collapsing them to 1px and removing the inert attribute when they are interacting with the sections.
    – DeanH
    Commented Jul 8 at 21:34
  • 1
    @DeanH adding, changing, or removing an attribute is not effected by the element being displayed or not.
    – Twisty
    Commented Jul 8 at 22:37
  • OK, but it still doesn't work properly ;)
    – DeanH
    Commented Jul 9 at 1:52
  • @DeanH not sure what you are looking for, so maybe clarify further. I added another update that works the way you had it in your codepen.
    – Twisty
    Commented Jul 9 at 14:50

Not the answer you're looking for? Browse other questions tagged or ask your own question.