Рефакторинг кода с помощью встроенного JavaScript

Я пытаюсь реорганизовать этот w3schools для кода с переключаемыми вкладками, потому что все мы знаем, что использование встроенного JavaScript — очень плохая практика, поэтому я пытаюсь максимально их разделить, поэтому я выбрал tablinks и добавил прослушиватель событий. но я борюсь с названиями городов (взгляните на их код, и вы поймете, о чем я говорю)

любая помощь, пожалуйста, и спасибо заранее

HTML

<!-- Tab links -->
<div class = "tab">
  <button class = "tablinks" onclick = "openCity(event, 'London')">London</button>
  <button class = "tablinks" onclick = "openCity(event, 'Paris')">Paris</button>
  <button class = "tablinks" onclick = "openCity(event, 'Tokyo')">Tokyo</button>
</div>

<!-- Tab content -->
<div id = "London" class = "tabcontent">
  <h3>London</h3>
  <p>London is the capital city of England.</p>
</div>

<div id = "Paris" class = "tabcontent">
  <h3>Paris</h3>
  <p>Paris is the capital of France.</p> 
</div>

<div id = "Tokyo" class = "tabcontent">
  <h3>Tokyo</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>

CSS

.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

/* Style the buttons that are used to open the tab content */
.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
}

/* Change background color of buttons on hover */
.tab button:hover {
  background-color: #ddd;
}

/* Create an active/current tablink class */
.tab button.active {
  background-color: #ccc;
}

/* Style the tab content */
.tabcontent {
  display: none;
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
}

JavaScript

function openCity(evt, cityName) {
  // Declare all variables
  var i, tabcontent, tablinks;

  // Get all elements with class = "tabcontent" and hide them
  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }

  // Get all elements with class = "tablinks" and remove the class "active"
  tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }

  // Show the current tab, and add an "active" class to the button that opened the tab
  document.getElementById(cityName).style.display = "block";
  evt.currentTarget.className += " active";
}

Используйте атрибуты элемента(ов). У вас есть доступ ко всему элементу как this внутри функции обработчика событий

charlietfl 09.04.2019 00:12
Поведение ключевого слова "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
1
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

w3schools — очень хороший источник плохой практики, потому что они часто используют множество ярлыков, пытаясь выделить один небольшой пример, который они приводят.

На практике вы могли бы решить эту ситуацию, используя атрибут data-. Если вы не узнаете некоторые из вызовов, обратитесь к некоторым из этих статей:

// Wrap our code in an IIFE in order to avoid polluting the global namespace
// and to facilitate faster garbage collection
(function(){

// Preload queries for later use
const tabs = document.querySelectorAll('.tablinks');
const content = document.querySelectorAll('.tabcontent');

// iterate tab to create content interaction
tabs.forEach(f => // f will be the tab element in this loop

  // Assign click event to each tab
  f.addEventListener('click',function(){

    // Locate any previously marked active tab element
    const prevActive = document.querySelector('.tablinks.active');

    // If a previously marked element exists set its classname to default
    if (prevActive) prevActive.className = 'tablinks';

    // Assign the currently clicked tab element the active class
    f.className = 'tablinks active';

    // Iterate through the content to look for the data-attribute we used earlier
    content.forEach(c => { // c will be the content element in this loop

      // if the id of the element matches the data attribute from the tab then show the content
      c.style.display = c.id == f.getAttribute("data-city") ? "block" : "none" ;
    })
  })
);

})();
.tab {
  overflow: hidden;
  border: 1px solid #ccc;
  background-color: #f1f1f1;
}

/* Style the buttons that are used to open the tab content */
.tab button {
  background-color: inherit;
  float: left;
  border: none;
  outline: none;
  cursor: pointer;
  padding: 14px 16px;
  transition: 0.3s;
}

/* Change background color of buttons on hover */
.tab button:hover {
  background-color: #ddd;
}

/* Create an active/current tablink class */
.tab button.active {
  background-color: #ccc;
}

/* Style the tab content */
.tabcontent {
  display: none;
  padding: 6px 12px;
  border: 1px solid #ccc;
  border-top: none;
}
<div class = "tab">
  <button class = "tablinks" data-city = "London">London</button>
  <button class = "tablinks" data-city = "Paris">Paris</button>
  <button class = "tablinks" data-city = "Tokyo">Tokyo</button>
</div>

<!-- Tab content -->
<div id = "London" class = "tabcontent">
  <h3>London</h3>
  <p>London is the capital city of England.</p>
</div>

<div id = "Paris" class = "tabcontent">
  <h3>Paris</h3>
  <p>Paris is the capital of France.</p> 
</div>

<div id = "Tokyo" class = "tabcontent">
  <h3>Tokyo</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>
    <button id = "London" class = "tablinks">London</button>


    var btns = document.querySelectorAll('.tab button')

        btns.forEach((btn)=>{
            btn.addEventListener('click', (event)=>{
               openCity(event, btn.id, btn)
            })
        })

Дайте каждой кнопке идентификатор с названием города, затем передайте идентификатор в функцию openCity.

Вы также можете передать btn своей функции openCity.

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