【问题标题】:Print when textarea has overflow当 textarea 溢出时打印
【发布时间】:2023-04-05 10:41:01
【问题描述】:

我有一个带有一些文本区域的表单,当文本超出文本框时允许滚动条。用户希望能够打印屏幕,但此文本不可见。如何使所有文本仅用于打印?我最好打印到 pdf 链接之类的吗?

【问题讨论】:

  • 注意:接受的答案未经研究或测试,实际上是不正确的。不幸的是,没有纯 CSS 的跨浏览器解决方案,但有几种基于 JavaScript 的解决方法是可能的(我的回答建议两种,我在实践中都做过)。
  • Alan H,我接受了这个答案,因为它对我和我的环境都有效。我不需要跨浏览器解决方案和所有这些东西。你还没有给我举个例子。如果您想从我这里打勾,那么您必须在实践中向我展示您的解决方案。
  • 蒂莫西,一切都很好。但是,此页面不仅是为了您自己的利益,而且可能还有成百上千的其他开发人员。我猜他们中的大多数人确实更喜欢跨浏览器解决方案,并且只是通过指出上述内容来帮他们一个忙(而不是批评你)。
  • 我已更新我的答案以包含一个有效的 JavaScript 解决方案。

标签: html printing textarea


【解决方案1】:

不能单独使用 CSS 解决这个问题。

为什么纯 CSS 解决方案不足(附演示)

让我说服您涉及打印样式表和overflow: visible 的答案是不够的。打开this page 并查看源代码。正是他们的建议,对吧?现在打印预览它(例如,在 OS X 上的 Chrome 13 中,就像我一样)。请注意,当您尝试打印时,您只能看到一两行注释!

这是我的测试用例的 URL:https://alanhogan.github.io/web-experiments/print_textarea.html

解决方案:

  1. 一个 JavaScript 链接,它打开一个新窗口并将 textarea 的内容写入其中以进行打印。或者:

  2. 更新文本区域时,将其内容复制到另一个元素,该元素在屏幕上隐藏但在打印时显示。

  3. (如果您的textarea 是只读的,那么服务器端解决方案也是可行的。)

请注意textareas 对待空白的方式与默认情况下 HTML 不同,因此您应该考虑分别在打开的新窗口中应用 CSS white-space: pre-wrap; 或将 CSS div 应用到帮助程序 div。但是,IE7 和更早版本不理解 pre-wrap,所以如果这是一个问题,要么接受它,要么为他们使用解决方法。或者使弹出窗口实际上是纯文本,使用媒体类型text/plain(可能需要服务器端组件)提供。

“打印助手”解决方案(带代码+演示)

我创建了一个demo of one JavaScript technique

核心概念是将 textarea 内容复制到另一个打印助手。代码如下。

HTML:

<textarea name="textarea" wrap="wrap" id="the_textarea">
</textarea>
<div id="print_helper"></div>

CSS(全部/非打印):

/* Styles for all media */
#print_helper {
  display: none;
}

CSS(打印):

/* Styles for print (include this after the above) */
#print_helper { 
    display: block;
    overflow: visible;
    font-family: Menlo, "Deja Vu Sans Mono", "Bitstream Vera Sans Mono", Monaco, monospace;
    white-space: pre;
    white-space: pre-wrap;
}
#the_textarea {
  display: none;
}

Javascript(使用 jQuery):

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
jQuery(function($){
  function copy_to_print_helper(){
    $('#print_helper').text($('#the_textarea').val());
  }
  $('#the_textarea').bind('keydown keyup keypress cut copy past blur change', function(){
    copy_to_print_helper(); // consider debouncing this to avoid slowdowns!
  });
  copy_to_print_helper(); // on initial page load
});
</script>

同样,成功基于 JavaScript 的演示位于 https://alanhogan.github.io/web-experiments/print_textarea_js.html

【讨论】:

  • 你能给我一个如何在javascript中使用它的例子吗?这对我的帮助会更大。
  • Javascript 不是必需的。它可以用纯CSS来完成。不过还是有点脖子疼。看我的回答。
  • @GordonM 您的“纯 CSS”答案需要 PHP,并且不允许用户在打印前编辑 textarea 的情况。
  • 很好的答案,更重要的是,它非常适用于 javascript 数据绑定框架,例如 angular 和 ember。
  • @EduardoMolteni 非常感谢您让我知道。 Dropbox 停止允许通过其服务提供网页;我更新了上面的 URL 以指向我之前设置的 GitHub Pages 站点作为替代。 (他们现在应该可以工作了!)
