简体   繁体   English

带有 WAI-ARIA 的可折叠部分:附加的“隐藏”按钮?

[英]Collapsible section with WAI-ARIA: additional "hide" button?

I'm using this code snippet (explained here ) to create a collapsible section using WAI-ARIA.我正在使用此代码片段在此处解释)使用 WAI-ARIA 创建可折叠部分。 My collapsible text is very long though, so that I would like to add an additional "hide" button at the bottom of the text so that readers don't have to scroll up to click on the original button to collapse the section.不过,我的可折叠文本很长,因此我想在文本底部添加一个额外的“隐藏”按钮,这样读者就不必向上滚动以单击原始按钮来折叠该部分。 I can't quite figure out how to get such a button to work.我不太明白如何让这样的按钮工作。 I would very much appreciate your help.我非常感谢您的帮助。

HTML: HTML:

<main> 
  <h3>Section 1</h3>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula.</p> 
    <p>Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero. Nullam tortor metus, tincidunt ut urna id, posuere placerat orci. Ut quis risus dictum risus facilisis imperdiet quis sed eros.</p>
  <h3>Section 2</h3>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
</main>

CSS: CSS:

body {
  max-width: 40rem;
  margin: 0 auto;
  padding: 1em;
}

main {
  border-width: 2px 0;
  border-style: solid;
}

main h2 {
  margin: 0;
}

main > div + h2 {
  border-top: 2px solid;
}

h2 button {
  all: inherit;
  border: 0;
  display: flex;
  justify-content: space-between;
  width: 100%;
  padding: 0.5em 0;
}   
    
h2 button:focus svg {
  outline: 2px solid;
}

button svg {
  height: 1em;
  margin-left: 0.5em;
}

[aria-expanded="true"] .vert {
  display: none;
}

[aria-expanded] rect {
  fill: currentColor;
}

/* page styles */

html {
  font-family: Arial, sans-serif;
}

* {
  box-sizing: border-box;
}

JavaScript: JavaScript:

 (function() {
  // Get all the <h2> headings
  const headings = document.querySelectorAll('main h2')
  
  Array.prototype.forEach.call(headings, heading => {
    // Give each <h2> a toggle button child
    // with the SVG plus/minus icon
    heading.innerHTML = `
      <button aria-expanded="false">
        ${heading.textContent}
        <svg aria-hidden="true" focusable="false" viewBox="0 0 10 10">
          <rect class="vert" height="8" width="2" y="1" x="4"/>
          <rect height="2" width="8" y="4" x="1"/>
        </svg>
      </button>
    `
    
    // Function to create a node list 
    // of the content between this <h2> and the next
    const getContent = (elem) => {
      let elems = []
      while (elem.nextElementSibling && elem.nextElementSibling.tagName !== 'H2') {
        elems.push(elem.nextElementSibling)
        elem = elem.nextElementSibling
      }
      
      // Delete the old versions of the content nodes
      elems.forEach((node) => {
        node.parentNode.removeChild(node)
      })

      return elems
    }
    
    // Assign the contents to be expanded/collapsed (array)
    let contents = getContent(heading)
    
    // Create a wrapper element for `contents` and hide it
    let wrapper = document.createElement('div')
    wrapper.hidden = true
    
    // Add each element of `contents` to `wrapper`
    contents.forEach(node => {
      wrapper.appendChild(node)
    })
    
    // Add the wrapped content back into the DOM 
    // after the heading
    heading.parentNode.insertBefore(wrapper, heading.nextElementSibling)
    
    // Assign the button
    let btn = heading.querySelector('button')
    
    btn.onclick = () => {
      // Cast the state as a boolean
      let expanded = btn.getAttribute('aria-expanded') === 'true' || false
      
      // Switch the state
      btn.setAttribute('aria-expanded', !expanded)
      // Switch the content's visibility
      wrapper.hidden = expanded    
    }
  })
})()

