基于JavaScript的模式/弹出服务如KissInsights和Hello Bar如何工作?

时间:2011-05-21 23:15:31

标签: javascript jquery modal-dialog

我正在为我的用户开发一个模态/弹出系统,以便嵌入他们的网站,与KissInsights和Hello Bar(例如herehere)一样。

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

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

TIA

4 个答案:

答案 0 :(得分:9)

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

1。嵌入脚本

首先要说的是在目标页面上有一个脚本。

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

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

但是,您需要考虑以下事项:

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

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

2。服务器上的处理脚本

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

这可以用你喜欢的任何语言写成。

通常,您的脚本网址应包含某种标识符,以便您知道要显示的内容。例如,您可以使用该ID来告知客户的网站或其他类似的内容。

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

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

这也有一些技巧。

如您所知,XMLHttpRequest在不同的域中不起作用,因此您无法使用它。

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

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

来实现

对于postMessage,请参阅http://ejohn.org/blog/cross-window-messaging/

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

答案 1 :(得分:2)

您可以查看here - 这是使用我的JsApiToolkit创建的API示例,该框架允许服务提供商轻松创建和分发类似Facebook Connect的工具到第三方网站

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

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

关于嵌入本身;您可以直接执行此操作,但大多数服务使用“引导”脚本,可以轻松更新以指向真实文件 - 这个小文件可以使用缓存编译指示,以确保它不会缓存太长时间,而注入的文件可以作为长文件提供。

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

答案 2 :(得分:1)

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

<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'};
}

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

答案 3 :(得分:0)

您可以提供动态生成(用于例如PHP或Ruby on Rails)以在每个请求上生成此文件)来自您的服务器的JS文件,该文件是从客户网站导入的,如下所示:

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

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

您的服务器可以看到每个JS文件请求的来源,并根据它提供不同的JS代码。例如,JS代码可以将HTML代码插入到客户网站中,在顶部创建一个带有文本和链接的栏。

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