С одной стороны, в не древних браузерах вы можете использовать :scope
, чтобы указать элемент, для которого вызывается querySelector
. Но querySelector
будет только выбирать элементы, которые являются дочерними текущего элемента, а желаемым <ul>
является брат или сестра .
Вместо этого возьмите nextElementSibling
элемента, убедитесь, что он существует, и проверьте, что вместо него ul
:
for (const menu of document.querySelectorAll("nav div > a")) {
menu.addEventListener("mouseenter", function() {
console.log(menu, menu.nextElementSibling);
const subMenu = menu.nextElementSibling;
if (!subMenu || !subMenu.matches('ul')) {
return;
}
if (subMenu.style.display === "block") {
console.log("subMenu.style.display === block");
const subMenuBox = subMenu.getBoundingClientRect();
const posX = (subMenuBox.left + subMenuBox.width) - window.innerWidth;
subMenu.style.left = -posX;
console.log("When here successfully!");
} else {
console.log("Failed...");
}
})
}
body {
color: #fff;
font-size: 20px;
background: #999;
margin: 0;
}
a {
color: #cfc;
}
nav,
nav div>a,
nav div {
float: left;
}
nav {
width: 100%;
background: #4169E1;
white-space: nowrap;
}
nav div {
margin: 0em 0.2em;
}
nav div:first-child {
margin-left: 0;
}
nav div div {
position: relative;
margin: 0;
}
nav a {
color: #cff;
display: block;
font-weight: 600;
text-decoration: none;
padding: 0.5em 1em;
}
nav a:hover {
color: #fff;
background: #f90;
}
nav div>a+ul {
position: absolute;
top: 2.15em;
float: left;
background: #666;
list-style-type: none;
margin: 0;
padding: 0;
min-width: 180px;
display: none;
}
nav div:hover>a+ul {
display: block;
}
.right {
float: right;
}
<nav>
<div>
<a href="#A1">Menu A.1</a>
<a href="#A2">Menu A.2</a>
</div>
<div class="right">
<div>
<a href="#B1">Menu B.1</a>
<ul>
<li><a href="#B1.1">B.1 Sub 1</a></li>
<li><a href="#B1.2">B.1 Sub 2</a></li>
</ul>
</div>
<div>
<a href="#B2">Menu B.2</a>
<ul>
<li><a href="#B2.1 ">B.2 Sub 1</a></li>
<li><a href="#B2.2 ">B.2 Sub 2</a></li>
</ul>
</div>
<div>
<a href="#B3 ">Menu B.3</a>
<ul>
<li><a href="#B3.1 ">B.3 Sub 1 Test Longer Text</a></li>
<li><a href="#B3.2 ">B.3 Sub 2</a></li>
</ul>
</div>
<div>
<a href="#B4 ">Menu B.4</a>
<ul>
<li><a href="#B4.1 ">B.4 Sub 1</a></li>
<li><a href="#B4.2 ">B.4 Sub 2</a></li>
</ul>
</div>
</div>
</nav>
<div style="float: left; margin-top: 1000px "></div>
Поскольку не все меню имеют подменю, вам do необходимо проверить, существует ли UL сначала, прежде чем пытаться выполнить разберитесь с ним.
Обратите внимание, что subMenu.style.display === "block"
никогда не выполняется в данном коде, потому что <ul>
s не имеет style
свойств непосредственно для элементов . Если они это сделают, тест пройдет успешно. Если вы пытаетесь увидеть, отображаются ли они , используйте window.getComputedStyle
вместо:
for (const menu of document.querySelectorAll("nav div > a")) {
menu.addEventListener("mouseenter", function() {
console.log(menu, menu.nextElementSibling);
const subMenu = menu.nextElementSibling;
if (!subMenu || !subMenu.matches('ul')) {
return;
}
if (window.getComputedStyle(subMenu).display === "block") {
console.log("subMenu.style.display === block");
const subMenuBox = subMenu.getBoundingClientRect();
const posX = (subMenuBox.left + subMenuBox.width) - window.innerWidth;
subMenu.style.left = -posX;
console.log("When here successfully!");
} else {
console.log("Failed...");
}
})
}
body {
color: #fff;
font-size: 20px;
background: #999;
margin: 0;
}
a {
color: #cfc;
}
nav,
nav div>a,
nav div {
float: left;
}
nav {
width: 100%;
background: #4169E1;
white-space: nowrap;
}
nav div {
margin: 0em 0.2em;
}
nav div:first-child {
margin-left: 0;
}
nav div div {
position: relative;
margin: 0;
}
nav a {
color: #cff;
display: block;
font-weight: 600;
text-decoration: none;
padding: 0.5em 1em;
}
nav a:hover {
color: #fff;
background: #f90;
}
nav div>a+ul {
position: absolute;
top: 2.15em;
float: left;
background: #666;
list-style-type: none;
margin: 0;
padding: 0;
min-width: 180px;
display: none;
}
nav div:hover>a+ul {
display: block;
}
.right {
float: right;
}
<nav>
<div>
<a href="#A1">Menu A.1</a>
<a href="#A2">Menu A.2</a>
</div>
<div class="right">
<div>
<a href="#B1">Menu B.1</a>
<ul>
<li><a href="#B1.1">B.1 Sub 1</a></li>
<li><a href="#B1.2">B.1 Sub 2</a></li>
</ul>
</div>
<div>
<a href="#B2">Menu B.2</a>
<ul>
<li><a href="#B2.1 ">B.2 Sub 1</a></li>
<li><a href="#B2.2 ">B.2 Sub 2</a></li>
</ul>
</div>
<div>
<a href="#B3 ">Menu B.3</a>
<ul>
<li><a href="#B3.1 ">B.3 Sub 1 Test Longer Text</a></li>
<li><a href="#B3.2 ">B.3 Sub 2</a></li>
</ul>
</div>
<div>
<a href="#B4 ">Menu B.4</a>
<ul>
<li><a href="#B4.1 ">B.4 Sub 1</a></li>
<li><a href="#B4.2 ">B.4 Sub 2</a></li>
</ul>
</div>
</div>
</nav>
<div style="float: left; margin-top: 1000px "></div>