what about to stick them on top so always you can collapse.怎么把它们粘在上面,这样你就可以崩溃了。

here is the example https://jsfiddle.net/zb0xkuL5/这是示例https://jsfiddle.net/zb0xkuL5/

and this is the code这是代码

<html>
<body>
 

<main>
    <h2>Section 1</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula.</p> 
    <p>Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero. Nullam tortor metus, tincidunt ut urna id, posuere placerat orci. Ut quis risus dictum risus facilisis imperdiet quis sed eros.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>

    <h2>Section 2</h2>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>
    <p>Nullam tortor metus, tincidunt ut urna id, posuere placerat orci.</p> 
    <p>Ut quis risus dictum risus facilisis imperdiet quis sed eros. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> 
    <p>Quisque commodo purus quis mi cursus hendrerit eu eu metus. Aliquam aliquam arcu eget aliquet scelerisque. Pellentesque sodales turpis vitae venenatis vehicula. Ut id porta velit. Ut eu dignissim dui, quis gravida est. Cras quis venenatis mauris, a bibendum enim. Sed at augue libero.</p>

</main>  </body>
</html>
<style>  
 body {
  max-width: 40rem;
  margin: 0 auto;
  padding: 1em;
}

main {
  border-width: 2px 0;
  border-style: solid;
}

main h2 {
    top: 0;
    position: sticky;
    background: #fff;
  margin: 0;
}

main > div + h2 {
  border-top: 2px solid;
}

h2 button {
  all: inherit;
  border: 0;
  display: flex;
  justify-content: space-between;
  width: 100%;
  padding: 0.5em 0;
}



h2 button:focus svg {
  outline: 2px solid;
}

button svg {
  height: 1em;
  margin-left: 0.5em;
}

[aria-expanded="true"] .vert {
  display: none;
}

[aria-expanded] rect {
  fill: currentColor;
}

/* page styles */

html {
  font-family: Arial, sans-serif;
}

* {
  box-sizing: border-box;
}
</style>
<script>  
    (function() {
   // Get all the <h2> headings
   const headings = document.querySelectorAll('main h2')
   
   Array.prototype.forEach.call(headings, heading => {
     // Give each <h2> a toggle button child
     // with the SVG plus/minus icon
     heading.innerHTML = `
       <button aria-expanded="false">
         ${heading.textContent}
         <svg aria-hidden="true" focusable="false" viewBox="0 0 10 10">
           <rect class="vert" height="8" width="2" y="1" x="4"/>
           <rect height="2" width="8" y="4" x="1"/>
         </svg>
       </button>
     `
     
     // Function to create a node list 
     // of the content between this <h2> and the next
     const getContent = (elem) => {
       let elems = []
       while (elem.nextElementSibling && elem.nextElementSibling.tagName !== 'H2') {
         elems.push(elem.nextElementSibling)
         elem = elem.nextElementSibling
       }
       
       // Delete the old versions of the content nodes
       elems.forEach((node) => {
         node.parentNode.removeChild(node)
       })
 
       return elems
     }
     
     // Assign the contents to be expanded/collapsed (array)
     let contents = getContent(heading)
     
     // Create a wrapper element for `contents` and hide it
     let wrapper = document.createElement('div')
     wrapper.hidden = true
     
     // Add each element of `contents` to `wrapper`
     contents.forEach(node => {
       wrapper.appendChild(node)
     })
     
     // Add the wrapped content back into the DOM 
     // after the heading
     heading.parentNode.insertBefore(wrapper, heading.nextElementSibling)
     
     // Assign the button
     let btn = heading.querySelector('button')
     
     btn.onclick = () => {
       // Cast the state as a boolean
       let expanded = btn.getAttribute('aria-expanded') === 'true' || false
       
       // Switch the state
       btn.setAttribute('aria-expanded', !expanded)
       // Switch the content's visibility
       wrapper.hidden = expanded    
     }
   })
 })()
      </script>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM