Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/378.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/77.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 addEventListener在innerHTML之后不工作_Javascript_Html - Fatal编程技术网

Javascript addEventListener在innerHTML之后不工作

Javascript addEventListener在innerHTML之后不工作,javascript,html,Javascript,Html,我在空闲时间写一个简单的文本游戏。这叫TARDIS flight(Who医生!),我正在处理主菜单。 因此,在设置主菜单的innerHTML之后,我使用一个函数,addMainMenuListeners,添加所有带有addEventListener的事件侦听器。 一切正常,直到我从其中一个子菜单返回主菜单为止。然后,我发现按钮不再工作。在设置innerHTML之后,我正在调用addMainMenuListeners,但即使我这样做了,我在控制台中这样做了,并且我检查了,也没有任何事件。

我在空闲时间写一个简单的文本游戏。这叫TARDIS flight(Who医生!),我正在处理主菜单。

因此,在设置主菜单的
innerHTML
之后,我使用一个函数,
addMainMenuListeners
,添加所有带有
addEventListener
的事件侦听器。
一切正常,直到我从其中一个子菜单返回主菜单为止。然后,我发现按钮不再工作。
在设置
innerHTML
之后,我正在调用
addMainMenuListeners
,但即使我这样做了,我在控制台中这样做了,并且我检查了,也没有任何事件。

代码:
在我的主javascript文件中:

function addMainMenuListeners()
{
    if($("start")) $("start").addEventListener("click", startGame);
    if($("instructions")) $("instructions").addEventListener("click", instructions);
    if($("settings")) $("settings").addEventListener("click", settings);
    if($("back")) $("back").addEventListener("click", resetMainMenu);
    if($("volume")) $("volume").addEventListener("change", function(){saveAndChangeVolume($("volume").value);});
}

function instructions()
{
    $("mainmenu").innerHTML = "<h1>Instructions</h1><p>Fly your TARDIS through the time vortex using the console.  Make sure that you use the correct materialization codes.  Try to keep the time-space coordinates close to the values of the ones given.  AND DON'T CREATE PARADOXES, WHATEVER YOU DO!</p><button id='back'>Back</button>";
    addMainMenuListeners();
    return true;
}

function settings()
{
    $("mainmenu").innerHTML = "<h1>Volume</h1><span>1</span><input type='range' id='volume' min='1' max='100' /><span>100</span><br><button id='back'>Back</button>";
    addMainMenuListeners();
    loadVolume();
    return true;
}

