代码之家  ›  专栏  ›  技术社区  ›  Jeff Atwood

为什么IE7不能将<pre><code>块正确复制到剪贴板?

  •  37
  • Jeff Atwood  · 技术社区  · 17 年前

    我们注意到IE7有一个奇怪的行为,代码块发布在堆栈溢出上。例如,这个小代码块:

    public PageSizer(string href, int index)
    {
        HRef = href;
        PageIndex = index;
    }
    

    public PageSizer(string href, int index){    HRef = href;    PageIndex = index;    }
    

    <pre><code>public PageSizer(string href, int index)
    {
        HRef = href;
        PageIndex = index;
    }
    </code></pre>
    

    那么,我们做错了什么?为什么IE7不能以理性的方式复制和粘贴这个HTML?

    更新: 这特别与 <pre> <code> 在运行时通过JavaScript修改的块。 本机HTML确实正确呈现和复制;这是该HTML的JavaScript修改版本,其行为不符合预期。请注意,复制和粘贴到WordPad或Word中是有效的,因为IE在富文本剪贴板中放置的内容与记事本从中获取数据的纯文本剪贴板不同。

    7 回复  |  直到 17 年前
        1
  •  35
  •   Andrew Johnson    17 年前

    这似乎是IE6的一个已知错误,而prettify.js有一个解决方法。具体来说,它将BR标记替换为“\r\n”。

    通过修改检查以允许IE6或IE7,则剪切和粘贴将从IE7正常工作,但它将使用 新线 接着是 空间 . 通过检查IE7并仅提供“\r”而不是“\r\n”,它将继续正确剪切、粘贴和渲染。

    将以下代码添加到prettify.js:

    function _pr_isIE7() {
      var isIE7 = navigator && navigator.userAgent &&
           /\bMSIE 7\./.test(navigator.userAgent);
      _pr_isIE7 = function () { return isIE7; };
      return isIE7;
    }
    

    然后修改prettyPrint函数,如下所示:

       function prettyPrint(opt_whenDone) {
         var isIE6 = _pr_isIE6();
    +    var isIE7 = _pr_isIE7();
    

    ...

    -        if (isIE6 && cs.tagName === 'PRE') {
    +        if ((isIE6 || isIE7) && cs.tagName === 'PRE') {
              var lineBreaks = cs.getElementsByTagName('br');
    +         var newline;
    +         if (isIE6) {
    +           newline = '\r\n';
    +         } else {
    +           newline = '\r';
    +         }
              for (var j = lineBreaks.length; --j >= 0;) {
                var lineBreak = lineBreaks[j];
                lineBreak.parentNode.replaceChild(
    -               document.createTextNode('\r\n'), lineBreak);
    +               document.createTextNode(newline), lineBreak);
              }
    

    你可以看到一个 working example here .

        2
  •  13
  •   Community Mohan Dere    9 年前

    问题是:

    代码着色脚本将换行符替换为<br/>标签。复制/粘贴时,IE7显然不会翻译<br/>标记为换行符,就像在屏幕上标记一样。

    换句话说,您的代码如下所示:

    public PageSizer(string href, int index)<br />{<br />    HRef = href;<br />    PageIndex = index;<br />    }

    但你希望它变成这样:

    
    public PageSizer(string href, int index)<br />
    {<br />
        HRef = href;<br />
        PageIndex = index;<br />
    }<br />
    

    
    html.push(htmlChunk.replace(newlineRe, '<br />'));
    


    对于IE7,这可能是该行应该更改为:

    
    html.push(htmlChunk.replace(newlineRe, '\n'));
    

    (假设newlineRe是占位符)。

    这个补丁也适用于Chrome和FFX3。。。我不确定哪些(如果有的话)浏览器需要<br/>标签。

    更新: 我在第二次答复中提供了更多信息:
    Why doesn't IE7 copy <pre><code> blocks to the clipboard correctly?

        3
  •  2
  •   Evan Shaw    17 年前

    这看起来像IE中的一个bug, 之前 密码 .

    为代码着色的美化脚本将删除 全部的 删除空格,并将其替换为空格和新行的HTML标记。生成的代码如下所示:

    <pre><code>code<br/>&nbsp;&nbsp;code<br/>&nbsp;&nbsp;code<br/>code</code></pre>
    

    这个 之前 默认情况下,标记以CSS样式呈现 . 在这种情况下,IE未能将 标记为换行符。它将在您的原始HTML上工作,因为IE将成功地将实际的换行符转换为换行符。

    为了修复它,您有3个选项。(我想你想要漂亮的HTML 在客户端启用或不启用javascript的情况下都能正常工作):

    1. {空白:pre} . 这是一个简单的解决方案,尽管可能不会让HTML标记纯粹主义者满意。

    2. 您可以有两个代码副本,一个使用正确的 之前 / 在CSS中隐藏普通div。使用javascript美化普通div并隐藏pre/code版本。

    3. 之前 元素,在该事件中不替换空格。


    笔记:

    • 重要的不是源代码中的HTML,而是在美化脚本运行后生成的HTML。

    • 此错误仍然存在,即使 之前 使用CSS。

        4
  •  1
  •   jlo    14 年前

    http://www.developerfusion.com/tools/convert/csharp-to-vb/

    此按钮将以纯文本形式复制显示信息的版本。 纯文本可以存储为内部页面属性。

        5
  •  0
  •   Jeff Atwood    17 年前

    坏消息:提议的修复方案都不起作用。修改第1000行附近的prettify.js

    html.push(htmlChunk.replace(newlineRe, '\n'));
    

    这会在其他浏览器中造成两倍间距,并且 无法解决IE7复制到记事本的问题!所以,即使我选择性地检测到IE7,这个“修复”也不能修复任何东西。

    我想这可能只是IE7中的一个bug,它与JavaScript重建 <pre>

        6
  •  0
  •   AaronSieb    17 年前

    @杰夫·阿特伍德

    
    // Replace <br>s with line-feeds so that copying and pasting works
    // on IE 6.
    // Doing this on other browsers breaks lots of stuff since \r\n is
    // treated as two newlines on Firefox, and doing this also slows
    // down rendering.
    

    至少,IE7似乎需要\r\n,而不仅仅是\r\n。弄清楚哪些浏览器可以工作,需要比我现在手头上更广泛的测试设置。

    无论如何,基本上需要为IE7插入\r\n。我会不停地在“美化”上翻来翻去,看看能不能再缩小范围。

    更新: IE7似乎从分配给innerHTML属性的字符串中删除换行符(\r或\n)。看起来它们需要重新添加到1227行附近。

        7
  •  -1
  •   Armin Ronacher    17 年前

    拆下内盖 <code> . IE的复制/粘贴行为可以将其视为内联标记,而忽略可见的空白。