基于 JavaScript 的模态/弹出服务(如 KissInsights 和 Hello Bar)如何工作

How do JavaScript-based modal/popup services like KissInsights and Hello Bar work?

本文关键字:Bar Hello JavaScript 何工作 工作 KissInsights 服务 基于 模态      更新时间:2023-09-26

我正在为我的用户开发一个模态/弹出系统,以嵌入他们的网站,就像KissInsights和Hello Bar(这里和这里的例子)一样。

构建此类服务的最佳实践是什么?看起来用户嵌入了一些JS,但该代码随后插入了额外的脚本标记。

我想知道它如何与 Web 服务通信以获取用户的内容等。

蒂亚

你是对的,通常它只是客户嵌入到他们网站上的脚本。然而,之后的事情有点复杂。

1. 嵌入脚本

如前所述,第一步是在目标页面上有一个脚本。

本质上,这个脚本只是一段JavaScript代码。这与你自己页面上的内容非常相似。

此脚本应在您希望显示的客户页面上生成内容。

但是,您需要考虑一些事项:

  • 您不能使用任何库(或者如果您这样做,请非常小心您使用的内容):这些库可能与页面上已有的内容冲突,并破坏客户的网站。你不想那样做。
  • 永远不要覆盖任何内容,因为覆盖可能会破坏客户的站点:这包括事件侦听器、本机对象属性等。例如,始终对事件使用 addEventListeneraddEvent,因为它们允许您拥有多个侦听器
  • 不能信任任何样式:您创建的所有样式的 HTML 元素都必须内联,因为客户的网站可能有自己的 CSS 样式。
  • 您无法添加自己的任何 CSS 规则:这些规则可能会再次破坏客户的网站。

这些规则适用于直接在客户站点上运行的任何脚本或内容。如果创建 iframe 并在其中显示内容,则可以在框架内的任何内容中忽略这些规则。

2. 在服务器上处理脚本

可嵌入脚本通常应由服务器上的脚本生成。这允许您包含逻辑,例如根据参数或应用程序数据库中的数据选择要显示的内容。

这可以用您喜欢的任何语言编写。

通常,脚本 URL 应包含某种标识符,以便您知道要显示的内容。例如,您可以使用 ID 来判断它是哪个客户的站点或其他类似的东西。

如果您的应用程序要求用户登录,您可以像往常一样处理此问题。服务器端脚本被其他网站调用的事实没有区别。

嵌入式脚本与服务器或帧之间的通信

这也有一些技巧。

如您所知,XMLHttpRequest 不能跨不同的域工作,因此您不能使用它。

从其他站点发送数据的最简单方法是使用 iframe 并让用户在 iframe 内提交表单(或在框架内运行 XMLHttpRequest,因为 iframe 的内容驻留在您自己的服务器上,因此没有跨域通信)

如果嵌入的脚本在 iframe 对话框中显示内容,则可能需要能够告诉客户站点上嵌入的脚本何时关闭 iframe。例如,这可以通过使用window.postMessage

来实现

有关帖子消息,请参阅 http://ejohn.org/blog/cross-window-messaging/

有关跨域通信,请参阅 http://softwareas.com/cross-domain-communication-with-iframes

你可以看看这里 - 这是一个使用我的JsApiToolkit创建的API的例子,这是一个允许服务提供商轻松创建和分发类似Facebook Connect的工具到第三方网站的框架。

该库建立在用于跨域消息传递的easyXDM之上,并通过模式对话框或弹出窗口促进交互。

代码和自述文件应该足以解释事物如何组合在一起(一旦你抽象出像XDM这样的东西,它真的不太复杂)。

关于嵌入本身;你可以直接这样做,但大多数服务使用"引导"脚本,可以很容易地更新以指向真正的文件 - 这个小文件可以与缓存编译指示一起提供,以确保它不会被缓存太久,而注入的文件可以作为长寿命文件提供。

这样,您只会产生重新下载引导程序而不是整个脚本集的开销。

最佳做法是将尽可能少的代码放入代码片段中,这样就不必要求用户更新其代码。 例如:

<script type="text/javascript" src="http://your.site.com/somecode.js"></script>

如果作者将其嵌入到他们的页面中,则工作正常。否则,如果您需要书签,则可以使用此代码在任何页面上加载脚本:

  javascript:(function(){
    var e=document.createElement('script');
    e.setAttribute('language','javascript');
    e.setAttribute('src','http://your.site.com/somecode.js');
    document.head.appendChild(e);
  })();

现在,您的所有代码都将位于上面引用的 URI 中,并且每当加载其页面时,都会下载并执行代码的新副本。(不考虑缓存设置)

从该脚本中,只需确保不要破坏命名空间,并在加载另一个库之前检查是否存在一个库。 使用安全jQuery对象而不是$(如果使用)。 如果你想加载更多的外部内容(如jQuery,UI内容等),请使用onload处理程序来检测它们何时完全加载。 例如:

function jsLoad(loc, callback){
  var e=document.createElement('script');
  e.setAttribute('language','javascript');
  e.setAttribute('src',loc);
  if (callback) e.onload = callback;
  document.head.appendChild(e);
}

然后你可以简单地调用这个函数来加载任何js文件,并执行一个回调函数。

jsLoad('http://link.to/some.js', function(){
  // do some stuff
});

现在,与您的域通信以检索数据的一种棘手方法是使用 javascript 作为传输。例如:

jsLoad('http://link.to/someother.js?data=xy&callback=getSome', function(){
  var yourData = getSome();
});

你的服务器必须动态处理该路由,并返回一些具有"getSome"函数的javascript,该函数可以执行您想要的操作。例如:

function getSome(){
  return {'some':'data','more':'data'};
}

这将非常有效地允许您与服务器通信并从服务器可以获取数据的任何地方处理数据。

你可以提供一个动态生成的(例如使用PHP或Ruby on Rails)在每个请求上生成这个文件)JS文件,从你的服务器导入从客户网站导入,如下所示:

<script type="text/javascript" src="//www.yourserver.com/dynamic.js"></script>

然后,您需要为客户提供一种方法来决定他们希望模态/弹出窗口包含的内容(例如文本,图形,链接等)。您可以创建一个简单的CMS,也可以为每个客户手动创建。

您的服务器可以看到对 JS 文件的每个请求来自何处,并基于此提供不同的 JS 代码。例如,JS代码可以将HTML代码插入到您的客户网站中,该网站在顶部创建一个带有一些文本和链接的栏。

如果您想访问客户的访问者信息,您可能需要从HTML代码中读取它,让您的客户以特定方式提供您想要的信息,或者找出从每个客户Web服务器访问它的不同方式。