简体   繁体   English

如何避免将内联 JavaScript 用于可点击的选项卡?

[英]How can I avoid using inline JavaScript for clickable tabs?

I need to create tabs that reveal content when clicked.我需要创建在单击时显示内容的选项卡。 I have found some code that provides the functionality I need from this W3Schools Tutorial , although I want to avoid using the inline JavaScript to call the openCity() function.我从这个W3Schools 教程中找到了一些提供我需要的功能的代码,尽管我想避免使用内联 JavaScript 来调用 openCity() 函数。 In the original code, each tab button was defined like so:在原始代码中,每个选项卡按钮的定义如下:

<button class="tablinks" onclick="openCity(event, 'London')">London</button>

This works fine, but I would much rather avoid using JavaScript like this in any code if I can.这很好用,但如果可以的话,我宁愿避免在任何代码中使用这样的 JavaScript。 It looks like the event.currentTarget property is one of the most important parts here for adding the .active class to the tabs when clicked, although I was wondering if there was another way to carry out the same process.看起来event.currentTarget属性是在单击时将.active类添加到选项卡的最重要部分之一,尽管我想知道是否有另一种方法来执行相同的过程。

I have tried several different solutions but still have not been able to find the best one.我尝试了几种不同的解决方案,但仍然无法找到最好的解决方案。 In previous attempts I had a few errors such as an Uncaught TypeError for not being able to access the property of an undefined value.在之前的尝试中,我遇到了一些错误,例如无法访问未定义值的属性的 Uncaught TypeError。 Now, no errors arise, but the page is just stuck on the first tab and the others do not work.现在,没有出现错误,但页面只是停留在第一个选项卡上,其他选项卡不起作用。

In the latest attempt, I tried looping through each tab and added an event listener to call the function on them individually, but am still new to using JavaScript and am unsure on what else to do.在最近的尝试中,我尝试遍历每个选项卡并添加一个事件侦听器来单独调用它们的函数,但我仍然不熟悉使用 JavaScript,并且不确定还能做什么。 Please excuse any silly mistakes!请原谅任何愚蠢的错误!

Please find the code below (HTML, CSS, and JavaScript).请在下面找到代码(HTML、CSS 和 JavaScript)。

<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        body {
            font-family: Arial;
        }
        .tab {
            overflow: hidden;
            border: 1px solid #ccc;
            background-color: #f1f1f1;
        }
        .tab button {
            background-color: inherit;
            float: left;
            border: none;
            outline: none;
            cursor: pointer;
            padding: 14px 16px;
            transition: 0.3s;
            font-size: 17px;
        }
        .tab button:hover {
            background-color: #ddd;
        }
        .tab button.active {
            background-color: #ccc;
        }
        .tabcontent {
            display: none;
            padding: 6px 12px;
            border: 1px solid #ccc;
            border-top: none;
        }
    </style>
</head>

<body>
    <div class="tab">
    <button class="tablinks">London</button>
    <button class="tablinks">Paris</button>
    <button class="tablinks">Tokyo</button>
</div>

<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>

<script>
    var i, tabcontent, tablinks;

    tablinks = document.getElementsByClassName("tablinks");
    for (var i = 0; i < tablinks.length; i++) {
        var name = tablinks[i].innerHTML;
        console.log(name);
        tablinks[i].addEventListener('click', openCity(name));
    }
    function openCity(cityName) {
        tabcontent = document.getElementsByClassName("tabcontent");
        for (i = 0; i < tabcontent.length; i++) {
            tabcontent[i].style.display = "none";
        }
        for (i = 0; i < tablinks.length; i++) {
            tablinks[i].className = tablinks[i].className.replace(" active", "");
        }
        document.getElementById(cityName).style.display = "block";
        this.className += ' active';
        // event.currentTarget.className += " active";
    }
</body>

I had other ideas without using data attributes, but i think it's a correct way.我有其他想法而不使用数据属性,但我认为这是一种正确的方法。
Probably code can looks like that:可能代码看起来像这样:

 let handleClick = e => { Array.from(document.querySelectorAll(".active"), e => e.classList.remove("active")); // remove `active` class from every elements which contains him. e.target.classList.add("active"); document.querySelector(`div.tabcontent[data-id*="${e.target.dataset.id}"]`).classList.add("active"); }; Array.from(document.getElementsByClassName("tablinks"), btn => btn.addEventListener('click', handleClick, false));
 .tab { overflow: hidden; border: 1px solid #ccc; background-color: #f1f1f1; } .tab button { background-color: inherit; float: left; border: none; outline: none; cursor: pointer; padding: 14px 16px; transition: 0.3s; font-size: 17px; } .tab button:hover { background-color: #ddd; } .tab button.active { background-color: #ccc; } .tabcontent { display: none; padding: 6px 12px; border: 1px solid #ccc; border-top: none; } .active { display: block; }
 <div class="tab"> <button class="tablinks" data-id="1">London</button> <button class="tablinks" data-id="2">Paris</button> <button class="tablinks" data-id="3">Tokyo</button> </div> <div data-id="1" class="tabcontent"> <h3>London</h3> <p>London is the capital city of England.</p> </div> <div data-id="2" class="tabcontent"> <h3>Paris</h3> <p>Paris is the capital of France.</p> </div> <div data-id="3" class="tabcontent"> <h3>Tokyo</h3> <p>Tokyo is the capital of Japan.</p> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM