iframe.contentWindow.document.write导致的内存一直增加,解决方案

问题详细说明

        我在开发一个H5项目在线代码编辑页面,需要一个预览窗口可以随时更新H5内容的变化。我采用的是通过iframe.contentWindow.document.write来进行内容更新,确实达到了预期的目的,但是在后续的测试中发下,每次进行write操作内存就会增加,而却一直都不会释放,还会出现各种莫名其妙的错误(估计是变量冲突)

iframe.contentWindow.document.write导致的内存一直增加,解决方案

我以前的解决方案

        初始的iframe指向一个空白页面,通过iframe.reload()进行页面刷,然后通过监听iframe的onload事件,在onload事件中进行iframe.contentWindow.document.write。虽然多加载了一次空白页面但是也算是解决内存一直增加莫名其妙的报错问题。

  此方法的问题

   占用了页面onload事件,我将a.html的内容通过iframe.contentWindow.document.write方法写入iframe中,那么a.html中onload事件将无法触发,只会执行iframe父级页面中监听的onload事件。

最新的解决方案

        通过删除iframe后,重新动态添加iframe元素,这样就不用占用页面的onload事件了。

function clearIframe(){
    //删除iframe
    iframe.src = ‘about:blank‘;
    iframe.contentWindow.document.write(‘‘);
    iframe.contentWindow.document.close();
    iframe.parentNode.removeChild(iframe);
    //创建新的iframe
    iframe = document.createElement(‘iframe‘);
    iframe.src = "./null.html";
    iframe.unselectable="on";
    iframe.name="container";
    iframe.id="container";
    //添加到原来的iframe位置  
    document.getElementById("mapContent").appendChild(iframe);
}

遇到的其他问题

  编辑的项目文件能够通过http或https访问情况:

  1. 写入iframe中的内容使用到相对路径的情况,需要解决iframe解析相对路径是以它自身src为基准来进行解析的问题。

    通过增加<base href="url">标签来解决,这样iframe就已url作为基准路径来解析相对路径了。

  

  编辑的项目文件不能访问:

  2. 写入iframe中的内容使用到了相对路径,需要解决相对路径转化为数据接口问题。

    通过正则表达式将相对路径全部解析出来,然后进行文件解析相对路径中的文件对应的数据,将相对路径转换为数据接口。

  js版:

//相对路径转换
function relPath(htmlStr){
    var reg = new RegExp("([‘|\"| \( ])(\\.{0,2}/?)+[a-zA-Z0-9-_\\./]+\\.[a-zA-Z]{1,6}([‘|\"|\)])", "ig");
    let jg = htmlStr.match(reg);
    if(jg){
      for(let u of jg){
          //去除 ‘ " 符号
          var reg = new RegExp("[‘\"\(\)]","g");
          u = u.replace(reg,"");
          let code = 通过文件相对路径获取文件唯一表示,根据自己业务而定;
          if(code){
            //待优化, u可能与其他链接存在内容重合
             a = a.replace(u, "我的新url");
      }
    }
  }
}

  java版:

public String relPath(String content){
    StringBuffer sb = new StringBuffer(content);
    Pattern r = Pattern.compile("([‘|\"|\\(])(\\.{0,2}/?)+[a-zA-Z0-9-_\\./]+\\.[a-zA-Z]{1,6}([‘|\"|\\)])");
    Matcher m = r.matcher(sb);
    List<Map<String, Object>> strs = new ArrayList<>();
    while (m.find()) {
        Map<String, Object> str = new HashMap<>();
        String ss = m.group().substring(1, m.group().length() - 1);
        str.put("str", ss);
        str.put("start", m.start() + 1);//去除‘ "
        str.put("end", m.end() - 1);//去除‘ "
        strs.add(str);
    }
    
    for (Map<String, Object> str : strs) { //符合相对路径正则表达式的 字符串
    String urlFileId = "";//通过相对路径获取唯一标识,根据自己业务而定
    if (urlFileId != null) {
      int start = (int) str.get("start");
      int end = (int) str.get("end");
      String url = "我的新url";
      sb.replace(start - diff, end - diff, url);
      diff = diff + end - start - url.length();
    }
  }
}

 

iframe.contentWindow.document.write导致的内存一直增加,解决方案

上一篇:Win8.1 Metro应用无法联网终极解决方法


下一篇:C#使用RabbitMq队列 worke模式