菜单切换按钮点击无响应问题求助(关联Cookie授权代码)
问题根源与解决方案
我一眼就看出问题所在了——你的Cookie授权代码里的document.body.innerHTML +=操作是罪魁祸首!
为什么会出现这个问题?
当你使用document.body.innerHTML += ...时,浏览器会把当前body的所有内容重新解析一遍:原来的DOM元素(包括你的.toggle-button按钮)会被销毁,然后重新创建新的DOM节点。而你之前通过addEventListener绑定在旧按钮上的点击事件,自然就跟着旧元素一起消失了,新生成的按钮并没有绑定这个事件,所以点击没反应。
至于为什么同意Cookie并刷新后就正常了?因为此时localStorage.getItem("cookieconsent")已经有值了,这段Cookie弹窗的代码不会执行,body的内容没有被重新渲染,原来的按钮和事件绑定都保留着,所以就能正常工作了。而你在jsfiddle里测试时没有这段Cookie代码,自然也不会有这个问题。
几种可行的解决方案
方案1:用DOM API创建弹窗(推荐)
避免使用innerHTML +=,而是通过createElement等方法手动构建弹窗元素,再添加到body中,这样不会破坏原有的DOM结构和事件绑定:
(function () { if (!localStorage.getItem("cookieconsent")) { // 创建弹窗容器 const cookieContainer = document.createElement('div'); cookieContainer.className = 'cookieconsent'; cookieContainer.style.cssText = 'position:fixed;padding:20px;left:0;bottom:0;background-color:#000;color:#FFF;text-align:center;width:100%;z-index:99999;'; // 构建弹窗内容 const textNode = document.createTextNode('This website uses cookies. Read more'); const privacyLink = document.createElement('a'); privacyLink.className = 'privacy-policy__link'; privacyLink.href = '/privacy-policy/index.html'; privacyLink.textContent = 'here'; const consentLink = document.createElement('a'); consentLink.id = 'consent'; consentLink.href = '#'; consentLink.textContent = 'I agree.'; // 组装元素 cookieContainer.appendChild(textNode); cookieContainer.appendChild(document.createTextNode('. ')); cookieContainer.appendChild(privacyLink); cookieContainer.appendChild(document.createTextNode(' ')); cookieContainer.appendChild(consentLink); // 添加到body document.body.appendChild(cookieContainer); // 绑定同意事件 consentLink.onclick = function (e) { e.preventDefault(); cookieContainer.style.display = 'none'; localStorage.setItem("cookieconsent", true); }; } })();
方案2:重新绑定按钮事件
如果你坚持要用innerHTML +=,那就在添加完弹窗后,重新给按钮绑定点击事件:
// 先定义绑定事件的函数 function bindToggleButton() { var toggleButton = document.querySelector(".toggle-button"); toggleButton.addEventListener("click", function() { console.log('open'); }); } // 初始绑定 bindToggleButton(); (function () { if (!localStorage.getItem("cookieconsent")) { document.body.innerHTML += '\ <div class="cookieconsent" style="position:fixed;padding:20px;left:0;bottom:0;background-color:#000;color:#FFF;text-align:center;width:100%;z-index:99999;">\ This website uses cookies. Read more\ <a class="privacy-policy__link" href="/privacy-policy/index.html">here</a>.\ <a id="consent" href="#" >I agree.</a>\ </div>\ '; document.querySelector("#consent").onclick = function (e) { e.preventDefault(); document.querySelector(".cookieconsent").style.display = "none"; localStorage.setItem("cookieconsent", true); }; // 添加完弹窗后重新绑定按钮事件 bindToggleButton(); } })();
方案3:使用事件委托
把点击事件绑定到body或者按钮的父元素上,这样不管按钮怎么被重建,只要匹配选择器,事件就会触发:
// 事件委托:绑定到body上 document.body.addEventListener('click', function(e) { if (e.target.classList.contains('toggle-button')) { console.log('open'); } }); // 你的Cookie授权代码保持不变(不过还是推荐方案1) (function () { if (!localStorage.getItem("cookieconsent")) { document.body.innerHTML += '\ <div class="cookieconsent" style="position:fixed;padding:20px;left:0;bottom:0;background-color:#000;color:#FFF;text-align:center;width:100%;z-index:99999;">\ This website uses cookies. Read more\ <a class="privacy-policy__link" href="/privacy-policy/index.html">here</a>.\ <a id="consent" href="#" >I agree.</a>\ </div>\ '; document.querySelector("#consent").onclick = function (e) { e.preventDefault(); document.querySelector(".cookieconsent").style.display = "none"; localStorage.setItem("cookieconsent", true); }; } })();
总结
最推荐的是方案1,因为它既不会破坏原有DOM,也更符合现代DOM操作的最佳实践。方案3的事件委托也很实用,适合需要动态生成元素的场景。
内容的提问来源于stack exchange,提问作者maja
相关产品推荐
相关产品推荐

