从 IIFE 内部调用 IIFE 外部的代码
Call code outside of IIFE from within IIFE
我有代码成功调用了 IIFE 中的函数,而该函数又引用了 IIFE 之外的代码,我不知道如何调用。
const msgbox = (function () {
function showMsgBox(msg) {
const modal = document.createElement("div");
modal.classList.add("modal");
modal.innerHTML = `<div class="modal-content"><p>${msg}</p></div>`;
document.body.appendChild(modal);
modal.style.display = "block";
window.onclick = function (event) {
if (event.target === modal) {
modal.style.display = "none";
}
};
}
return {
showMsgBox: showMsgBox
};
})();
const example = document.getElementById("example");
function changeClass() {
if (example.getAttribute("class") === "classTwo") {
example.classList.remove("classTwo");
example.classList.add("classOne");
} else {
example.classList.add("classTwo");
example.classList.remove("classOne");
}
}
document.querySelectorAll(".change_class").forEach((item) => {
item.addEventListener("click", function (e) {
changeClass();
});
});
document.querySelector(".showmsg").addEventListener("click", function (e) {
msgbox.showMsgBox(
'Call Function outside of IIFE=> <button class="change_class">Change Class</button> (<= this button should have the same functionality as the other button)'
);
});
我尝试将非 IIFE 部分放入其自己的 IIFE 中并为其提供一个单独的命名空间,但这没有用。上面的示例是我的实际问题的简化版本,但这更简洁地封装了我的问题并减少了混淆。是的,我可以使 IIFE 只是一个函数并以这种方式调用它,但我正在努力扩展我的知识。
这是我为此创建的 CodePen 示例的 link:
https://codepen.io/NoahBoddy/pen/PoOVMzK
希望我的解释很清楚。如果没有,我可以提供更多细节。谢谢!
模式中的按钮没有 click
处理程序,因此它什么都不做:
msgbox.showMsgBox(
'Call Function outside of IIFE=> <button class="change_class">Change Class</button> (<= this button should have the same functionality as the other button)'
);
您可以将 click
处理程序设置为内联:
msgbox.showMsgBox(
'Call Function outside of IIFE=> <button onclick="changeClass()" class="change_class">Change Class</button> (<= this button should have the same functionality as the other button)'
);
或者您可以更新 showMsgBox()
以添加处理程序:
function showMsgBox(msg) {
const modal = document.createElement("div");
⋮
modal.querySelectorAll(".change_class").forEach((item) => {
item.addEventListener("click", function (e) {
changeClass();
});
});
}
新按钮没有运行点击事件代码的原因是因为它没有被添加进去
一次
document.querySelectorAll(".change_class").forEach((item) => {
item.addEventListener("click", function (e) {
changeClass();
});
});
运行s,就是这样。任何带有 class 的新元素都不会自动再次生成上述代码 运行
您可以在创建按钮后将相同的事件处理程序添加到新创建的按钮 - 这很乏味,并且重复代码 - 如果您需要进行更改,您可能需要更改多个位置。错误代码的秘诀。
或者...这是一个使用事件委托的解决方案
const msgbox = (function () {
function showMsgBox(msg) {
const modal = document.createElement("div");
modal.classList.add("modal");
modal.innerHTML = `<div class="modal-content"><p>${msg}</p></div>`;
document.body.appendChild(modal);
modal.style.display = "block";
window.onclick = function (event) {
if (event.target === modal) {
modal.style.display = "none";
}
};
}
return {
showMsgBox: showMsgBox
};
})();
const example = document.getElementById("example");
function changeClass() {
if (example.getAttribute("class") === "classTwo") {
example.classList.remove("classTwo");
example.classList.add("classOne");
} else {
example.classList.add("classTwo");
example.classList.remove("classOne");
}
}
const change_class = document.getElementsByClassName("change_class");
document.body.addEventListener('click', function(e) {
if ([...change_class].includes(e.target)) {
changeClass();
}
});
document.querySelector(".showmsg").addEventListener("click", function (e) {
msgbox.showMsgBox('<button class="change_class">Change Class</button>');
});
* { font-family: sans-serif; }
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0, 0, 0); /* Fallback color */
background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */
}
/* Modal Content/Box */
.modal-content {
background-color: #fefefe;
margin: 15% auto; /* 15% from the top and centered */
padding: 20px;
border: 1px solid #888;
width: 80%; /* Could be more or less, depending on screen size */
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
.classOne {
background: #088;
color: #fff;
padding: 0.5rem;
}
.classTwo {
background: #808;
color: #fff;
padding: 0.5rem;
}
<button class="change_class">Change Class</button>
<br><br>
<div id="example" class="classOne">This will alternately use 'classOne' and 'classTwo'</div>
<br>
<button class="showmsg">Show MsgBox</button>
如代码中所述 document.getElementsByClassName
returns 一个 live
列表(querySelectorAll 没有)
这意味着使用指定 class 添加的任何新元素都将出现在该列表中,您无需执行任何操作。删除的元素也一样,它们只是从列表中消失
注意:getElementsByClassName
也是任何元素的方法,所以你不必获取文档中的所有此类元素,你可以使用它来获取文档中选定元素下的目标元素DOM - 不适用于此代码,但可能有用
我有代码成功调用了 IIFE 中的函数,而该函数又引用了 IIFE 之外的代码,我不知道如何调用。
const msgbox = (function () {
function showMsgBox(msg) {
const modal = document.createElement("div");
modal.classList.add("modal");
modal.innerHTML = `<div class="modal-content"><p>${msg}</p></div>`;
document.body.appendChild(modal);
modal.style.display = "block";
window.onclick = function (event) {
if (event.target === modal) {
modal.style.display = "none";
}
};
}
return {
showMsgBox: showMsgBox
};
})();
const example = document.getElementById("example");
function changeClass() {
if (example.getAttribute("class") === "classTwo") {
example.classList.remove("classTwo");
example.classList.add("classOne");
} else {
example.classList.add("classTwo");
example.classList.remove("classOne");
}
}
document.querySelectorAll(".change_class").forEach((item) => {
item.addEventListener("click", function (e) {
changeClass();
});
});
document.querySelector(".showmsg").addEventListener("click", function (e) {
msgbox.showMsgBox(
'Call Function outside of IIFE=> <button class="change_class">Change Class</button> (<= this button should have the same functionality as the other button)'
);
});
我尝试将非 IIFE 部分放入其自己的 IIFE 中并为其提供一个单独的命名空间,但这没有用。上面的示例是我的实际问题的简化版本,但这更简洁地封装了我的问题并减少了混淆。是的,我可以使 IIFE 只是一个函数并以这种方式调用它,但我正在努力扩展我的知识。
这是我为此创建的 CodePen 示例的 link: https://codepen.io/NoahBoddy/pen/PoOVMzK 希望我的解释很清楚。如果没有,我可以提供更多细节。谢谢!
模式中的按钮没有 click
处理程序,因此它什么都不做:
msgbox.showMsgBox(
'Call Function outside of IIFE=> <button class="change_class">Change Class</button> (<= this button should have the same functionality as the other button)'
);
您可以将 click
处理程序设置为内联:
msgbox.showMsgBox(
'Call Function outside of IIFE=> <button onclick="changeClass()" class="change_class">Change Class</button> (<= this button should have the same functionality as the other button)'
);
或者您可以更新 showMsgBox()
以添加处理程序:
function showMsgBox(msg) {
const modal = document.createElement("div");
⋮
modal.querySelectorAll(".change_class").forEach((item) => {
item.addEventListener("click", function (e) {
changeClass();
});
});
}
新按钮没有运行点击事件代码的原因是因为它没有被添加进去
一次
document.querySelectorAll(".change_class").forEach((item) => {
item.addEventListener("click", function (e) {
changeClass();
});
});
运行s,就是这样。任何带有 class 的新元素都不会自动再次生成上述代码 运行
您可以在创建按钮后将相同的事件处理程序添加到新创建的按钮 - 这很乏味,并且重复代码 - 如果您需要进行更改,您可能需要更改多个位置。错误代码的秘诀。
或者...这是一个使用事件委托的解决方案
const msgbox = (function () {
function showMsgBox(msg) {
const modal = document.createElement("div");
modal.classList.add("modal");
modal.innerHTML = `<div class="modal-content"><p>${msg}</p></div>`;
document.body.appendChild(modal);
modal.style.display = "block";
window.onclick = function (event) {
if (event.target === modal) {
modal.style.display = "none";
}
};
}
return {
showMsgBox: showMsgBox
};
})();
const example = document.getElementById("example");
function changeClass() {
if (example.getAttribute("class") === "classTwo") {
example.classList.remove("classTwo");
example.classList.add("classOne");
} else {
example.classList.add("classTwo");
example.classList.remove("classOne");
}
}
const change_class = document.getElementsByClassName("change_class");
document.body.addEventListener('click', function(e) {
if ([...change_class].includes(e.target)) {
changeClass();
}
});
document.querySelector(".showmsg").addEventListener("click", function (e) {
msgbox.showMsgBox('<button class="change_class">Change Class</button>');
});
* { font-family: sans-serif; }
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0, 0, 0); /* Fallback color */
background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */
}
/* Modal Content/Box */
.modal-content {
background-color: #fefefe;
margin: 15% auto; /* 15% from the top and centered */
padding: 20px;
border: 1px solid #888;
width: 80%; /* Could be more or less, depending on screen size */
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
.classOne {
background: #088;
color: #fff;
padding: 0.5rem;
}
.classTwo {
background: #808;
color: #fff;
padding: 0.5rem;
}
<button class="change_class">Change Class</button>
<br><br>
<div id="example" class="classOne">This will alternately use 'classOne' and 'classTwo'</div>
<br>
<button class="showmsg">Show MsgBox</button>
如代码中所述 document.getElementsByClassName
returns 一个 live
列表(querySelectorAll 没有)
这意味着使用指定 class 添加的任何新元素都将出现在该列表中,您无需执行任何操作。删除的元素也一样,它们只是从列表中消失
注意:getElementsByClassName
也是任何元素的方法,所以你不必获取文档中的所有此类元素,你可以使用它来获取文档中选定元素下的目标元素DOM - 不适用于此代码,但可能有用