从 JS 脚本创建一个可嵌入的 "widget"

Create an embeddable "widget" from the JS script

我希望能够使用一行代码将通过此代码段创建的内容嵌入我喜欢的任何位置 - 与在某处获取任何类型的代码段的方式相同,以便它呈现 iframe 或 return 中的类似内容。我不确定从哪里开始,如果我已经拥有的是 usable/ready 以“转换”为可嵌入的片段。我浏览了一些教程,但它非常混乱,因为它使用了一些我不太了解的后端内容...

显然,它应该托管在某个地方,但是我需要“调用”代码片段的部分对我来说并不是很清楚。现在,它出现在我的网站上无处不在,因为它只是一个被包含的普通 JS 文件,与所有其他文件一样。

如果我能以某种方式打包并像这样调用它就太好了让我们说:

<script src="link-to-my-snippet.js"></script> 

如果有人能指导我一点,那就太好了。

const data = [
  {
    name: "John Doe",
    age: 40
  },
  {
    name: "Jane Doe",
    age: 50
  }
];

window.addEventListener("DOMContentLoaded", function() {
  function Item(configurationObject) {
    apiCall(data);
  }

  function apiCall(data) {
    // Do some API call and get back the data
    // With the Unique ID that wass passed in via the 
    // configuration Object
    // "data" is faked just for the demonstration
    createHTML(data);
  }

  function createHTML(data) {
    const mainDiv = document.createElement("div");
    document.body.appendChild(mainDiv);
    let html = '';

    data.forEach((user) => {
      html += `
          <div class="test">
              <p>${user.name}</p>
              <p>${user.age}</p>
          </div>
        `;
    });

    mainDiv.innerHTML = html;

    createStylesheet();
  }

  function createStylesheet() {
    const style = document.createElement("style");
    style.innerHTML = `
        .test {
                background-color: lightgreen;
            color: white;
        }
    `;

    document.head.appendChild(style);
  }

  let configurationObject = {
    uniqueID: 1234
  }

  let initialize = new Item(configurationObject);
});

我假设您有一些本地静态 HTML/CSS 页面。

首先,您不需要在 iframe 中呈现由 javascript 生成的 HTML,几乎任何元素都可以。 JS的目的是创建、操作和读取DOM-elements,所以不要觉得受限。

其次,其中一些代码对您的目的毫无用处,除非您打算使用 API(我假设不是)做一些事情,并且确实需要一个唯一的 ID。在该代码中,该唯一 ID 无论如何都不是唯一的,也没有用于任何用途。

有多种方法可以在您选择的任何页面上实施此脚本,但这里有一个:

你有一个 HTML 文件,在那个文件中,输入:

<div id="users-list"></div>

无论您希望列表出现在何处。

创建一个任意名称的文件,例如 users-list.js。检查我的答案中的演示,了解要放入该文件的 JS 代码。

在您添加了 ID 为 'users-list' 的元素的任何 HTML 文件中,也只需将脚本添加到同一个 HTML 文件中。最好在结束标签之前。

<script src="/path/to/users-list.js"></script>

当然,您以多种方式制作它,并无限扩展它。例如,像这样的东西可能很酷:

<div id="some-div-id"></div>

...

<script src="/path/users-list.js">
  getUsers({
    element: 'some-div-id'
    theme: 'dark',
    layout: 'boxes' // or 'rows'
  }); 
</script>

然后你可以在不同的页面上调用脚本生成不同的 HTML,当然,这需要对你的 JS 代码进行一些修改,才能真正打印出不同的 css 内容,并且获取放置数据的正确元素。

总之,做起来并不难。

但回到主题,工作演示:

const users = [
  {
    name: "John Doe",
    age: 40
  },
  {
    name: "Jane Doe",
    age: 50
  }
];

const styles = `
    .user {
        background-color: lightgreen;
        color: white;
    }

    .age { font-weight: bold; }
`;

function setStyles() {
    const styleElement = document.createElement('style');
    
    styleElement.innerHTML = styles;

    document.head.appendChild(styleElement);
}

function setUsers(users) {
    let element = document.getElementById('users-list')

    let usersHtml = '';

    users.forEach(user => {
        usersHtml += `
            <div class="user">
                <p class="name">${user.name}</p>
                <p class="age">${user.age}</p>
            </div>
        `;
    })

    if (element) element.innerHTML = usersHtml;
}



window.addEventListener("DOMContentLoaded", function () {
    setUsers(users);
    setStyles(styles); 
});
<div id="users-list"></div>

这是一个自调用递归 IIFE 检查文档 readyState 的示例,比公认的答案解决方案更好


const myPlugin = () => {
  // stuff
}

/** 
 *  Checks the document readyState until it's ready
 */
(ready = (delay) => {
  // this is always 'complete' if everything on the page is loaded,
  // if you want to check for a state when all html/js is loaded but not all assets, check for 'interactive'
  if (document.readyState == 'complete') {
    myPlugin() // your stuff being invoked when doc is ready
  } else {
    console.log('Retrying!')
    setTimeout(() => { ready(delay) }, delay)
  }
})(50)

有两种方法:

  1. 使用现代 javascript - ES6、Webpack、SCSS,然后使用 NPM 将它们全部打包到一个文件中 关注:https://blog.jenyay.com/building-javascript-widget/

  2. 纯 JavaScript - 自定义创建。

您可以像这样创建一个可自行执行的匿名函数,并在其中编写完整的小部件代码 - 包括您的 HTML、CSS 等。一旦您的页面加载了此脚本,它将被执行。

(function() {
    // The following code will be enclosed within an anonymous function
    var foo = "Hello World!";
    document.write("<p>Inside our anonymous function foo means '" + foo + '".</p>');
})(); // We call our anonymous function immediately

第二种方案也可以参考以下文章: https://gomakethings.com/the-anatomy-of-a-vanilla-javascript-plugin/