Javascript 小部件如何在没有 iFrame 的情况下制作?
How are Javascript widgets made without iFrames?
我有一个聊天小部件,我想将它嵌入其他人的网站。它看起来就像 Intercom 和所有其他聊天弹出窗口。无论您滚动到哪里,我都想让聊天弹出窗口固定在屏幕的右下角。但是,当我将聊天应用程序作为 iframe 导入并给它 position: fixed; bottom: 0px; right: 15px;
时,iframe 没有到达我期望的位置。
我意识到 iframe 不是嵌入式 JS 小部件的最佳选择,所有最好的嵌入式应用程序都从文件存储中导入 .js 文件。在网上搜索了几个小时后,我还没有找到关于如何制作挂接到 a 并呈现小部件的 JS 文件的 explanation/tutorial。您是如何制作其中一个纯 javascript 应用程序的,它们叫什么? (我假设不是网络组件,因为小部件已经存在很长时间了)。
抱歉,如果这个问题有点菜鸟。在我尝试自己实施之前,我从来不知道这是一回事。谁能指出我如何开始制作 JS 网络小部件的正确方向?谢谢! (也许 ReactJS 到 VanillaJS 转换器会非常酷)
纯 Javascript 应用程序称为 SPA - 单页应用程序 - 他们可以完全控制文档(页面)。但是既然你问的是嵌入一个小部件,我不认为这是这个问题的问题(有大量的信息。在 SPA 的网络上)。
我打算建议您今后使用 Web 组件来执行此操作 - 现在有可用的 polyfill 可以在几乎所有浏览器上运行 - 但由于您的问题提到您想知道没有它是如何完成的,我在下面详细介绍了我的一种方法。
当创建一个纯 JS 小部件时,您需要确保您知道 a) 您无法控制全局 space 和 b) 它需要与其余部分一起使用页。此外,由于您没有使用 Web 组件(并且正在寻找纯 javascript(无库)),因此您还必须初始化小部件 "manually",然后将其插入到所需的页面location - 与声明式方法相反,在这种方法中,您为小部件分配了一个 HTML 标签名称,您只需将其添加到文档中,魔法就会发生 :)
让我这样分解:
小部件工厂
这是一个简单的 Javascript 小部件工厂 - create()
returns 一个 HTML 元素与您的小部件:
const Widget = Object.create({
create(chatId) {
const wdg = document.createElement("div")
wdg.classList.add("chat-box");
wdg.innerHTML = `<h1>Chat: ${ chatId }</h1>`;
// Load your chat data into UI
return wdg;
}
});
要使用上面的方法创建一个新的小部件(HTML 元素),您将:
const myWidgetInstance = Widget.create("chat-12345");
并将此小部件插入页面的给定位置(例如,在 ID 为 "chat_box" 的 DIV 元素内,您将:
document.getElementById("chat_box").appendChild(myWidgetInstance);
这就是使用本机(网络)平台创建 Widget 的基础知识:)
正在创建一个 reusable/embeddable 组件
交付可重用和可嵌入组件时的一个关键目标是确保您不依赖全局 space。因此,您的交付方法(更像是您的构建过程)会将所有内容打包在一个 JavaScript IIFD 中,这也会为您的所有代码创建一个私有范围。
这些类型的单例 reusable/embeddable 组件的另一个重要方面是您的元素样式需要确保它们不会 "leak" 出来并影响页面的其余部分(需要和别人玩得开心)。我不会在这里详细介绍这个领域。 (仅供参考:这也是 Web 组件真正派上用场的领域)
这是一个聊天组件示例,您可以将其添加到页面中您希望它出现的任何位置。该组件作为 <script>
标签交付,其中包含所有代码:
<script>(function() {
const Widget = Object.create({
create(chatId) {
const wdg = document.createElement("div");
wdg.classList.add("chat-box");
wdg.innerHTML = `<h1>Chat: ${ chatId }</h1>`;
// Load your chat data into UI
return wdg;
}
});
const myWidgetInstance = Widget.create("chat-12345");
const id = `chat-${ Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1) }`;
document.write(`<div id="${ id }"></div>`);
document.getElementById(id).appendChild(myWidgetInstance);
})();</script>
所以你可以在多个地方使用它,只需将这个脚本标签放在所需的位置:
<body>
<div>
<h1>Chat 1</h1>
<script>/* script tag show above */</script>
</div>
...
<div>
<h1>Chat 2</h1>
<script>/* script tag show above */</script>
</div>
</body>
这只是如何完成的示例方法。您将不得不添加更多内容以支持将选项传递给每个小部件(例如聊天 ID)、定义样式以及其他可能提高运行时效率的改进。
另一种方法
您可以添加 "script" 一次并等待页面的其余部分加载,然后在文档中搜索 "known" 组元素(例如任何具有 CSS Class of chat-box
),然后在其中初始化一个小部件(jQuery 使这种方法流行起来)。
示例:
请注意如何在 DOM 元素中使用 data
属性来存储更多特定于您的小部件的数据。
<div class="chat-box" data-chatid="123"></div>
<script>(function() {
const Widget = Object.create({
create(chatId) {
const wdg = document.createElement("div");
wdg.classList.add("chat-box");
wdg.innerHTML = `<h1>Chat: ${ chatId }</h1>`;
// Load your chat data into UI
return wdg;
}
});
const initWhenReady = () => {
removeEventListener("DOMContentLoaded", initWhenReady);
Array.prototype.forEach.call(document.querySelectorAll(".chat-box"), ele => {
const myWidgetInstance = Widget.create(ele.dataset.chatid);
ele.appendChild(myWidgetInstance);
});
};
addEventListener('DOMContentLoaded', initWhenReady);
})();</script>
希望这对您有所帮助。
在没有 third-party 库的情况下创建 Javascript 小部件的最佳方法是创建自定义元素。
下面link:Custom Elements v1很好的介绍了这项技术
请参阅下面的最小示例:
class Chat extends HTMLElement {
connectedCallback () {
this.innerHTML = "<textarea>Hello</textarea>"
}
}
customElements.define( "chat-widget", Chat )
<chat-widget>
</chat-widget>
我有一个聊天小部件,我想将它嵌入其他人的网站。它看起来就像 Intercom 和所有其他聊天弹出窗口。无论您滚动到哪里,我都想让聊天弹出窗口固定在屏幕的右下角。但是,当我将聊天应用程序作为 iframe 导入并给它 position: fixed; bottom: 0px; right: 15px;
时,iframe 没有到达我期望的位置。
我意识到 iframe 不是嵌入式 JS 小部件的最佳选择,所有最好的嵌入式应用程序都从文件存储中导入 .js 文件。在网上搜索了几个小时后,我还没有找到关于如何制作挂接到 a 并呈现小部件的 JS 文件的 explanation/tutorial。您是如何制作其中一个纯 javascript 应用程序的,它们叫什么? (我假设不是网络组件,因为小部件已经存在很长时间了)。
抱歉,如果这个问题有点菜鸟。在我尝试自己实施之前,我从来不知道这是一回事。谁能指出我如何开始制作 JS 网络小部件的正确方向?谢谢! (也许 ReactJS 到 VanillaJS 转换器会非常酷)
纯 Javascript 应用程序称为 SPA - 单页应用程序 - 他们可以完全控制文档(页面)。但是既然你问的是嵌入一个小部件,我不认为这是这个问题的问题(有大量的信息。在 SPA 的网络上)。
我打算建议您今后使用 Web 组件来执行此操作 - 现在有可用的 polyfill 可以在几乎所有浏览器上运行 - 但由于您的问题提到您想知道没有它是如何完成的,我在下面详细介绍了我的一种方法。
当创建一个纯 JS 小部件时,您需要确保您知道 a) 您无法控制全局 space 和 b) 它需要与其余部分一起使用页。此外,由于您没有使用 Web 组件(并且正在寻找纯 javascript(无库)),因此您还必须初始化小部件 "manually",然后将其插入到所需的页面location - 与声明式方法相反,在这种方法中,您为小部件分配了一个 HTML 标签名称,您只需将其添加到文档中,魔法就会发生 :)
让我这样分解:
小部件工厂
这是一个简单的 Javascript 小部件工厂 - create()
returns 一个 HTML 元素与您的小部件:
const Widget = Object.create({
create(chatId) {
const wdg = document.createElement("div")
wdg.classList.add("chat-box");
wdg.innerHTML = `<h1>Chat: ${ chatId }</h1>`;
// Load your chat data into UI
return wdg;
}
});
要使用上面的方法创建一个新的小部件(HTML 元素),您将:
const myWidgetInstance = Widget.create("chat-12345");
并将此小部件插入页面的给定位置(例如,在 ID 为 "chat_box" 的 DIV 元素内,您将:
document.getElementById("chat_box").appendChild(myWidgetInstance);
这就是使用本机(网络)平台创建 Widget 的基础知识:)
正在创建一个 reusable/embeddable 组件
交付可重用和可嵌入组件时的一个关键目标是确保您不依赖全局 space。因此,您的交付方法(更像是您的构建过程)会将所有内容打包在一个 JavaScript IIFD 中,这也会为您的所有代码创建一个私有范围。
这些类型的单例 reusable/embeddable 组件的另一个重要方面是您的元素样式需要确保它们不会 "leak" 出来并影响页面的其余部分(需要和别人玩得开心)。我不会在这里详细介绍这个领域。 (仅供参考:这也是 Web 组件真正派上用场的领域)
这是一个聊天组件示例,您可以将其添加到页面中您希望它出现的任何位置。该组件作为 <script>
标签交付,其中包含所有代码:
<script>(function() {
const Widget = Object.create({
create(chatId) {
const wdg = document.createElement("div");
wdg.classList.add("chat-box");
wdg.innerHTML = `<h1>Chat: ${ chatId }</h1>`;
// Load your chat data into UI
return wdg;
}
});
const myWidgetInstance = Widget.create("chat-12345");
const id = `chat-${ Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1) }`;
document.write(`<div id="${ id }"></div>`);
document.getElementById(id).appendChild(myWidgetInstance);
})();</script>
所以你可以在多个地方使用它,只需将这个脚本标签放在所需的位置:
<body>
<div>
<h1>Chat 1</h1>
<script>/* script tag show above */</script>
</div>
...
<div>
<h1>Chat 2</h1>
<script>/* script tag show above */</script>
</div>
</body>
这只是如何完成的示例方法。您将不得不添加更多内容以支持将选项传递给每个小部件(例如聊天 ID)、定义样式以及其他可能提高运行时效率的改进。
另一种方法
您可以添加 "script" 一次并等待页面的其余部分加载,然后在文档中搜索 "known" 组元素(例如任何具有 CSS Class of chat-box
),然后在其中初始化一个小部件(jQuery 使这种方法流行起来)。
示例:
请注意如何在 DOM 元素中使用 data
属性来存储更多特定于您的小部件的数据。
<div class="chat-box" data-chatid="123"></div>
<script>(function() {
const Widget = Object.create({
create(chatId) {
const wdg = document.createElement("div");
wdg.classList.add("chat-box");
wdg.innerHTML = `<h1>Chat: ${ chatId }</h1>`;
// Load your chat data into UI
return wdg;
}
});
const initWhenReady = () => {
removeEventListener("DOMContentLoaded", initWhenReady);
Array.prototype.forEach.call(document.querySelectorAll(".chat-box"), ele => {
const myWidgetInstance = Widget.create(ele.dataset.chatid);
ele.appendChild(myWidgetInstance);
});
};
addEventListener('DOMContentLoaded', initWhenReady);
})();</script>
希望这对您有所帮助。
在没有 third-party 库的情况下创建 Javascript 小部件的最佳方法是创建自定义元素。
下面link:Custom Elements v1很好的介绍了这项技术
请参阅下面的最小示例:
class Chat extends HTMLElement {
connectedCallback () {
this.innerHTML = "<textarea>Hello</textarea>"
}
}
customElements.define( "chat-widget", Chat )
<chat-widget>
</chat-widget>