Javascript 如何解决addEventListener的问题:无法读取属性';当前目标';未定义的
我是JavaScript的新手,所以请容忍我 我正在尝试使用JavaScript为特定内容生成选项卡式窗口。HTML如下所示:Javascript 如何解决addEventListener的问题:无法读取属性';当前目标';未定义的,javascript,dom,Javascript,Dom,我是JavaScript的新手,所以请容忍我 我正在尝试使用JavaScript为特定内容生成选项卡式窗口。HTML如下所示: <div class="tab-win" id="tablinks-d38e44"> <button class="tablinks" data-target="tab-bash-d38e44">bash</button> <button class="tablinks" data-target="tab-gui-d
<div class="tab-win" id="tablinks-d38e44">
<button class="tablinks" data-target="tab-bash-d38e44">bash</button>
<button class="tablinks" data-target="tab-gui-d38e44">gui</button>
</div>
<div class="tabcontents" id="tabcontents-d38e44">
<div class="tabcontent" id="tab-bash-d38e44">This is bash.</div>
<div class="tabcontent" id="tab-gui-d38e44">This is plain old GUI...</div>
</div>
<p class="p">Here is another one.</p>
<div class="tab-win" id="tablinks-d38e56">
<button class="tablinks" data-target="tab-bash-d38e56">bash</button>
<button class="tablinks" data-target="tab-gui-d38e56">gui</button>
</div>
<div class="tabcontents" id="tabcontents-d38e56">
<div class="tabcontent" id="tab-bash-d38e56">This is bash #2.</div>
<div class="tabcontent" id="tab-gui-d38e56">This is plain old GUI..#2.</div>
</div>
</div>
它工作得很好。然而,我试图注意关注点的分离,并希望动态添加事件。我正试图通过以下方式实现这一点:
const tab = document.querySelectorAll(".tablinks");
const content = document.querySelectorAll(".tabcontent");
for (let i = 0; i < tab.length; i++) {
let conId = tab[i].getAttribute('data-target');
let conArray = Array.from(content);
let con = conArray.find((c) => c.getAttribute('id') === conId);
let c = con.getAttribute('id');
tab[i].addEventListener('click', tabbedWindows(event,c), false);
}
我认为这是因为当函数尝试附加侦听器时,事件变量已经超出范围。这正是我从研究中得到的。长话短说,我被难住了,甚至不确定这是否是正确的方法。我想我有一些问题:
非常感谢您的帮助。当您像这样声明事件处理程序时-
tab[i]。addEventListener('click',tabbedWindows(event,c),false)
,则使用未定义的值调用选项卡窗口
。由于evt
是undefined
此语句-evt.currentTarget
-抛出错误
您需要向事件处理程序传递第二个参数,因为您需要从“数据目标”选项卡获取的内容id。但是,该选项卡是事件的目标,您可以在单击它时获取信息。我已经重构了代码,并删除了冗余
const tabLinks=document.queryselectoral(“.tabLinks”);
const tabContents=document.queryselectoral(“.tabcontent”);
const activateTab=目标=>{
const contentId=target.getAttribute('data-target');
//使用class=“tabcontent”获取所有元素并隐藏它们,然后显示当前选项卡
tabContents.forEach(tabContent=>{
tabContent.style.display=tabContent.id==contentId?'block':'none';
});
//使用class=“tablinks”获取所有元素并删除类“active”
tabLinks.forEach(tablink=>{
tablink.classList.remove('active');
});
//向打开选项卡的按钮添加“活动”类
target.classList.add('active');
};
常量选项卡窗口=evt=>{
常数目标=evt.currentTarget;
活化乙胺(靶);
}
document.querySelectorAll(“.tablinks”).forEach(制表符=>{
tab.addEventListener('click',tabbedWindows,false);
});
activateTab(tabLinks[0])代码>
猛击
桂
这是bash。
这是一个普通的老GUI。。。
这里是另一个
猛击
桂
这是bash#2。
这是一个朴素的老古董。
当您像这样声明事件处理程序时-选项卡[i]。addEventListener('click',tabbedWindows(event,c),false)
,则使用未定义的值调用选项卡窗口
。由于evt
是undefined
此语句-evt.currentTarget
-抛出错误
您需要向事件处理程序传递第二个参数,因为您需要从“数据目标”选项卡获取的内容id。但是,该选项卡是事件的目标,您可以在单击它时获取信息。我已经重构了代码,并删除了冗余
const tabLinks=document.queryselectoral(“.tabLinks”);
const tabContents=document.queryselectoral(“.tabcontent”);
const activateTab=目标=>{
const contentId=target.getAttribute('data-target');
//使用class=“tabcontent”获取所有元素并隐藏它们,然后显示当前选项卡
tabContents.forEach(tabContent=>{
tabContent.style.display=tabContent.id==contentId?'block':'none';
});
//使用class=“tablinks”获取所有元素并删除类“active”
tabLinks.forEach(tablink=>{
tablink.classList.remove('active');
});
//向打开选项卡的按钮添加“活动”类
target.classList.add('active');
};
常量选项卡窗口=evt=>{
常数目标=evt.currentTarget;
活化乙胺(靶);
}
document.querySelectorAll(“.tablinks”).forEach(制表符=>{
tab.addEventListener('click',tabbedWindows,false);
});
activateTab(tabLinks[0])代码>
猛击
桂
这是bash。
这是一个普通的老GUI。。。
这里是另一个
猛击
桂
这是bash#2。
这是一个朴素的老古董。
也许您应该先尝试一下:
for (let i = 0; i < tab.length; i++) {
tab[i].addEventListener('click', tabbedWindows, false);
}
也许你应该先尝试一下:
for (let i = 0; i < tab.length; i++) {
tab[i].addEventListener('click', tabbedWindows, false);
}
您需要使用tab[i].addEventListener('click',(event)=>tabbedWindows(event,c),false)代码>-传递函数(带有事件参数)而不是函数calli的结果我喜欢使用data-attrib将稍后需要的信息附加到元素,这样就可以从事件处理程序的event.target.dataset.prop
@Bergi Sheesh轻松访问它!我想这只是一个关注细节的问题。我想我还得学。谢谢@dandavis使用event.currentTarget.dataset.prop
(或this.dataset.prop
)仅供参考:永远不要使用。尤其是因为您似乎知道.queryselectoral()
。您需要使用选项卡[i]。addEventListener('click',(event)=>选项卡窗口(event,c),false)代码>-传递函数(带有事件参数)而不是函数calli的结果我喜欢使用data-attrib将稍后需要的信息附加到元素,这样就可以从事件处理程序的event.target.dataset.prop
@Bergi Sheesh轻松访问它!我想这只是一个关注细节的问题。我想我还得学。谢谢@dandavis使用event.currentTarget.dataset.prop
(或this.dataset.prop
)仅供参考:永远不要使用。尤其是因为您似乎知道.querySelectorAll()
。它看起来更像cu
evt.currentTarget.className += " active";
for (let i = 0; i < tab.length; i++) {
tab[i].addEventListener('click', tabbedWindows, false);
}
function tabbedWindows(event) {
let conId = event.currentTarget.getAttribute('data-target');
let conArray = Array.from(content);
let con = conArray.find((c) => c.getAttribute('id') === conId);
let c = con.getAttribute('id');
// and then rest of your code goes here
}