【解决方案2】:

遍历每个文本区域并将内容移动到一个持有人

    window.onbeforeprint = function () {
        $('.print-content').remove();
        $('textarea').each(function () {
            var text = $(this).val();
            $(this).after('<p class="well print-content">' + text + '</p>');
        });
    }

并使用以下 CSS

.print-content {
  display: none !important;
}

@media print {
  .print-content {
    display: block !important;
  }
  textarea {display: none !important;}
}

【讨论】:

    【解决方案3】:

    我最近遇到了同样的问题。我的解决方案是将内容复制到用于编辑的表单控件和用于打印的 div 中。

    在我的头脑中,我放了一个打印样式表。

    <link rel="stylesheet" href="printform.css" type="text/css" media="print" />
    

    在 printform.css 我放了以下

    .screenOnly { display: none; }
    .printOnly { display: inline-block; }
    

    对于 textareas(和其他导致问题的字段类型),我使用了以下代码

    <textarea class="screenOnly" name="myTextArea"><?php echo (htmlspecialchars ($_POST ['myTextArea'])); ?></textarea>
    <div class="printOnly"><?php echo (htmlspecialchars ($_POST ['myTextArea'])); ?></div>
    

    当显示在屏幕上时,会显示文本区域,并且隐藏复制其内容的 div。打印时则相反。

    我知道您已经选择了这个问题的答案,但是虽然使用打印样式表是个好主意,但它并没有描述具体的解决方案。在 textarea 上设置溢出:可见(我的第一个想法)不起作用,所以我最终选择了上面的解决方案。如果您仍然遇到困难,我希望这对您有所帮助

    【讨论】:

    • 如果您要使用 PHP 再次回显其内容,然后假设用户在打印之前不会对其进行编辑,那么使用 textarea 的意义何在?虽然这种技术可能有用,但我认为您不应该将您的解决方案作为“纯 CSS”出售,因为它假定 PHP 和一个狭窄的、不太可能的用例。
    • 示例代码在 PHP 中,因为它必须在某些东西中。在大多数用于网络脚本的语言中应该可以做类似的事情。是的,这种技术确实有局限性,但是因为你不能溢出:可见文本区域,所以总是需要做出一些妥协。我想如果您需要在提交到服务器之前打印出一个表单,您还可以添加一些 javascript 以将 textareas 与它们各自的 div 同步。但是,这会添加一个 javascript 依赖项,因此如果 js 关闭,它将无法工作。
    【解决方案4】:

    最近也解决了这个问题。感谢艾伦 H 的帖子。它与 Chrome 和 Safari 完美搭配。但是,在 IE 和 Firefox 中,问题是最后几页(textarea 之后的页面元素)将丢失打印(FF)、丢失页面和重叠布局(IE9)。

    另一个有助于解决该问题的发现是,您可以正确设置 textarea 的 rows 属性,因为控件的高度表明它可以与 CSS overflow:visable 一起使用。所有浏览器在打印时似乎都尊重 rows 属性。

    【讨论】:

      【解决方案5】:

      这似乎适用于所有内容溢出的元素:

      $("textarea").each(function () {
          var Contents = $(this).val();
          if ($(this)[0].scrollHeight > $(this).height()) {
              $(this).after("<div class='print-helper'>" + Contents + "</div>");
              $(this).addClass("no-print");
          }
      });
      

      【讨论】:

        【解决方案6】:

        这是一个简单的 CSS 解决方案,因为大多数用户并不真正为打印一些额外的空白空间而烦恼。打印时只针对文本区域的最小高度:

        @media print { 
        textarea {
        min-height: 500px;  
        }
        }
        

        将其标记到 CSS 的末尾,并使用当您在打印预览中查看时足够舒适的最小高度。

        【讨论】:

          【解决方案7】:

          使用纯 CSS 无法准备 textarea 进行打印。

          需要在文本区域添加一些javacript魔法或者添加隐藏字段。

          这里提到了几个解决方案:

          1. 隐藏段落或 div
          2. 使用 Javascript 扩展文本区域的大小

          1.隐藏段落或 div

          HTML 和 CSS:

          <textarea>Sample Text</textarea>
          <div class="hidden-div">Sample Text</div>
          
          <style>
            .hidden-div{display: none;}
            @media print{
              .hidden-div{display:block;}
            }
          </style>
          

          2。 Javascript

          您可以使用 js 库,例如 https://github.com/thomasjo/jquery-autoresize

          $(function() {
              $("textarea").autoResize()
          })
          

          【讨论】:

            【解决方案8】:

            添加到上面的Alan's 答案,如果您在同一页面上有多个此问题的实例,那么您可以使用 data-* 属性一次处理所有问题。示例:

            var $printOnlyArr = $('.print-only');
            for (var i = 0; i < $printOnlyArr.length; i++) {
              var $printOnly = $($printOnlyArr[i]);
            	var textSource = $printOnly.data('textsource');
            	if (textSource) {
            	  $printOnly.text($("#" + textSource).val());
            	}
            }
            .print-only {
            	display: none;
            }
            
            @media print {
            	.print-only {
            		display: block;
            	}
            	.no-print {
            		display: none;
            	}
            }
            <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
            <textarea class="form-control no-print" maxlength="2000" id="txtAdditionalComments"></textarea>
            <div class="print-only" data-textsource="txtAdditionalComments"></div>

            【讨论】:

              【解决方案9】:

              我遇到了同样的问题。我的项目是 React,我是一个 semnaticUi TextArea 组件。当我按下打印屏幕按钮时,无法在打印视图中看到只能通过在 Textarea 中向下滚动才能看到的文本,也就是“溢出”。

              解决方案 :)

              我只是使用了一个普通的段落标签,并在包含 p 标签的 div 上设置了 css white-space: pre-wrap

              为我工作!

              【讨论】:

                【解决方案10】:

                使用 jQuery 试试这个。根据行数重新定义所有文本区域的高度。

                注意:这段代码也改变了屏幕上的文本区域

                window.onbeforeprint = function () {
                    $('textarea').each(function () {
                        var lines = Math.round($(this).val().split('\n').length * 1.6) ; //multiply to 1.6 to consider spacing between lines
                        $(this).height(lines+'em');
                    });
                }
                

                【讨论】:

                  【解决方案11】:

                  为像&lt;link rel="stylesheet" href="print.css" type="text/css" media="print" /&gt;这样的打印媒体定义一个单独的CSS,对于文本区域,定义溢出属性为

                  overflow: visible;
                  

                  【讨论】:

                  • 看来,这个答案和作为解决方案接受的答案是一样的。
                  【解决方案12】:

                  我在我的造型中使用这个:

                  PRE.print {
                  display:none;
                  }
                  
                  @media print {
                  
                    TEXTAREA {
                      display:none;
                    }
                  
                    PRE.print {
                      display:block;
                      width:90%; /* fixes margin issues in some funky browsers */
                      white-space: pre-wrap;       /* css-3 */
                      white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
                      white-space: -pre-wrap;      /* Opera 4-6 */
                      white-space: -o-pre-wrap;    /* Opera 7 */
                      word-wrap: break-word;       /* Internet Explorer 5.5+ */
                      font-family:monospace,sans;
                    }
                  
                  }
                  

                  然后,在每个 TEXTAREA 之后,我使用带有“print”类的 PRE,如下所示:

                  <textarea id="message" name="message" rows="10" cols="80" onblur="updatePrint('#message')"><?= $MESSAGE ?></textarea>
                  <pre id="message-print" class="print">
                  <?= $MESSAGE ?>
                  </pre>
                  

                  ...请注意我使用的 PHP——您可以使用您的编程语言进行切换。然后上面的代码需要下面的函数,假设你已经加载了 jQuery 库:

                  <script type="text/javascript">
                  
                  function updatePrint(sID) {
                    $(sID + '-print').text($(sID)[0].value);
                  }
                  
                  </script>
                  

                  这一切的运作方式

                  这种工作方式是我基本上将内容两次加载到页面中,但使用样式表隐藏不适合像 TEXTAREA 这样的打印机的内容。

                  您可以根据需要更改 PRE 样式。但是,如果有人想要打印他们在字段中键入的 HTML 代码并希望它的格式很好,我会使用等宽字体。

                  onblur 事件有助于捕捉更新相关 PRE 的需求。

                  请注意,您还可以通过 HTML HEAD 部分中的链接 rel 上的 media 属性来处理样式表,使用诸如 media="all not print" 和 media="print" 之类的东西。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多