我在思考优化此代码块的新方法时遇到了一些麻烦。现在,它看起来过于重复和冗长。我可以将函数与EventListener分开编写,但只会编写更多行代码,甚至更长。
let modalIntro = document.getElementById('modal-intro');
let buttonIntro = document.getElementById('button-intro');
let close = document.getElementsByClassName('close')[0];
buttonIntro.addEventListener ('click', function(){
modalIntro.classList.remove("out");
modalIntro.classList.add("in");
});
close.addEventListener('click', function (){
modalIntro.classList.add("out");
});
let modalWork = document.getElementById('modal-work');
let buttonWork = document.getElementById('button-work');
let close1 = document.getElementsByClassName('close')[1];
buttonWork.addEventListener ('click', function(){
modalWork.classList.remove("out");
modalWork.classList.add("in");
});
close1.addEventListener('click', function (){
modalWork.classList.add("out");
});
let modalAbout = document.getElementById('modal-about');
let buttonAbout = document.getElementById('button-about');
let close2 = document.getElementsByClassName('close')[2];
buttonAbout.addEventListener ('click', function(){
modalAbout.classList.remove("out");
modalAbout.classList.add("in");
});
close2.addEventListener('click', function (){
modalAbout.classList.add("out");
});
let modalContact = document.getElementById('modal-contact');
let buttonContact = document.getElementById('button-contact');
let close3 = document.getElementsByClassName('close')[3];
buttonContact.addEventListener ('click', function(){
modalContact.classList.remove("out");
modalContact.classList.add("in");
});
close3.addEventListener('click', function (){
modalContact.classList.add("out");
});
任何帮助将不胜感激。
答案 0 :(得分:1)
看到您有一个通用的命名模式,并假设关闭按钮是每个模式的子代,则可以执行以下操作:
注意,我在关闭按钮上添加了modal.classList.remove('in');
function bindModals(modals) {
modals.forEach(name => {
let modal = document.getElementById(`modal-${name}`)
let button = document.getElementById(`button-${name}`)
let close = modal.querySelector('.close');
button.addEventListener ('click', function(){
modal.classList.remove('out');
modal.classList.add('in');
});
close.addEventListener('click', function (){
modal.classList.remove('in');
modal.classList.add('out');
});
});
}
bindModals(['intro', 'work', 'about', 'contact'])
.out {
display: none;
}
.in {
display: block;
border: 1px solid red;
height: 200px;
width: 400px;
}
<section>
<button id="button-intro">Intro</button>
<button id="button-work">Work</button>
<button id="button-about">About</button>
<button id="button-contact">Contact</button>
</section>
<section id="modal-intro" class="out">
<button class="close">Close</button>
<p>Intro Modal</p>
</section>
<section id="modal-work" class="out">
<button class="close">Close</button>
<p>Work Modal</p>
</section>
<section id="modal-about" class="out">
<button class="close">Close</button>
<p>About Modal</p>
</section>
<section id="modal-contact" class="out">
<button class="close">Close</button>
<p>Contact Modal</p>
</section>
答案 1 :(得分:0)
最简单的方法就是简单地创建一个函数:
function MakeModal(modalId, buttonId, closeId)
let modal = document.getElementById(modalId);
let button = document.getElementById(buttonId);
let close = document.getElementsById(closeId);
button.addEventListener ('click', function(){
modal.classList.remove("out");
modal.classList.add("in");
});
close.addEventListener('click', function (){
modal.classList.add("out");
});
}
然后您可以调用:
MakeModal('modal-intro', 'button-into', 'close-intro');
MakeModal('modal-about', 'button-about', 'close-about');
MakeModal('modal-contact', 'button-contact', 'close-contact');
那只是编程基础:DRY。
请注意,您需要在关闭按钮而不是类中添加ID(或者您可以将其重写为let close = modal.find('.close');
或其他内容,在这种情况下,您可以摆脱第三个参数closeId
)。而且,如果您严格遵守此处使用的命名约定,甚至可以简化多个MakeModal(...)
调用:
['intro', 'about', 'contact'].forEach(function(e) {
MakeModal('modal-' + e, 'button-' + e, 'close-' + e);
});
或者,如果您摆脱了第三个参数并使用了.find(...)
建议:
['intro', 'about', 'contact'].forEach(function(e) {
MakeModal('modal-' + e, 'button-' + e);
});
无论如何我都不是jQuery专家,但如果我没记错的话
modal.classList.remove("out");
modal.classList.add("in");
可以写为:
modal.classList.switchClass("out", "in");
答案 2 :(得分:0)
您可以使用函数获取元素ID以使其更短:
function getElem(el) {
return document.getElementById(el);
}
现在删除以下所有代码:
let modalIntro = document.getElementById('modal-intro');
let buttonIntro = document.getElementById('button-intro');
let modalWork = document.getElementById('modal-work');
let buttonWork = document.getElementById('button-work');
let modalContact = document.getElementById('modal-contact');
let buttonContact = document.getElementById('button-contact');
–并用getElem('elem-id')
替换变量,例如下面的
getElem('modal-intro').classList.remove("out");
getElem('modal-intro').classList.add("in");
类似地,您可以使通用函数按类获取Element并添加事件侦听器。
答案 3 :(得分:0)
如果没有任何HTML,我不确定这是否会非常准确,但是我可以尝试一下。
我看到每个模式的行为方式都相同...我将向每个按钮添加一个属性,以标识它激活了哪个模式,并添加一个类,以便我们可以引用所有这些模式:
<input type="button" value="intro" class="modalButton" id="button-intro" data-activates="modal-intro">
<input type="button" value="work" class="modalButton" id="button-work" data-activates="modal-work">
<input type="button" value="about" class="modalButton" id="button-about" data-activates="modal-about">
<input type="button" value="contact" class="modalButton" id="button-contact" data-activates="modal-contact">
现在,我们可以使用以下代码行来引用和操作:
document.getElementsByClassName("modalButton").forEach(function(btn) {
btn.addEventListener ('click', function() {
var modal = document.getElementById(btn.getAttribute("data-activates"));
modal.classList.remove("out");
modal.classList.add("in");
});
});
假设模态中的按钮是这样的:
<!-- Example of a modal with a close button -->
<div id="modal-intro" class="modal out">
<input type="button" class="close" value="close">
<!-- content -->
</div>
我们可以通过在DOM树中向上移动来进入模态:
document.getElementsByClassName("close").forEach(function(closeBtn) {
closeBtn.addEventListener ('click', function(){
// In this case the modal is the button's parent
closeBtn.parentElement.classList().remove("in");
closeBtn.parentElement.classList().add("out");
// P.S I also suppose you want to remove the "in" class
});
});
奇怪的是,如果按钮位于模式内部更深的位置,则只需调用'parentElement'属性,直到获得它为止。
答案 4 :(得分:0)
这是使用具有相同结构乘以三的事实的另一种方法。 如果我使用jQuery,这会短很多,但由于您似乎并未使用它,所以我将其保留为香草:
document.querySelectorAll("nav a").forEach(a => a.addEventListener("click", function(e) {
e.preventDefault(); // don't navigate to href
// hide all modals, i.e. remove the one potentially still open
document.querySelectorAll("#modals > div").forEach(modal => modal.classList.remove("in"));
// finally, show modal
document.getElementById(this.dataset.modal).classList.add("in");
}));
document.querySelectorAll("#modals > div").forEach(modal =>
// for each modal, grab its close button
modal.querySelector(".close").addEventListener("click", function(e) {
e.preventDefault(); // don't navigate to href
modal.classList.remove("in"); // and hide the modal
})
);
#modals>div {
position: fixed;
width: 50%;
left: 25%;
box-sizing: border-box;
border: 1px solid black;
padding: 0.5em;
top: -300px;
transition: .5s
}
#modals .close {
float: right
}
.in {
top: 50px !important;
}
<nav>
<a data-modal="intro" href="">Intro</a>
<a data-modal="work" href="">Work</a>
<a data-modal="about" href="">About</a>
</nav>
<div id="modals">
<div id="intro"><a href="" class="close">X</a>
<p>Intro modal</p>
</div>
<div id="work"><a href="" class="close">X</a>
<p>Work modal</p>
</div>
<div id="about"><a href="" class="close">X</a>
<p>About modal</p>
</div>
</div>
通过通过菜单链接的data-modal
将代码指向模式,我不再需要使用任何特定于元素的代码,从而实现了理想的可重用代码。