function resetMainMenu()
{
    $("mainmenu").innerHTML = "<h1>TARDIS Flight</h1><button id='start'>Start!</button><button id='instructions'>Instructions</button><button id='settings'>Settings</button>";
    addMainMenuListeners();
    return true;
}
函数addMainMenuListeners()
{
如果($(“开始”)$(“开始”).addEventListener(“单击”,开始名称);
如果($(“说明”)$(“说明”)。添加了EventListener(“单击”,说明);
如果($(“设置”)$(“设置”).addEventListener(“单击”,设置);
如果($(“返回”)$(“返回”).addEventListener(“单击”,重置主菜单);
if($((“卷”)$(“卷”).addEventListener(“更改”,function(){saveAndChangeVolume($(“卷”).value);});
}
功能指令()
{
$(“mainmenu”).innerHTML=“Instructions使用控制台让您的TARDIS穿越时间漩涡。确保使用正确的物化代码。尽量使时空坐标接近给定的值。无论您做什么,都不要制造矛盾!

返回”; addMainMenuListeners(); 返回true; } 函数设置() { $(“主菜单”).innerHTML=“Volume1100
返回”; addMainMenuListeners(); loadVolume(); 返回true; } 函数resetMainMenu() { $(“主菜单”).innerHTML=“TARDIS FlightStart!指令设置”; addMainMenuListeners(); 返回true; }


在我的HTML文件中:

<div id="mainmenu">
<h1>TARDIS Flight</h1>
<button id="start">Start!</button>
<button id="instructions">Instructions</button>
<button id="settings">Settings</button>
</div>

塔迪斯飞行
开始
说明书
设置
如果你需要任何澄清,尽管问。

编辑:显然,没有人明白我的意思。在执行
innerHTML
之后,我正在读取事件侦听器,您可以从代码中看到这一点。我根本看不到添加的事件,函数正在启动,但没有添加事件。

另外,我正在使用一个自定义的
$
函数,只是一个
返回文档.getElementById(id)
类函数。

检查您的
$()
是否使用任何缓存。如果缓存对元素的旧引用,则当设置
innerHTML
时,
$(“id”)
将返回对无效引用的引用


[edit]这些引用更有可能有效,即使它们在HTML DOM中不再可见。因此,修改分离的元素是可行的,但没有任何好处,因为它们是从DOM分离的。

禁用
$
函数上的缓存是可行的。它引用的是一个被破坏的HTML元素,这就是它不起作用的原因。另外,
setTimeout
s在
innerHTML
没有及时执行的情况下有助于提高可靠性。

抓住了主要问题:您的自定义$函数(用来替换document.getElementById)使用了缓存机制

经过一些测试(出于个人好奇),结果表明,只要您对某个元素有一些引用,即使在
elm.parentNode.removeChild
或完整的
elm.parentNode.innerHTML
重写(至少在FF中)之后,该元素仍然是可访问的

换句话说:事件每次都被添加到错误的/旧的/以前的元素,而不是新的元素。否则也会出现错误,即元素不存在,因此没有
addEventListener
方法

请参阅此原始测试小提琴以获取证据:


我玩弄了一个$函数(因为你还没有发布你的函数),并给它一个“刷新”标志,以配合可选的缓存机制:

var $=function(/*cache_enabled*/c){  // getElementById with optional caching & refresh
   return c ?( c={}, function(s,r){return (!r && c[s]) || (c[s]=document.getElementById(s));} 
           ):( function(s){return document.getElementById(s);} );
}(true); // or nothing or 0 etc to disable the cache
注意:动态创建的函数速度较慢(出于某些原因),因此它有两个函数,以便浏览器可以优化运行它们(另一个应该由垃圾收集器清除)

要请求刷新,只需添加一个计算结果为true的标志作为第二个参数,如:
$('elm_id',1)

然后,我稍微修改了
addMainMenuListeners
函数,首先测试是否存在新的getElementById,然后通过新更新的缓存引用添加eventListener(因此,基本上我没有改变例程流中的任何内容)

格式化以强调更改的内容及其工作方式

最后,将上述2个函数和其他函数/html放入这个提琴中,得到了一个工作结果:
注意:我必须替换一个伪函数
startGame
,否则会出现致命错误。缺少的音量功能并不重要

我想指出的是,这不是真正的方式去与您的界面,将有很多工作,你可以节省自己和浏览器。您可能希望查看div(包含html的子部分)并切换它们,以便只有一个可见。像标签。(谷歌查询提示)

Sukima仍然值得称赞(“这一点的力量很强大”),但我觉得分享你的问题的正确解释(有证据)是一个好主意,不要浪费已经完成的工作(出于好奇)


希望这有帮助

我制作了自己的
$
函数。它只是一个
返回文档。getElementById(id)
函数。对不起,我没有澄清。伙计们,OP没有使用jQuery。它看起来不像jQuery。OP在上面确认它不是jQuery。如果是jQuery,它根本就不起作用。@Atutouato如果我是你,我会有多个div,其中包含我的TARDIS飞行的“阶段”,并在单击时显示/隐藏这些div,而不是使用
。innerHTML
,它正在破坏你的事件
function addMainMenuListeners(){
   $(   'start'    , 1) && $(   'start'    ).addEventListener('click', startGame);
   $('instructions', 1) && $('instructions').addEventListener('click', instructions);
   $(  'settings'  , 1) && $(  'settings'  ).addEventListener('click', settings);
   $(   'back'     , 1) && $(    'back'    ).addEventListener('click', resetMainMenu);
   $(  'volume'    , 1) && $(   'volume'   ).addEventListener('change', function(){ 
                                               saveAndChangeVolume($('volume').value); 
                                             });
}