Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Eventlistener不会注册单击_Javascript_Settimeout_Addeventlistener - Fatal编程技术网

Javascript Eventlistener不会注册单击

Javascript Eventlistener不会注册单击,javascript,settimeout,addeventlistener,Javascript,Settimeout,Addeventlistener,我遇到了一件很奇怪的事情,我真的不知道该怎么解决 我在大学里做一个项目,我们的任务是制作一个游戏来测试用户的智力。每个游戏都有自己的模块 我现在正在处理的一个基本上是在使用window.setTimeout将一组标志翻转过来之前显示一秒钟。这工作绝对不错,过渡和一切看起来都很顺利。在我设置电路板(显示标志)的过程中,我还为每个标志提供了一个eventListener,它会侦听单击,从而在其Y轴上翻转标志 不过,任务的最后一部分是创建并显示标志列表。我正在使用一个名为set\u list的单独函数

我遇到了一件很奇怪的事情,我真的不知道该怎么解决

我在大学里做一个项目,我们的任务是制作一个游戏来测试用户的智力。每个游戏都有自己的模块

我现在正在处理的一个基本上是在使用
window.setTimeout
将一组标志翻转过来之前显示一秒钟。这工作绝对不错,过渡和一切看起来都很顺利。在我设置电路板(显示标志)的过程中,我还为每个标志提供了一个
eventListener
,它会侦听
单击
,从而在其Y轴上翻转标志

不过,任务的最后一部分是创建并显示标志列表。我正在使用一个名为
set\u list
的单独函数,它只是将一个有序列表添加到gameboard的innerHTML中

但每当我添加列表时,eventListener就会中断(即,当单击翻转的标志时,它不会激活)

当点击一个按钮时,游戏本身就开始了。因此,基本上有一个按钮具有自己的
eventListener
,需要按下该按钮,gameboard才能启动:

document.getElementById('start').addEventListener('click', function(){
    setup_cards();
    create_cards();
    set_list(); 
});
这两个功能似乎把事情搞得一团糟:

function create_cards() {
    for (i = 0; i < cards_arr.length; i++) {
        if (i == 3 || i == 6) {
            flag_divs += "</div><div class='row flag-buffer'>"
        }
        if (flags[cards_arr[i]].name == 'Colombia' || flags[cards_arr[i]].name == 'Chile' || flags[cards_arr[i]].name == 'Japan') {
            flag_divs += "<div id='flag_" + i + "' class='flip-container col-xs-2 col-xs-offset-1'>" +
                        "<div class='front'>" +
                        "</div>" +
                        "<div class='back'>" +
                        specialflag(flags[cards_arr[i]].name) +
                        "</div>" +
                        "</div>";
        } else {
            flag_divs += "<div id='flag_" + i + "' class='flip-container col-xs-2 col-xs-offset-1'>" +
                            "<div class='front'>" +
                            "</div>" +
                            "<div class='back'>" +
                            "<div id='" + flags[cards_arr[i]].class + "' class='flag'> </div>" +
                            "</div>" +
                            "</div>";
        }
    }
    board.innerHTML = '<h3 class="text-center"> Memorize the flags </h3><div class="container-fluid"> <div class="row">' + flag_divs + '</div></div>';
    var myNodeList = document.getElementsByClassName('flip-container');



    for (var iterator = 0; iterator < myNodeList.length; iterator++) {

        var el = document.getElementById(myNodeList["flag_" + iterator].id);
        el.id = iterator;
        //console.log(el); 
        el.style.transform = 'rotateY(180deg)';
        el.classList.add('flipper');
        el.addEventListener('click', function () {
            animate(this);
        });
        var animate = function (sender) {
            sender.style.transform = "rotateY(0deg)";
            console.log("animating");
            sender.style.transform = "rotateY(180deg)";
            sender.classList.add('flipper');

        };
    }
    window.setTimeout(() => {
        for (var iterator = 0; iterator < myNodeList.length; iterator++) {
            var el = document.getElementById(myNodeList[iterator].id);
            el.id = iterator;
            el.style.transform = 'rotateY(0deg)';
            console.log("I'm done!");
        }
    }, 1000);
}

function set_list() {
    console.log("I'm in");
    var flag_list = "<ol>";
    for (var i = 0; i < cards_arr.length; i++) {
        flag_list += "<li>" + flags[cards_arr[i]].name + "</li>";
    }
    flag_list += "</ol>";
    board.innerHTML += flag_list;
    console.log(board.innerHTML);
}
函数创建卡片(){
对于(i=0;i{
for(var iterator=0;iterator”+标志[卡片阵列[i]]。名称+””;
}
标志_列表+=“”;
board.innerHTML+=标志列表;
log(board.innerHTML);
}

能否在getElementById()调用后添加一些空测试,例如:

if ( el == null ) { 
    // Error handler.
} else {
    // Your existing code.
}
你的问题是:

board.innerHTML += flag_list;
这样做的目的是要求将
board
元素的内容作为HTML字符串,在该字符串的末尾添加一些HTML,然后删除
board
的内容,并用解析的字符串替换它们。新创建的开始按钮节点没有附加任何事件侦听器,因此不会发生任何事情

由于许多原因,使用
element.innerHTML+=some_html
是一个坏主意,这就是其中之一。最好尽可能避免使用
.innerHTML

  • 将尽可能多的游戏文本/HTML(在本例中,特别是开始按钮,以及说明文本)放入原始静态HTML,而不是使用JS添加
  • 要操纵现有HTML,请使用DOM节点操纵操作,如
    document.createElement
    element.appendChild
    ,它们根据DOM树而不是文本工作
  • .innerHTML
    相对安全的用法是设置新创建元素的初始内容
也就是说,对现有代码最简单的修复方法是更改事情发生的顺序,以便在上次使用
innerHTML
后执行
addEventListener
。也就是说,将事件侦听器代码从
create_cards
中取出,并将其放在
set_list()
之后将调用的位置(根据您的喜好,是否在函数中)


另外,通过字符串连接构建HTML,就像您正在做的那样

... + "<div id='" + flags[cards_arr[i]].class + "' class='flag'> </div>" + ...
…+" " + ...
这是非常糟糕的做法,因为——不是在本例中,而是在其他情况下——它会导致XSS安全漏洞。如果插入的字符串包含引用字符,则会发生什么情况。


使用DOM方法(
createTextNode
setAttribute
或属性等)构造节点是避免XSS风险的一个好方法,因为您不需要确保引用或清除文本。

检查您的浏览器控制台是否有任何错误?@NewToJS建议不错,但是是的。我在当地做过几次。但是我不确定小提琴的错误。试着用这个小提琴。是的,很抱歉。我已经设置好了,但一定是挂错了小提琴。容易出错…:/不考虑XSS和安全问题,因为这实际上不在任务范围内,我如何着手解决这个问题?更具体地说,在代码中,