在不受Host Page CSS影响的跨域主机页面中创建嵌入式JavaScript?

con*_*ile 26 html javascript css iframe gwt

可以嵌入到网站中的大多数javascript小部件使用以下结构.首先,你嵌入一个像这样截断的代码:

<script type="text/javascript">
window.$zopim||(function(d,s){var z=$zopim=function(c){
z._.push(c)},
$=z.s=d.createElement(s),
e=d.getElementsByTagName(s)[0];
z.set=function(o){
    z.set._.push(o)
};
z._=[];
z.set._=[];
$.async=!0;
$.setAttribute('charset','utf-8');
$.src='//v2.zopim.com/?2342323423434234234';
z.t=+new Date;
$.type='text/javascript';
e.parentNode.insertBefore($,e)})(document,'script');
</script>
Run Code Online (Sandbox Code Playgroud)

然后,在加载页面时,此脚本会创建一个html结构,如下所示:

<div class="widget-class">
  <iframe src="about:blank">
    // the content of the widget
  </iframe>
</div
Run Code Online (Sandbox Code Playgroud)

我在许多聊天服务中看到了相同的结构,例如:

https://en.zopim.com/ 
http://banckle.com/
https://www.livechatinc.com/
Run Code Online (Sandbox Code Playgroud)

所有的共同点都是他们的iframe没有src,即附加了一个URL.

更新:这是我用来将我的窗口小部件代码加载到第三方网站的脚本:

<script type="text/javascript">
(function(d){
    var f = d.getElementsByTagName('SCRIPT')[0], p = d.createElement('SCRIPT');
    window.WidgetId = "1234";   
    p.type = 'text/javascript';
    p.setAttribute('charset','utf-8');
    p.async = true;     
    p.src = "//www.example.com/assets/clientwidget/chatwidget.nocache.js";     
    f.parentNode.insertBefore(p, f);
}(document));
</script>    
Run Code Online (Sandbox Code Playgroud)

我希望集成GWT小部件的站点的CSS不应该影响GWT小部件的CSS.我会阻止主页的CSS影响我的GWT小部件的CSS.

注意:我也希望从我的GWT小部件访问主机网站.
主页的域名是www.example.com,iframe的域名是www.widget.com.我还想从iframe设置主机域的cookie.

构建在这样的结构上运行的小部件的过程是什么?如何设置iframe的内容?那有什么模式吗?我怎么能用GWT做到这一点

Mic*_*ski 6

我不知道 GWT,但是您可以使用纯 JavaScript 轻松实现这一点。

假设您正在创建一个在线计数小部件。首先,创建一个 iframe:

<script id="your-widget">
  // Select the script tag used to load the widget.
  var scriptElement = document.querySelector("your-widget");
  // Create an iframe.
  var iframe = document.createElement("iframe");
  // Insert iframe before script's next sibling, i.e. after the script.
  scriptElement.parentNode.insertBefore(iframe, scriptElement.nextSibling);
  // rest of the code
</script>
Run Code Online (Sandbox Code Playgroud)

然后使用 JSONP 获取在线计数(请参阅什么是 JSONP?),例如:

// The URL of your API, without JSONP callback parameter.
var url = "your-api-url";
// Callback function used for JSONP.
// Executed as soon as server response is received.
function callback(count) {
  // rest of code
}
// Create a script.
var script = document.createElement("script");
// Set script's src attribute to API URL + JSONP callback parameter.
// It makes browser send HTTP request to the API.
script.src = url + "?callback=callback";
Run Code Online (Sandbox Code Playgroud)

然后处理服务器响应(在callback()函数内部):

// Create a div element
var div = document.createElement("div");
// Insert online count to this element.
// I assume that server response is plain-text number, for example 5.
div.innerHTML = count;
// Append div to iframe's body.
iframe.contentWindow.document.body.appendChild(div);
Run Code Online (Sandbox Code Playgroud)

就这样。您的整个代码可能如下所示:

插入第三方网站的代码段:

<script type="text/javascript">
(function(d){
    var f = d.getElementsByTagName('SCRIPT')[0], p = d.createElement('SCRIPT');
    window.WidgetId = "1234";   
    p.type = 'text/javascript';
    p.setAttribute('charset','utf-8');
    p.async = true;
    p.id = "your-widget";
    p.src = "//www.example.com/assets/clientwidget/chatwidget.nocache.js";     
    f.parentNode.insertBefore(p, f);
}(document));
</script>    
Run Code Online (Sandbox Code Playgroud)

您服务器上的 JavaScript 文件:

// Select the script tag used to load the widget.
var scriptElement = document.querySelector("#your-widget");
// Create an iframe.
var iframe = document.createElement("iframe");
// Insert iframe before script's next sibling, i.e. after the script.
scriptElement.parentNode.insertBefore(iframe, scriptElement.nextSibling);

// The URL of your API, without JSONP callback parameter.
var url = "your-api-url";
// Callback function used for JSONP.
// Executed as soon as server response is received.
function callback(count) {
  // Create a div element
  var div = document.createElement("div");
  // Insert online count to this element.
  // I assume that server response is plain-text number, for example 5.
  div.innerHTML = count;
  // Append div to iframe's body.
  iframe.contentWindow.document.body.appendChild(div);
}
// Create a script.
var script = document.createElement("script");
// Set script's src attribute to API URL + JSONP callback parameter.
// It makes browser send HTTP request to the API.
script.src = url + "?callback=callback";
Run Code Online (Sandbox Code Playgroud)