액세스 가능한 드롭다운 탐색 만들기
27997 단어 a11ywebdevjavascript
HTML:
<nav>
<ul class="menu">
<li class="menu__item">
<a href="/" class="menu__link">About</a>
<ul class="submenu">
<li class="submenu__item">
<a class="submenu__link" href="/our-mission">Our Mission</a>
</li>
<li class="submenu__item">
<a class="submenu__link" href="/our-team">Our Team</a>
</li>
</ul>
</li>
</ul>
</nav>
CSS:.submenu {
position: absolute;
left: 0;
padding: 0;
list-style: none;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
}
.menu__item:hover .submenu {
padding: 0.5rem 0;
width: 9rem;
height: auto;
background: #eedbff;
clip: auto;
}
주의: visually-hidden 스타일이 아니라 display: none
스타일을 사용했습니다.이것은 접근성에 매우 중요합니다. 위의 링크에서 더 많은 내용을 읽을 수 있습니다.나는 일반적인 스타일을 좀 뺐지만, 이 CSS는 정지 효과를 초래하는 원인이다.그러나, 아래gif에서 보듯이tab키를 사용하면 작업 방식이 달라집니다.
우리가 인코딩을 시작하기 전에, 나는 내가 이 문제를 해결하는 방법을 공유하고 싶다.우선, 내가 해결하고 싶은 문제는 정지할 때 내비게이션을 열 뿐만 아니라, 초점을 맞출 때 내비게이션을 열 수 있다는 것이다.둘째, 초점을 맞출 때 모든 하위 메뉴가 멈출 때처럼 열려 있는지 확인하고 싶습니다.셋째, 링크를 클릭하면 내가 떠날 때 특정한 하위 메뉴가 닫히는 것을 확보하고 싶습니다.이제 시작합시다!
초점에 스톱 효과 복사하기
우리는
:hover
원소에 li
위류가 있기 때문에 li
원소에 주목해야 한다.하지만 내 블로그 글을 읽으면tabindexes의 개념을 알게 될 것이다.li
요소는tabindexes가 없지만 링크가 있습니다.개인적으로 좋아하는 것은 자바스크립트의 최고급 링크를 겨냥하고 초점 이벤트에 부모에게 클래스를 추가하는 것이다.우리 좀 더 알아보자.const topLevelLinks = document.querySelectorAll('.menu__link');
console.log(topLevelLinks);
console.log
변수가 있을 때, 나는 맨 위 메뉴 항목의 노드 목록을 얻었다.내가 좋아하는 것은 forEach
이 대상들을 반복해서 훑어보고 parentElement
의 로그를 기록하는 것이다.topLevelLinks.forEach(link => {
console.log(link.parentElement);
});
지금 내가 해야 할 일은 링크에
focus
이벤트 탐지기를 추가하고 컨트롤러를 추가하는 것이다.this
의 상하문이 정확한지 다시 확인하기 위해 기록this
.topLevelLinks.forEach(link => {
link.addEventListener('focus', function() {
console.log(this);
});
});
나는 ES6+화살표 함수가 아니라 구식 함수를 사용한다. 왜냐하면 나는
this
의 상하문이 목표라는 것을 확보하고 싶기 때문이다.만약 당신이 더 많은 것을 알고 싶다면, 이것에 관한 블로그 게시물이 매우 많다. (하하, 내가 거기서 무엇을 했는지 봐라.)어쨌든 지금 나는 그것을 원한다. 그러면 우리의 목표는 parentElement
, 즉 li
이다.topLevelLinks.forEach(link => {
link.addEventListener('focus', function() {
console.log(this.parentElement);
});
});
이 부원소는 우리가 조준해야 할 것이다.내가 해야 할 일은 우리가 컨트롤러에 로그인한 리에 클래스를 추가하는 것이다.그리고 내가 할 일은 CSS 클래스를 사용하여 우리가
:hover
에 있는 스타일을 복제하는 것이다.topLevelLinks.forEach(link => {
link.addEventListener('focus', function() {
this.parentElement.classList.add('focus');
});
});
.menu__item:hover .submenu,
.menu__item.focus .submenu {
padding: 0.5rem 0;
width: 9rem;
height: auto;
background: #eedbff;
clip: auto;
}
보시다시피 메뉴는 우리가 떠난 후에 닫히지 않았습니다. 이것은 제가 열거한 행동 항목 중의 하나입니다.그 전에
blur
사건과 이것이 무엇을 의미하는지 알아보자.모호한 사건
모질라 docs에 따르면 요소가 초점을 잃을 때 촉발됩니다blur event.마지막 하위 메뉴 항목이 초점을 잃을 때까지 하위 메뉴를 열기를 원합니다.그래서 우리가 해야 할 일은 모호한 초점류를 삭제하는 것이다.
내가 좋아하는 첫 번째 일은 우리가 가지고 있는forEach 순환에서 존재하는지 확인하는 것이다
nextElementSibling
.topLevelLinks.forEach(link => {
link.addEventListener('focus', function() {
this.parentElement.classList.add('focus');
});
console.log(link.nextElementSibling);
});
다음에 내가 해야 할 일은 조건을 만드는 것이다.하위 메뉴가 있다면, 우리는 아래 코드만 실행하고 싶습니다.다음은 내가 한 일이다.
topLevelLinks.forEach(link => {
link.addEventListener('focus', function() {
this.parentElement.classList.add('focus');
});
if (link.nextElementSibling) {
const subMenu = link.nextElementSibling;
console.log(subMenu);
console.log(subMenu.querySelectorAll('a'));
}
});
내가
subMenu
과querySelectorAll
를 기록한 이유는 시각 학습을 위해서이다.이 두 개의 하위 메뉴 요소가 모두 정확하게 위치를 정하고 그 안에 연결된 노드 목록을 보니 나는 매우 기쁘다.그래서 내가 여기서 하고 싶은 것은 그 중의 마지막 링크querySelectorAll
를 겨냥한 것이다.우리는 그것을 변수에 넣어서 더욱 읽을 수 있게 합시다.topLevelLinks.forEach(link => {
link.addEventListener('focus', function() {
this.parentElement.classList.add('focus');
});
if (link.nextElementSibling) {
const subMenu = link.nextElementSibling;
const subMenuLinks = subMenu.querySelectorAll('a');
const lastLinkIndex = subMenuLinks.length - 1;
console.log(lastLinkIndex);
const lastLink = subMenuLinks[lastLinkIndex];
console.log(lastLink);
}
});
마지막 링크마다 클래스
li
를 삭제하는 모호한 이벤트를 추가하고 싶습니다.우선 우리가 예상한 결과를 얻었는지 확인하기 위해 link.parentElement
를 봅시다.topLevelLinks.forEach(link => {
link.addEventListener('focus', function() {
this.parentElement.classList.add('focus');
});
if (link.nextElementSibling) {
const subMenu = link.nextElementSibling;
const subMenuLinks = subMenu.querySelectorAll('a');
const lastLinkIndex = subMenuLinks.length - 1;
const lastLink = subMenuLinks[lastLinkIndex];
lastLink.addEventListener('blur', function() {
console.log(link.parentElement);
});
}
});
이제 우리는 우리가 바라는 것을 얻었다. 나는 사건 탐지기에 초점을 맞추는 것과 상반된 일을 할 것이다.
topLevelLinks.forEach(link => {
link.addEventListener('focus', function() {
this.parentElement.classList.add('focus');
});
if (link.nextElementSibling) {
const subMenu = link.nextElementSibling;
const subMenuLinks = subMenu.querySelectorAll('a');
const lastLinkIndex = subMenuLinks.length - 1;
const lastLink = subMenuLinks[lastLinkIndex];
lastLink.addEventListener('blur', function() {
link.parentElement.classList.remove('focus');
});
}
});
내가 해야 할 마지막 일은 초점 사건 탐지기를 이 조건 문장에 놓는 것이다.사실상, 우리는 하위 메뉴가 없는 항목에 초점 클래스를 추가할 필요가 없다.
topLevelLinks.forEach(link => {
if (link.nextElementSibling) {
link.addEventListener('focus', function() {
this.parentElement.classList.add('focus');
});
const subMenu = link.nextElementSibling;
const subMenuLinks = subMenu.querySelectorAll('a');
const lastLinkIndex = subMenuLinks.length - 1;
const lastLink = subMenuLinks[lastLinkIndex];
lastLink.addEventListener('blur', function() {
link.parentElement.classList.remove('focus');
});
}
});
기타 과제
이 박문은 갈수록 길어지기 때문에 아마도 다음 주에 나는 후속 문장을 한 편 만들 것이다.내 후속 게시물 중 내가 아직 해결하지 못한 것이 하나 있다. 바로 메뉴에서 어떻게 후퇴하는가이다.
tab
및 shift
키를 동시에 사용하면 메뉴로 돌아갈 때 효과가 없습니다.만약 당신이 별도의 도전을 원한다면, 스스로 해 보세요!지금 이대로!만약 이것이 나와 다르다면, 나는 네가 어떻게 해결 방안을 생각해 냈는지 매우 보고 싶다.너의 생각을 나에게 알려줘!
Reference
이 문제에 관하여(액세스 가능한 드롭다운 탐색 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/lkopacz/create-an-accessible-dropdown-navigation-114n텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)