我是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-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>
我已经把这个功能拼凑在一起了。
function tabbedWindows(evt, env) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(env).style.display = "block";
evt.currentTarget.className += " active";
}
如果我直接向按钮元素添加onclick属性,如下所示:
onclick="tabbedWindows(event,'content-id')"
效果很好。但是,我试图将关注点分离,并希望动态添加事件。我正在尝试以下操作:
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);
}
由于以下错误而无法使用:main.js:23 Uncaught TypeError:无法读取未定义的属性'currentTarget'。它失败的行是:
evt.currentTarget.className += " active";
我认为原因是当函数尝试附加侦听器时,事件变量已经超出范围。这正是我从研究中得到的东西。我对它的长或短感到困惑,甚至不确定这是否是正确的方法。我想我有一些问题:
感谢您的任何帮助。
[这样声明事件处理程序-tab[i].addEventListener('click', tabbedWindows(event,c), false);
时,将使用tabbedWindows
值调用undefined
。由于evt
为undefined
,因此此语句-evt.currentTarget
-引发错误。
您可以使用部分应用程序获取env
,并返回一个等待事件对象的新函数:
/** get env and return a new function that will be called with the event object **/
const tabbedWindows = env => evt => {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(env).style.display = "block";
evt.currentTarget.className += " active";
}
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(c), false); // call tabbedWindows with c
}
<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>
Hi Jason,
May be you should just try doing this first
*for (let i = 0; i < tab.length; i++) {
tab[i].addEventListener('click', tabbedWindows, false);
}*
and in your tabbedWindows function you can add these lines
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
}