Добавить событие клика к нескольким идентификаторам

У меня есть элементы 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 элементов, было бы много кода.

Как я могу добиться этого для всех идентификаторов, написав только один раз?

А петля?

JRichardsz 20.08.2023 07:33

Добавьте атрибут имени с одинаковым значением для всех элементов и укажите ссылку на эту коллекцию по имени getelemntsbyname. Затем вы можете получить доступ ко всем из них в цикле, как упоминал JRichardsz.

Shahram Alemzadeh 20.08.2023 08:12

Вы пробовали делегирование событий?

Konrad 20.08.2023 08:30
[id1, id2, id3, idN].forEach(id => document.getElementById(id).style.<property> = <value>)
Mohammad Mostafa Dastjerdi 20.08.2023 08:30
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Решение

Получите все элементы этого типа класса, где, перебирая каждый из них с помощью цикла, вы можете применить операцию 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>. Как я могу это исправить?

nitinatsangsit 20.08.2023 10:16

В данном случае вы точно не использовали мой код. «Выполнить фрагмент кода» можно использовать для проверки того, что нажатие на другой SVG приводит к исчезновению другого «контента». В моем коде я обработал это в событии onclick. Если вы нажмете на элемент, я узнаю, на какой из них вы нажали, и скрою все остальные. Вы можете найти этот скрипт под комментарием «Скрыть все содержимое, кроме текущего».

rozsazoltan 20.08.2023 10:24

Важно, чтобы каждый многоугольник, g, путь и т. д. имели отдельное имя данных (и я счел более разумным размещать элемент содержимого на основе имени данных).

rozsazoltan 20.08.2023 10:25

Хорошо, я понял. Отсутствует часть содержимого div. Это сработало бы, если бы все они существовали. Спасибо.

nitinatsangsit 20.08.2023 11:17

Другие вопросы по теме