如果没有iFrame,Javascript小部件是如何制作的?

时间:2018-03-11 13:31:55

标签: reactjs iframe widget web-component

我有一个聊天小部件,我想将其嵌入其他人的网站。它看起来就像对讲机和所有其他聊天弹出窗口。我想让聊天弹出窗口贴在屏幕的右下角,无论你在哪里滚动。但是,当我将聊天应用作为iframe导入并提供position: fixed; bottom: 0px; right: 15px;时,iframe不会转到我预期的位置。

我意识到嵌入式JS小部件的iframe不是最理想的,所有最好的嵌入式应用程序都是从文件存储中导入.js文件。在网上搜索了几个小时后,我还没有找到关于如何制作那些挂钩并渲染小部件的JS文件的解释/教程。你怎么做那些纯粹的javascript应用程序,他们叫什么? (我假设不是网络组件,因为很长一段时间都有小部件)。

很抱歉,如果这个问题有点像菜鸟。直到我自己尝试实现它,我才知道这是一件事。任何人都可以指出我如何开始制作JS网页小部件的正确方向?谢谢! (也许ReactJS到VanillaJS转换器会非常酷)

2 个答案:

答案 0 :(得分:4)

纯Javascript应用程序称为SPA - 单页应用程序 - 它们可以完全控制文档(页面)。但是,既然你问过嵌入一个小部件,我就不会认为这就是这个问题(在网上有很多关于SPA的信息)。

我打算建议你继续使用Web Components来实现这一目标 - 今天有多种填充功能可以在几乎所有浏览器上使用 - 但是因为你的问题提到你想知道如果没有它就会完成它,我以下是我的一种方法。

在创建纯JS小部件时,您需要确保您知道a)您无法控制全局空间,以及b)它需要与页面的其余部分一起使用。此外,由于您没有使用Web组件(并且正在寻找纯javascript(无库)),因此您还必须初始化小部件"手动"然后将其插入到所需位置的页面 - 作为一种明确的方法,您可以为您的窗口小部件指定一个HTML标签名称,只需将其添加到文档中,然后就会发生魔术:)

让我以这种方式打破它:

Widget Factory

这是一个简单的Javascript Widget工厂 - create()返回一个包含小部件的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为#34的DIV元素内部; chat_box&#34;,您会:

document.getElementById("chat_box").appendChild(myWidgetInstance);

因此,这是使用本机(Web)平台创建Widget的基础知识:)

创建可重用/可嵌入的组件

提供可重复使用和可嵌入组件的关键目标之一是确保您不依赖于全球空间。因此,您的交付方法(更像是您的构建过程)会将所有内容打包在一个JavaScript IIFD中,这也会为您的所有代码创建一个私有范围。

这些单件可重复使用/可嵌入组件的另一个重要方面是,您的Element的样式需要确保他们不会泄漏&#34; out并影响页面的其余部分(需要与其他人一起玩)。我这里不会详细介绍这方面的细节。 (仅供参考:这也是Web Component真正派上用场的地方)

以下是您可以在任何想要显示的页面添加的聊天组件的示例。该组件作为<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),定义样式以及其他可能使运行时更高效的改进。

另一种方法

您可以添加&#34;脚本&#34;一旦等待页面的其余部分加载,然后在文档中搜索已知的&#34;已知的&#34;元素集(例如,任何具有CSS类chat-box的elemnet)然后初始化它们内部的小部件(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>

希望这会有所帮助。

答案 1 :(得分:0)

创建没有第三方库的Javascript小部件的最佳方法是创建自定义元素。

以下链接:Custom Elements v1是对此技术的一个很好的介绍。

请参阅下面的最小示例:

&#13;
&#13;
class Chat extends HTMLElement {
    connectedCallback () {
        this.innerHTML = "<textarea>Hello</textarea>"    
    }
}

customElements.define( "chat-widget", Chat )
&#13;
<chat-widget>
</chat-widget>
&#13;
&#13;
&#13;