为了账号安全,请及时绑定邮箱和手机立即绑定

单击事件侦听器调用的函数在不单击的情况下被调用,但仅在第二次运行时调用

单击事件侦听器调用的函数在不单击的情况下被调用,但仅在第二次运行时调用

MMTTMM 2022-06-09 19:46:05
这是一个谜题:我正在尝试创建一个简单的选择你自己的路径游戏,它从本地 JSON 文件中获取内容。运行时,它将每个场景(JSON 文件中的“Section”)分解为多个段落,并将第一个段落添加到 DOM,并在其周围的 div 上附加一个事件侦听器。每次用户单击“容器”时,都会从该部分添加另一个段落,直到显示所有段落。之后,如果用户再次单击“容器”,则会添加三个选项,每个选项都附加了自己的事件侦听器。单击这些选项之一时,场景(或“部分”)将更改为选定的选项。HTML“容器”被清空,该过程通过添加新场景(部分)的第一段重新开始。问题是它对第一部分和选项工作正常,但是在用户单击选项后,它会加载新场景的两段而不是一个。它应该加载一个段落并等待点击事件,但它实际上加载了一秒钟。第二段是通过 readyToUpdate 函数加载的,该函数只能由事件侦听器调用(尚未触发)。{      "Section_1": {        "Content": "Dark corner paragraph one<>Dark corner paragraph two<>Dark corner paragraph three",        "Choices": [            "Go to the garden<>24",            "Go to the terrace<>95",            "Go to the beach<>145"        ]    },    "Section_24": {        "Content": "Garden paragraph one<>Garden paragraph two<>Garden paragraph three",        "Choices": [            "Go to the dark corner<>1",            "Go to the terrace<>95",            "Go to the beach<>145"        ]    },    "Section_95": {        "Content": "Terrace paragraph one<>Terrace paragraph two<>Terrace paragraph three",        "Choices": [            "Go to the dark corner<>1",            "Go to the garden<>24",            "Go to the beach<>145"        ]    },    "Section_145": {        "Content": "Beach paragraph one<>Beach paragraph two<>Beach paragraph three",        "Choices": [            "Go to the dark corner<>1",            "Go to the garden<>24",            "Go to the terrace<>95"        ]    }}    <div id="container"></div>
查看完整描述

2 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

我相信正在发生的事情是,当您单击一个选项并调用选项单击侦听器时,您正在经历update()并向updateParagraphs()容器添加一个新的单击侦听器。但与此同时,click 事件正在传播到容器,并被您刚刚添加的新容器侦听器捕获。


所以你有两个选择:第一个,正如@wth193 所建议的,是使用 setTimeout() 在下一个滴答声中添加容器监听器。


function updateParagraphs(){

    // ...

    // container.addEventListener('click', readyToUpdate, {once: true});

    setTimeout(function () {

        container.addEventListener('click', readyToUpdate, {once: true});

    });

}

在我看来,一个更干净(更清晰)的解决方案是使用Event.stopPropagation()。


function choiceUpdater(e){

  console.log("Enter choiceUpdater");

  e.stopPropagation();

  // ...

}

这样,click 事件仅由选择元素捕获,而不是由容器捕获。


查看完整回答
反对 回复 2022-06-09
?
慕莱坞森

TA贡献1810条经验 获得超4个赞

function updateParagraphs(){

    ...

    // container.addEventListener('click', readyToUpdate, {once: true});

    setTimeout(function () {

        container.addEventListener('click', readyToUpdate, {once: true});

    });

}

我认为打破调用堆栈的 setTimeout 似乎有效,但我无法解释原因。


查看完整回答
反对 回复 2022-06-09
  • 2 回答
  • 0 关注
  • 159 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号