【问题标题】:Updating page with "document.write" removes formatting使用“document.write”更新页面会删除格式
【发布时间】:2013-02-03 00:13:00
【问题描述】:

我一直想知道是否有办法防止我的函数隐藏任何当前文本/格式。

<body>
<script type="text/javascript">
document.body.style.backgroundColor = "#F5F0EB";
var page = 0
function flip(){
document.write(page);
page++;
}
</script>
<input type=button value="Next" onClick="flip()">
</body>

当我按下按钮时,我失去了彩色背景并出现了文字。有没有办法让背景保持不变并出现文字?

【问题讨论】:

  • 不要使用document.write
  • 在这种情况下我应该使用什么?
  • document.write 在 DOM 准备就绪后清除 DOM。

标签: javascript html


【解决方案1】:

是的,不使用document.write()MDN explains it clearly:

写入已加载但未调用的文档 document.open() 将自动执行 document.open 调用。

关于document.open()it says

如果目标中存在文档,则此方法将其清除。

应该做的是操作 DOM 中的节点。例如,您可以更改正文的内部 HTML:

document.body.innerHTML += page;

或者,您可以创建一个文本节点并附加它:

var textNode = document.createTextNode(page);
document.body.appendChild(textNode);

在这两种情况下,当前文档都不会被刷新,它只会被修改。

【讨论】:

  • +1,删除了示例引用,因为您没有添加示例... :)
  • @gdoron 谢谢,看来我复制粘贴的速度太快了。 :-P
【解决方案2】:

发生这种情况是因为您正在将非 html 写入应为 html 的文档。正如其他人所指出的,它也可能正在清除您现有的 html。您可能不想使用document.write,而是将新元素附加到您的文档中。

您可以使用document.createElement 函数和document.appendChild 函数来做到这一点。

以下是快速 Google 搜索返回的结果:

http://www.dustindiaz.com/add-and-remove-html-elements-dynamically-with-javascript/

【讨论】:

    【解决方案3】:

    您正在将页面写入覆盖整个 HTML 的文档。相反,将内容写入 DIV。

    这也应该可以解决您的背景颜色问题。

    这是JS Fiddle 的示例。

    <script type="text/javascript">
    document.body.style.backgroundColor = "#F5F0EB";
    var page = 0
    function flip(){
    document.getElementById("contentgoeshere").innerHTML=page;
    page++;
    }
    </script>
    <input type=button value="Next" onClick="flip()">
    <div id="contentgoeshere">
    </div>
    

    祝你好运。

    【讨论】:

      【解决方案4】:

      正如 Mattias Buelens 所解释的,document.write 调用了清除 DOM 的 open 方法,仅仅是因为 - 在加载之后 - 自动调用了 document.close 方法。当然,您可以使用许多替代方案。
      例如,使用body 元素的innerHTML 属性。
      使用document.createElementdocument.body.appendChild 也是一种选择

      但也许值得考虑的是,这两种方法都有其缺点:使用innerHTML 允许您将格式错误的标记注入 DOM,并且可能使您容易受到 XSS 攻击。
      使用document.createElement 速度较慢(通常)并且通常需要更多代码,这反过来会降低您的脚本的可维护性。

      你可以这样使用:

      var flip = (function(tempDiv)
      {//create a div once
          var page = 0,
          targetDiv = document.getElementById('contentgoeshere');//closure variables
          //page is now no longer an evil global, and the target element into which
          //we will inject new data is referenced, so we don't have to scan the DOM
          //on each function call
          return function(overridePage)//optional argument, just in case
          {//actual flip function is returned here
              overridePage = overridePage || page++;//new content
              tempDiv.innerHTML = overridePage;//render in div that isn't part of the DOM
              //any number of checks can go here, like:
              if (tempDiv.getElementsByTagName('script').length > 0)
              {
                  alert('Naughty client, trying to inject your own scripts to my site');
                  return;
              }
              targetDiv.innerHTML = tempDiv.innerHTML;
              //or, depending on your needs:
              targetDiv.innerHTML = tempDiv.innerText;//or the other way 'round
          };
      }(document.createElement('div')));
      

      一些旁注:就目前而言,这个函数将不起作用,因为必须完全加载 DOM 才能使闭包工作。一个快速的解决方法是:

      var flip;//undefined
      window.onload = function()
      {
          flip = (function(tempDiv)
          {
              var page = 0,
              targetDiv = document.getElementById('contentgoeshere');
              return function(e)
              {
                  tempDiv.innerHTML = e instanceof Event ? page++ : (e || page++);//ternary + logical or
                  //your [optional] checks here
                  targetDiv.innerHTML = tempDiv.innerHTML;
                  if (e instanceof Event)
                  {//this part is optional, but look it up if you want to: it's good stuff
                      e.returnValue = false;
                      e.cancelBubble = true;
                      if (e.preventDefault)
                      {
                          e.preventDefault();
                          e.stopPropagation();
                      }
                  }
                  return e;
              };
          }(document.createElement('div')));
          //instead of using the HTML onclick attribute:
          document.getElementById('buttonID').onclick = flip;//use as event handler
      };
      

      请注意,window.onload 会导致 IEcheck this link for the solution to this issue 上的内存泄漏

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-21
        • 2013-02-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多