douchaoyang / blog

blogs use issues
0 stars 0 forks source link

广告系统中加载HTML片段广告(可包含外部js引用)或加载iframe广告的方法 #9

Open douchaoyang opened 1 year ago

douchaoyang commented 1 year ago

在广告系统设计中,其中有一种类型来自于自定义的HTML片段。 或者是第三方提供的一个HTML片段,大多数时候还包含外部js的引用。 针对此类广告,实现以下加载方式,mock的数据格式如下。 其中 key 为广告锚点元素的id,value中定义了广告的宽高、是否可iframe加载,HTML片段的代码。 此结构仅为示例,可后期扩展与调整。

{
  id: {
    width,
    height,
    iframeFriendly,
    html
  }
}

渲染的模块示例。

window.Advertisment = (function () {
  /* 

    {
      id: {
        width,
        height,
        iframeFriendly,
        html
      }
    }

   */

  function createFrame(option) {
    var e = document.createElement("IFRAME");
    var g = e.style;
    e.scrolling = "no";
    e.frameBorder = 0;
    e.width = option.width > 0 ? option.width : 0;
    e.height = option.height > 0 ? option.height : 0;
    g.border = 0;
    g.overflow = "hidden";
    return e;
  }

  function loadFrame(frame, content) {
    var doc = frame.contentDocument || frame.contentWindow.document;
    doc.open();
    doc.writeln("<!DOCTYPE html>");
    doc.writeln("<html>");
    doc.writeln('<head><base target="_top"></head>');
    doc.writeln('<body border="0" margin="0" style="margin: 0; padding: 0">');
    doc.writeln(content);
    doc.writeln("</body>");
    doc.writeln("</html>");
    doc.close();
  }

  function init(elements) {
    for (var id in elements) {
      if (elements.hasOwnProperty(id)) {
        var option = elements[id];
        var element = document.getElementById(id);
        if (element) {
          var ins = document.createElement("INS");
          if (option.iframeFriendly) {
            var frame = createFrame(option);
            ins.appendChild(frame);
            element.parentNode.replaceChild(ins, element);
            loadFrame(frame, option.html);
          } else {
            ins.innerHTML = option.html;
            var scripts = ins.getElementsByTagName("SCRIPT");
            for (var i = 0; i < scripts.length; i++) {
              var script = document.createElement("SCRIPT");
              var attrs = scripts[i].attributes;
              for (var j = 0; j < attrs.length; j++) {
                script[attrs[j].nodeName] = attrs[j].value;
              }
              if (scripts[i].innerHTML) {
                script.text = scripts[i].innerHTML;
              }
              scripts[i].parentNode.replaceChild(script, scripts[i]);
            }
            element.parentNode.replaceChild(ins, element);
          }
        }
      }
    }
  }

  return {
    init: init,
  };
})();

锚点示例。

<ins id="revive-0-0"></ins>

数据示例,可设计为接口异步加载。

var data = {
  "revive-0-0": {
    html: "your html code here",
    width: "970",
    height: "90",
    iframeFriendly: false,
  }
};

调用方法。

window.Advertisment.init(data);