#javascript
#javascript
Вопрос:
Мне нужно удерживать выпадающий список при щелчке внутри элементов выпадающего списка, для чего я добавил две строки с комментариями под комментарием к задаче в моем JS-файле ниже, и это неправильный путь, но он удерживает выпадающий список при нажатии на элементы выпадающего списка, но он прерывается одна из моих функций, то есть когда я делаю щелчок вне области выпадающего списка, выпадающий список сворачивается. Ошибка, возникающая на консоли, гласит «Uncaught TypeError» addEventListener не является функцией. Пожалуйста, поправьте меня, используя только чистый javascript.
HTML -
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://unpkg.com/98.css">
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
<title>Test</title>
</head>
<body>
<div class="window" style="width: 100%">
<div class="title-bar">
<div class="title-bar-text">Test Page</div>
<div class="title-bar-controls">
<button aria-label="Minimize"></button>
<button aria-label="Maximize"></button>
<button aria-label="Close"></button>
</div>
</div>
<!-- Main menu -->
<div class="window-body">
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_file')">File</button>
<div class="dropdown-content" id="dd_file">
<a href="#">Open</a>
<a href="#">Close</a>
<a href="#">Settings</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_edit')">Edit</button>
<div class="dropdown-content" id="dd_edit">
<a href="#">Cut</a>
<a href="#">Copy</a>
<a href="#">Paste</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_view')">View</button>
<div class="dropdown-content" id="dd_view">
<a href="#">Toggle CSS</a>
<a href="#">Toggle Javascript</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_tools')">Tools</button>
<div class="dropdown-content" id="dd_tools">
<a href="#">Not Decided</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_favorite')">Favourties</button>
<div class="dropdown-content" id="dd_favorite">
<a href="#">Add New Favorite</a>
<a href="#">Add this Page to Favorites</a>
<a href="#">Show Favorites</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_help')">Help</button>
<div class="dropdown-content" id="dd_help">
<a
href="#">Final</a>
</div>
</div>
</div>
</div>
</body>
</html>
CSS -
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
JS-
function open_dropdown(element_id) {
console.log('Opening Dropdown:', element_id)
close_all_dropdowns()
document.getElementById(element_id).style.display = 'block';
}
// Close the dropdown if the user clicks outside of it
function close_dropdown(element) {
console.log('I am closing dropdown:', element)
element.style.display = 'none'
}
// Close all dropdowns.
function close_all_dropdowns() {
var dropdowns = document.getElementsByClassName('dropdown-content')
for (var i = 0; i < dropdowns.length; i ) {
close_dropdown(dropdowns[i]);
}
}
// Close all dropdowns.
function close_all_dropdowns() {
var dropdowns = document.getElementsByClassName('dropdown-content')
for (var i = 0; i < dropdowns.length; i ) {
close_dropdown(dropdowns[i]);
}
}
// Close all dropdowns when clicking outside.
window.onclick = function (e) {
//TO-DO
//document.getElementsByClassName(' ').addEventListener('click',
//function (e) {e.stopPropagation(); });
if (!e.target.matches('.dropbtn')) {
close_all_dropdowns()
}
}
Комментарии:
1. По ошибке я оставил getElementsByClassName(‘ ‘) пустым, что находится чуть ниже TO-DO в js. Это был //document.getElementsByClassName(‘выпадающее содержимое’).addEventListener(‘click’, //function (e) {e.stopPropagation(); });
2. getElementsByClassName возвращает коллекцию, вам нужно выделить ее, чтобы добавить прослушиватель событий. Попробуйте getElementsByClassName(‘dropdown-content’)[0].addEventListener, чтобы избавиться от ошибки типа
3. @Sydney Y, большое вам спасибо, это сработало!
4. В этом была вся проблема? Думаю, я напишу ответ…
Ответ №1:
Добавьте прослушиватель событий ко всем вашим ссылкам. Я добавил это в нижнюю часть вашего JS.
window.onload = (event) => {
alert('page is fully loaded')
var elements = document.querySelectorAll('.dropdown a')
for (var i = 0, len = elements.length; i < len; i ) {
elements[i].onclick = function (e) {
alert('clicked a link')
e.stopPropagation()
}
}
}
function open_dropdown(element_id) {
close_all_dropdowns()
document.getElementById(element_id).style.display = 'block';
}
// Close the dropdown if the user clicks outside of it
function close_dropdown(element) {
element.style.display = 'none'
}
// Close all dropdowns.
function close_all_dropdowns() {
var dropdowns = document.getElementsByClassName('dropdown-content')
for (var i = 0; i < dropdowns.length; i ) {
close_dropdown(dropdowns[i]);
}
}
// Close all dropdowns when clicking outside.
window.onclick = function (e) {
//TO-DO
//document.getElementsByClassName(' ').addEventListener('click',
//function (e) {e.stopPropagation(); });
if (!e.target.matches('.dropbtn')) {
close_all_dropdowns()
}
}
window.onload = (event) => {
var elements = document.querySelectorAll('.dropdown a');
for(var i = 0, len = elements.length; i < len; i ) {
elements[i].onclick = function (e) {
e.stopPropagation()
}
}
};
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
float: none;
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left;
}
<body>
<!-- Main menu -->
<div class="window-body">
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_file')">File</button>
<div class="dropdown-content" id="dd_file">
<a href="#">Open</a>
<a href="#">Close</a>
<a href="#">Settings</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_edit')">Edit</button>
<div class="dropdown-content" id="dd_edit">
<a href="#">Cut</a>
<a href="#">Copy</a>
<a href="#">Paste</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_view')">View</button>
<div class="dropdown-content" id="dd_view">
<a href="#">Toggle CSS</a>
<a href="#">Toggle Javascript</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_tools')">Tools</button>
<div class="dropdown-content" id="dd_tools">
<a href="#">Not Decided</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_favorite')">Favourties</button>
<div class="dropdown-content" id="dd_favorite">
<a href="#">Add New Favorite</a>
<a href="#">Add this Page to Favorites</a>
<a href="#">Show Favorites</a>
</div>
</div>
<div class="dropdown">
<button class="dropbtn" onclick="open_dropdown('dd_help')">Help</button>
<div class="dropdown-content" id="dd_help">
<a
href="#">Final</a>
</div>
</div>
</div>
</div>
</body>
Комментарии:
1. Просто будьте осторожны, если у вас есть другие ссылки на вашей странице, которые вы хотите вести себя нормально!
2. Я изменил его на «документ. querySelectorAll(‘.dropdown a’)». Так что это относится только к ссылкам в выпадающем списке.
3. @Aaron Tomlinson , я точно так же сделал. Также я попробовал — var elements = document.getElementsByClassName(‘выпадающее содержимое’); // Это тоже работает нормально
Ответ №2:
document.getElementsByClassName('dropdown-content')
Этот метод возвращает коллекцию элементов HTML и addEventListener
может быть применен только к одному элементу.
Чтобы добавить слушателя к каждому элементу в коллекции, вы должны перебирать их и применять к каждому из них.
Чтобы добавить слушателя только к одному элементу, вы можете просто добавить индекс:
document.getElementsByClassName('dropdown-content')[0].addEventListener('click', function (e) {
e.stopPropagation();
});