简体   繁体   English

Javascript - 脚本在第二次单击时不起作用

[英]Javascript - Script doesn't work on second click

A basic question by a newbie…新手的一个基本问题……

I always encounter the same problem: I often want an element "A" to show an element "B" on click when "B" is hidden, but to hide it when it is visible.我总是遇到同样的问题:我经常希望元素“A”在“B”隐藏时在单击时显示元素“B”,但在可见时隐藏它。 Here are two different try that doesn't work:以下是两种不起作用的不同尝试:

 let ref = document.getElementsByTagName('sup'); let refContent = document.getElementsByTagName('i'); for(let i = 0; i < ref.length; i++) { ref[i].addEventListener('click', function() { if (refContent[i].style.display == "inline") { refContent[i].style.display = "none"; } else { refContent[i].style.display = "none"; }; }); }

 let ref = document.getElementsByTagName('sup'); let refContent = document.getElementsByTagName('i'); for(let i = 0; i < ref.length; i++) { if (refContent[i].style.display == "") { ref[i].addEventListener('click', function() { refContent[i].style.display = "inline"; }); } else { ref[i].addEventListener('click', function() { refContent[i].style.display = "none"; }); } }

Hi你好

I'm gonna change some variable names to make this easier to talk about.我将更改一些变量名称以使其更易于讨论。 So, you start off strong所以,你开始坚强

    // get all elements with tag sup
    let buttons = document.getElementsByTagName('sup'); 
    //get all elements with tag i
    let showables = document.getElementsByTagName('i');

For each element buttons we want to bind an onclick event listener .对于每个元素buttons ,我们要绑定一个 onclick 事件监听器 showables should respond to those clicks. showables应该响应这些点击。 You write你写


    //for every `button` bind this `event listener`
    buttons[i].addEventListener('click', function() {
        if (showable[i].style.display == "inline") {
            showable[i].style.display = "none";
        } else {
            showable[i].style.display = "none";
        };
    });
}

To make this a little more clear lets take out the function and give it a name为了更清楚一点,让我们取出function并为其命名

let show_hide = function(i) {
        if (showable[i].style.display == "inline") {
            showable[i].style.display = "none";
        } else {
            showable[i].style.display = "none";
        };
});

//for each button, bind show_hide
for(let i = 0; i < buttons.length ; i++) {
    buttons[i].addEventListener('click', show_hide(i))
}

The loop there does exactly what you'd expect;那里的循环完全符合您的期望; it binds show_hide to each button .它将show_hide绑定到每个button What does show_hide do? show_hide是做什么的?

    //if the element is shown, hide it
    if (showable[i].style.display == "inline") {
        showable[i].style.display = "none";
    //if the element is not shown, hide it
    } else {
        showable[i].style.display = "none";
    };

as you can see that no matter what, show_hide hides the element.如您所见,无论如何, show_hide都会隐藏元素。 so a quick change will fix this for you.因此,快速更改将为您解决此问题。

    if (showable[i].style.display == "inline") {
        showable[i].style.display = "none";
    //if not shown, show
    else {
****    showable[i].style.display = "inline";
    };

putting it all together, this should work把它们放在一起,这应该工作

let show_hide = function(i) {
    if (showable[i].style.display == "inline") {
        showable[i].style.display = "none";
    } else {
        showable[i].style.display = "inline";
    };
});

//for each button, bind show_hide
for(let i = 0; i < buttons.length ; i++) {
    buttons[i].addEventListener('click', show_hide(i))
}

If you want my solution to this problem I'd be more than willing to solve this problem in my own way.如果你想要我解决这个问题,我非常愿意以我自己的方式解决这个问题。 Comment and let me know!评论并让我知道! I hope this helps我希望这有帮助

fin

I will interpret what you have written but I do not have the complete code I will fix some issues and update if/when you update your code by adding the markup (html).我将解释您所写的内容,但我没有完整的代码,如果/当您通过添加标记 (html) 更新代码时,我将修复一些问题并更新。

You should put your selected elements in an array because some browsers will not let you loop over a NodeLists.您应该将您选择的元素放在一个数组中,因为某些浏览器不允许您循环遍历 NodeLists。 You can change a NodeLists into an array in a few ways I like the Array.From() way.您可以通过几种我喜欢Array.From()方式的方式将 NodeLists 更改为数组。 After changing the NodeLists into an array you can safely loop over the elements in the array using a forEach() loop.将 NodeList 更改为数组后,您可以使用forEach()循环安全地遍历数组中的元素。

let ref = Array.from(document.getElementsByTagName('sup'));
let refContent = Array.from(document.getElementsByTagName('i'));
ref.forEach(el => {
    el.addEventListener('click', e => {
        e.target.getElementsByTagName('i').style.display = '' // do something
    });
});

This snippet will most likely not work as-is, I'm missing information to finish this script, but perhaps this is a good starting point for further exploration.此代码段很可能无法按原样工作,我缺少完成此脚本的信息,但也许这是进一步探索的良好起点。 (Search for stuff and add 'mdn', to get good results). (搜索东西并添加'mdn',以获得良好的结果)。

In stead of directly changing the style of an element it is better to either add or remove a css class which contains the css properties you desire.与其直接更改元素的样式,不如添加或删除 css class ,其中包含您想要的 css 属性。 You can also toggle a class: element.toggle('className) .您还可以切换class: element.toggle('className)

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

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