【问题标题】:Find the element before and after a specific element with pure javascript使用纯javascript查找特定元素之前和之后的元素
【发布时间】:2012-07-13 17:15:14
【问题描述】:

有一个这样的链接列表:

<ul>
    <li><a href="#">First tab</a></li>
    <li><a href="#">Second tab</a></li>
    <li class="active"><a href="#">Active tab</a></li>
    <li><a href="#">Fourth tab</a></li>
    <li><a href="#">Fifth tab</a></li>
</ul>

如何在活动标签之前和之后找到元素? (在本例中为第二个和第四个选项卡)。


我只在 纯 JavaScript 中寻找解决方案,因为 jQuery 解决方案是 here

注意: IE8 和 FF3 不支持 nextElementSiblingpreviousElementSibling,因此请发布这些浏览器也支持的解决方案。谢谢。

【问题讨论】:

标签: javascript


【解决方案1】:

假设您的&lt;ul&gt; 元素被称为element

var active, prev, next;
active = prev = next = element.querySelector('.active');

do prev = prev.previousSibling; while(prev && prev.nodeType !== 1);
do next = next.nextSibling;     while(next && next.nodeType !== 1);

这适用于 Internet Explorer 8。如果您只担心现代浏览器:

var active = element.querySelector('.active');
var prev = active.previousElementSibling;
var next = active.nextElementSibling;

【讨论】:

    【解决方案2】:

    很容易,只要有最新的浏览器:

    // here we first retrieve the currently-active element, via
    // document.getElementsByClassName(), using bracket-notation
    // to access a specific element-node from the HTMLCollection;
    // the zeroth element is the first element in the array-like
    // collection:
    const activeTab = document.getElementsByClassName('active')[0],
      // from that element-node we find the previous sibling element:
      activePrevSibling = activeTab.previousElementSibling,
      // and also the next sibling element:
      activeNextSibling = activeTab.nextElementSibling;
    
    // we then set the background-color of these elements:
    activeTab.style.backgroundColor = '#0f0';
    activePrevSibling.style.backgroundColor = '#f00';
    activeNextSibling.style.backgroundColor = '#00f';
    *,
     ::before,
     ::after {
      box-sizing: border-box;
      font-family: sans-serif;
      font-size: 1rem;
      font-weight: 400;
      line-height: 1.5;
    }
    
    ul,
    li {
      list-style-type: none;
    }
    
    ul {
      display: flex;
      gap: 0.5em;
      margin-block: 1em;
      margin-inline: auto;
      width: clamp(20em, 80vw, 600px);
    }
    
    li {
      background-color: #fff;
      border-radius: 1em;
      display: flex;
      flex-grow: 1;
      font-size: 2em;
      place-content: center;
      text-align: center;
    }
    
    a {
      background-color: #fffa;
      border-radius: 1em;
      color: #000;
      padding-block: 0.25em;
      padding-inline: 0.5em;
      text-decoration: underline;
      text-decoration-color: transparent;
      text-underline-offset: 0.01em;
      transition: all 0.3s linear;
    }
    
    a:focus-visible {
      background-color: #fffc;
      outline-color: currentColor;
      outline-offset: 0.1em;
      outline-style: solid;
      outline-width: 0.2em;
      scale: 1.2;
    }
    
    a:active,
    a:hover,
    a:focus {
      text-decoration-color: currentColor;
      text-underline-offset: 0.25em;
    }
    <ul>
      <li><a href="#">First tab</a></li>
      <li><a href="#">Second tab</a></li>
      <li class="active"><a href="#">Active tab</a></li>
      <li><a href="#">Fourth tab</a></li>
      <li><a href="#">Fifth tab</a></li>
    </ul>

    JS Fiddle demo(带有可怕,可怕的颜色......)。


    以上编辑,基于 Esailija 留下的评论:

    document.querySelector(".active") 更受支持,更简洁:

    // exactly as above, with the exception we're now retrieving the first,
    // and only, element from the document that matches the supplied CSS
    // selector; bear in mind that this method will return null if no
    // matching element is found; so sanity-checks should be used in
    // production code:
    const activeTab = document.querySelector(".active"),
      activePrevSibling = activeTab.previousElementSibling,
      activeNextSibling = activeTab.nextElementSibling;
    
    activeTab.style.backgroundColor = '#0f0';
    activePrevSibling.style.backgroundColor = '#f00';
    activeNextSibling.style.backgroundColor = '#00f';
    *,
     ::before,
     ::after {
      box-sizing: border-box;
      font-family: sans-serif;
      font-size: 1rem;
      font-weight: 400;
      line-height: 1.5;
    }
    
    ul,
    li {
      list-style-type: none;
    }
    
    ul {
      display: flex;
      gap: 0.5em;
      margin-block: 1em;
      margin-inline: auto;
      width: clamp(20em, 80vw, 600px);
    }
    
    li {
      background-color: #fff;
      border-radius: 1em;
      display: flex;
      flex-grow: 1;
      font-size: 2em;
      place-content: center;
      text-align: center;
    }
    
    a {
      background-color: #fffa;
      border-radius: 1em;
      color: #000;
      padding-block: 0.25em;
      padding-inline: 0.5em;
      text-decoration: underline;
      text-decoration-color: transparent;
      text-underline-offset: 0.01em;
      transition: all 0.3s linear;
    }
    
    a:focus-visible {
      background-color: #fffc;
      outline-color: currentColor;
      outline-offset: 0.1em;
      outline-style: solid;
      outline-width: 0.2em;
      scale: 1.2;
    }
    
    a:active,
    a:hover,
    a:focus {
      text-decoration-color: currentColor;
      text-underline-offset: 0.25em;
    }
    <ul>
      <li><a href="#">First tab</a></li>
      <li><a href="#">Second tab</a></li>
      <li class="active"><a href="#">Active tab</a></li>
      <li><a href="#">Fourth tab</a></li>
      <li><a href="#">Fifth tab</a></li>
    </ul>

    JS Fiddle demo.

    参考资料:

    【讨论】:

    • document.querySelector(".active") 支持更简洁;P
    • 真的吗?我(显然,我想)从来不知道。谢谢(和编辑!)
    • @Esailija:嗯,任何支持*ElementSibling的浏览器也支持getElementsByClassName...但肯定更简洁。我想知道相比之下它的表现如何?
    • @minitech:我感觉 JS Perf 来了..!
    • @Ωmega:大卫明确指出了这一点:“[...] 给定了一个最新的浏览器”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多