У меня есть элементы SVG (g, path, polygon) с уникальными идентификаторами для каждого, но они имеют один и тот же класс.
<svg>
<!-- 1002027 -->
<polygon id = "_1002027" data-name = "1002027" class = "site" points = "1708.49 1009.6 1719.01 1018.1 1752.71 1014.51 1761.21 1003.99 1757.63 970.29 1747.1 961.79 1713.41 965.37 1704.9 975.9 1708.49 1009.6"/>
<!-- 1002028 -->
<polygon id = "_1002028" data-name = "1002028" class = "site" points = "1708.49 1009.6 1719.01 1018.1 1752.71 1014.51 1761.21 1003.99 1757.63 970.29 1747.1 961.79 1713.41 965.37 1704.9 975.9 1708.49 1009.6"/>
<!-- ... -->
</svg>
Затем я хочу, чтобы соответствующий div отображался при нажатии на элемент и скрывался, если пользователь щелкает за пределами элемента.
<div id = "content_1002027" class = "svgcontent"">Text Here</div>
<!-- and -->
<div id = "content_1002028" class = "svgcontent"">Text Here</div>
<!-- ... -->
Теперь я могу добиться этого с помощью этого скрипта:
// Show 1002027
document.getElementById('_1002027').addEventListener('click', function (event) {
document.getElementById("content_1002027").style.display = "block";
}, false);
// Show 1002028
document.getElementById('_1002028').addEventListener('click', function (event) {
document.getElementById("content_1002028").style.display = "block";
}, false);
document.addEventListener('click', function clickOutside(event) {
// Hide 1002027
if (!document.getElementById('_1002027').contains(event.target)) {
document.getElementById("content_1002027").style.display = 'none';
}
// Hide 1002028
if (!document.getElementById('_1002028').contains(event.target)) {
document.getElementById("content_1002028").style.display = 'none';
}
});
Однако с помощью этого метода мне приходится повторять этот скрипт для каждого идентификатора. Если бы у меня было 60 элементов, было бы много кода.
Как я могу добиться этого для всех идентификаторов, написав только один раз?
Добавьте атрибут имени с одинаковым значением для всех элементов и укажите ссылку на эту коллекцию по имени getelemntsbyname. Затем вы можете получить доступ ко всем из них в цикле, как упоминал JRichardsz.
Вы пробовали делегирование событий?
[id1, id2, id3, idN].forEach(id => document.getElementById(id).style.<property> = <value>)


![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Получите все элементы этого типа класса, где, перебирая каждый из них с помощью цикла, вы можете применить операцию onclick к каждому из них.
const siteElements = document.querySelectorAll('svg > .site');
// Add click event listener to all '.site' elements
siteElements.forEach((element) => {
element.addEventListener('click', function (event) {
// Show content for this element
document.getElementById(`content_${this.getAttribute('data-name')}`).style.display = 'block';
// Hide all content except the current one
siteElements.forEach(site => {
if (site !== this) {
document.getElementById(`content_${site.getAttribute('data-name')}`).style.display = 'none';
}
});
}, false);
})
// Add click event listener to the document (detect clicks outside)
document.addEventListener('click', function clickOutside(event) {
// If the clicked element is not a '.site' element
const clickedOnSite = Array.from(siteElements).some(site => site.contains(event.target));
if (!clickedOnSite) {
// Hide all content
document.querySelectorAll('.svgcontent').forEach(content => {
content.style.display = 'none';
});
}
});.svgcontent {
display: none;
}<!-- 1. -->
<div>
<svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 1920 1080">
<polygon id = "_1002027" data-name = "1002027" class = "site" points = "1708.49 1009.6 1719.01 1018.1 1752.71 1014.51 1761.21 1003.99 1757.63 970.29 1747.1 961.79 1713.41 965.37 1704.9 975.9 1708.49 1009.6" />
</svg>
<div id = "content_1002027" class = "svgcontent">Text Here</div>
</div>
<!-- 2. -->
<div>
<svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 1920 1080">
<polygon id = "_1002028" data-name = "1002028" class = "site" points = "1708.49 1009.6 1719.01 1018.1 1752.71 1014.51 1761.21 1003.99 1757.63 970.29 1747.1 961.79 1713.41 965.37 1704.9 975.9 1708.49 1009.6" />
</svg>
<div id = "content_1002028" class = "svgcontent">Text Here</div>
</div>
<!-- ... -->Есть еще проблема. Когда я щелкнул другой элемент .site, появилось новое содержимое, в то время как предыдущее оставалось видимым. Чтобы очистить все содержимое, мне нужно нажать на пустую область. Может быть, потому что все они находятся в одном элементе <svg>. Как я могу это исправить?
В данном случае вы точно не использовали мой код. «Выполнить фрагмент кода» можно использовать для проверки того, что нажатие на другой SVG приводит к исчезновению другого «контента». В моем коде я обработал это в событии onclick. Если вы нажмете на элемент, я узнаю, на какой из них вы нажали, и скрою все остальные. Вы можете найти этот скрипт под комментарием «Скрыть все содержимое, кроме текущего».
Важно, чтобы каждый многоугольник, g, путь и т. д. имели отдельное имя данных (и я счел более разумным размещать элемент содержимого на основе имени данных).
Хорошо, я понял. Отсутствует часть содержимого div. Это сработало бы, если бы все они существовали. Спасибо.
А петля?