嵌入在 HTML 腳本中的 ES6 模塊中定義的函式對該腳本不可用。因此,如果您有以下陳述句:
<button onclick="doSomething();">Do something</button>
在您的 HTML 中,并且您的 doSomething() 函式位于嵌入 HTML 腳本的 ES6 模塊中,當您運行腳本時,您將收到“doSomething() 未定義”錯誤。
直接在 html 中使用 ES6 模塊中定義的函式為當前問題提供了一個很好的解決方案,建議您通過修改 HTML 將函式“系結”到按鈕:
<button id="dosomethingbutton">Do something</button>
并使用模塊本身來創建鏈接,因此:
document.getElementById('dosomethingbutton').addEventListener('click', doSomething);
這作業正常,但是如果您的原始按鈕更復雜并且引數化了怎么辦?例如:
<button onclick="doSomething('withThisString');">Do Something with String</button>
“系結”可以提供的最多似乎僅限于與事件相關的情況 - 我找不到將其與資料相關聯的方法。我完全被困在試圖找到解決方案的程序中,非常感謝您的幫助。
我想補充一點,雖然這個問題可能看起來有點模糊,但我認為任何遷移到 Firebase 9 的人都會感興趣。除其他更改外,遷移要求您將 javascript 代碼移動到 ES6 模塊中,因此很可能最簡單的 HTML 會立即解決這些問題。谷歌自己沒有提到這個問題,這可能是因為他們希望代碼與 Webpack 捆綁在一起。但是我對這些概念還不熟悉,還沒有嘗試過,因為我仍在努力掌握轉換程序的基礎知識。建議將是最受歡迎的。
uj5u.com熱心網友回復:
這作業正常,但是如果您的原始按鈕更復雜并且引數化了怎么辦?
有幾個解決方案:
一個
data-*屬性:<button id="the-button" data-string="withThisString">Do Something with String</button>document.getElementById("the-button").addEventListener("click", function() { doSomething(this.getAttribute("data-string")); });(更多關于這個下面。)
或者
系結事件時系結字串
<button id="the-button">Do Something with String</button>document.getElementById("the-button").addEventListener("click", () => { doSomething("withThisString"); });
上面有很多變化,如果您使用doSomething具有不同字串的多個按鈕,您可以使用類和回圈而不是使用 1 來做#1 id,但這是一般想法。
關于data-*屬性的事情:如果你愿意,你可以通過data-*屬性和一個將事物聯系起來的單個函式使這個程序完全由 HTML 驅動。例如,假設您有這些按鈕:
<button data-click="doThisx@module1">Do This</button>
<button data-click="doThat@module2">Do That</button>
<button data-click="doTheOther@module3">Do The Other</button>
你可以有一個可重用的函式來連接它們:
class EventSetupError extends Error {
constructor(element, msg) {
if (typeof element === "string") {
[element, msg] = [msg, element];
}
super(msg);
this.element = element;
}
}
export async function setupModuleEventHandlers(eventName) {
try {
const attrName = `data-${eventName}`;
const elements = [...document.querySelectorAll(`[${attrName}]`)];
await Promise.all(elements.map(async element => {
const attrValue = element.getAttribute(`data-${eventName}`);
const [fname, modname] = attrValue ? attrValue.split("@", 2) : [];
if (!fname || !modname) {
throw new EventSetupError(
element,
`Invalid '${attrName}' attribute "${attrValue}"`
);
}
// It's fine if we do import() more than once for the same module,
// the module loader will return the same module
const module = await import(`./${modname}.js`);
const fn = module[fname];
if (typeof fn !== "function") {
throw new EventSetupError(
element,
`Invalid '${attrName}': no '${fname}' on module '${modname}' or it isn't a function`
);
}
element.addEventListener(eventName, fn);
}));
} catch (error) {
console.error(error.message, error.element);
}
}
使用它來查找和連接點擊處理程式:
import { setupModuleEventHandlers } from "./data-attr-event-setup.js";
setupModuleEventHandlers("click")
.catch(error => {
console.error(error.message, error.element);
});
這是一次性管道,但在 HTML 中為您提供相同的基于屬性的體驗(事件處理程式仍然可以從另一個data-*屬性獲取引數資訊,或者您可以將其放入設定函式中)。(該示例依賴于dynamicimport,但所有主要瀏覽器的最新版本都支持它,并且在不同程度上支持打包程式。
有幾十種方法可以旋轉它,我不是在推廣它,只是舉例說明如果你愿意,你可以很容易地做的事情。
但實際上,這正是 React、Vue、Ember、Angular、Lit 等庫發揮作用的地方。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/336908.html
標籤:javascript html 火力基地 ecmascript-6
