Twitter Bootstrap:打印模态窗口的内容

时间:2012-08-29 15:47:36

标签: javascript printing twitter-bootstrap modal-dialog

我正在使用Bootstrap开发一个站点,它有28个模态窗口,其中包含不同产品的信息。我希望能够在开放模式窗口中打印信息。每个窗口都有一个id

<!-- firecell panel & radio hub -->
           <div class="modal hide fade" id="fcpanelhub">
              <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">X</button>
                <h3>5000 Control Panel & Radio Hub</h3>
              </div>
              <div class="modal-body">
                <img src="../site/img/firecell/firecell-panel-info-1.png" alt=""/><hr/>
                <img src="../site/img/firecell/firecell-panel-info-2.png" alt=""/><hr/>
                <img src="../site/img/firecell/firecell-radio-hub-info-1.png" alt=""/><hr/>
                <img src="../site/img/firecell/firecell-radio-hub-info-2.png" alt=""/>
              </div>
              <div class="modal-footer">
                <a href="#" class="btn" data-dismiss="modal">Close</a>
              </div>    
           </div>

因此,如果我在modal-footer - 'print'中添加一个新按钮,并且单击它我想要打印该模态。我会说javascript会被使用吗?如果是这样,我怎么告诉javascript只打印open模式,而不打印其他模式?

所有帮助表示赞赏。

11 个答案:

答案 0 :(得分:57)

另一种解决方案

以下是Bennett McElwee answer中基于same question的新解决方案,如下所述。

使用IE 9&amp; C测试10,Opera 12.01,谷歌Chrome 22和Firefox 15.0。
jsFiddle example

1。)将此CSS添加到您的站点:

@media screen {
  #printSection {
      display: none;
  }
}

@media print {
  body * {
    visibility:hidden;
  }
  #printSection, #printSection * {
    visibility:visible;
  }
  #printSection {
    position:absolute;
    left:0;
    top:0;
  }
}

2.)添加我的JavaScript函数

function printElement(elem, append, delimiter) {
    var domClone = elem.cloneNode(true);

    var $printSection = document.getElementById("printSection");

    if (!$printSection) {
        $printSection = document.createElement("div");
        $printSection.id = "printSection";
        document.body.appendChild($printSection);
    }

    if (append !== true) {
        $printSection.innerHTML = "";
    }

    else if (append === true) {
        if (typeof (delimiter) === "string") {
            $printSection.innerHTML += delimiter;
        }
        else if (typeof (delimiter) === "object") {
            $printSection.appendChild(delimiter);
        }
    }

    $printSection.appendChild(domClone);
}​

您已准备好在您的网站上打印任何元素!
只需使用您的元素调用printElement(),并在完成后执行window.print()

注意: 如果您想在打印之前修改内容(并且仅在打印版本中),请查看此示例(由评论中的waspina提供):http://jsfiddle.net/95ezN/121/

也可以使用CSS来显示打印版本中的其他内容(仅在那里)。


以前的解决方案

我认为,您必须通过CSS隐藏网站的所有其他部分。

将所有不可打印的内容移到单独的DIV中是最好的:

<body>
  <div class="non-printable">
    <!-- ... -->
  </div>

  <div class="printable">
    <!-- Modal dialog comes here -->
  </div>
</body>

然后在你的CSS中:

.printable { display: none; }

@media print
{
    .non-printable { display: none; }
    .printable { display: block; }
}

积分转至Greg已回答类似问题的人:Print <div id="printarea"></div> only?

使用JavaScript时出现一个问题:用户无法看到预览 - 至少在Internet Explorer中是这样!

答案 1 :(得分:8)

我建议你试试这个jQuery插件print element

它可以让您只打印您选择的元素。

答案 2 :(得分:8)

使用当前接受的解决方案,您无法打印包含对话框本身的页面。这是一个更加动态的解决方案:

JavaScript的:

$().ready(function () {
    $('.modal.printable').on('shown.bs.modal', function () {
        $('.modal-dialog', this).addClass('focused');
        $('body').addClass('modalprinter');

        if ($(this).hasClass('autoprint')) {
            window.print();
        }
    }).on('hidden.bs.modal', function () {
        $('.modal-dialog', this).removeClass('focused');
        $('body').removeClass('modalprinter');
    });
});

CSS:

@media print {
    body.modalprinter * {
        visibility: hidden;
    }

    body.modalprinter .modal-dialog.focused {
        position: absolute;
        padding: 0;
        margin: 0;
        left: 0;
        top: 0;
    }

    body.modalprinter .modal-dialog.focused .modal-content {
        border-width: 0;
    }

    body.modalprinter .modal-dialog.focused .modal-content .modal-header .modal-title,
    body.modalprinter .modal-dialog.focused .modal-content .modal-body,
    body.modalprinter .modal-dialog.focused .modal-content .modal-body * {
        visibility: visible;
    }

    body.modalprinter .modal-dialog.focused .modal-content .modal-header,
    body.modalprinter .modal-dialog.focused .modal-content .modal-body {
        padding: 0;
    }

    body.modalprinter .modal-dialog.focused .modal-content .modal-header .modal-title {
        margin-bottom: 20px;
    }
}

示例:

<div class="modal fade printable autoprint">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title">Modal title</h4>
      </div>
      <div class="modal-body">
        <p>One fine body&hellip;</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary" onclick="window.print();">Print</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

答案 3 :(得分:6)

这是一个选项,使用我在接受的答案的评论中根据waspinator的代码制作的JQuery扩展:

jQuery.fn.extend({
    printElem: function() {
        var cloned = this.clone();
        var printSection = $('#printSection');
        if (printSection.length == 0) {
            printSection = $('<div id="printSection"></div>')
            $('body').append(printSection);
        }
        printSection.append(cloned);
        var toggleBody = $('body *:visible');
        toggleBody.hide();
        $('#printSection, #printSection *').show();
        window.print();
        printSection.remove();
        toggleBody.show();
    }
});

$(document).ready(function(){
    $(document).on('click', '#btnPrint', function(){
        $('.printMe').printElem();
    });
});

JSFiddle:http://jsfiddle.net/95ezN/1227/

如果您不想将其应用于每个打印件并且只是在自定义打印按钮上执行此操作(这是我的情况),这将非常有用。

答案 4 :(得分:4)

这是一个经过修改的解决方案,也适用于使用Grails模板渲染的模态窗口,您可以在同一个主体中使用相同的模式模板多次调用(具有不同的值)。这个帖子对我帮助很大,所以我想我会分享它,以防其他Grails用户在这里找到他们的方式。

对于那些好奇的人来说,接受的解决方案对我不起作用,因为我正在渲染一张桌子;每行都有一个按钮,打开一个模态窗口,其中包含有关该记录的更多详细信息。这导致创建多个printSection div并将它们打印在彼此之上。因此,我必须修改js以在打印完成后清理它。

CSS

我将这个CSS直接添加到我的模态gsp中,但将其添加到父级具有相同的效果。

template: "<li data-bind='html: vm.message'>vm.onChangeElement</li>"

将其添加到网站范围内的CSS会破坏网站其他部分的打印功能。我从ComFreak接受的答案(基于Bennett McElwee answer)得到了此答案,但是使用fanfavoritePrint <div id=printarea></div> only?的答案中使用':not'功能进行了修订。我选择了“显示”而不是“可见度”,因为我看不见的正文内容正在创建额外的空白页面,这对我的用户来说是不可接受的。

JS

这是我的javascript,修改自ComFreak对此问题的接受答案。

function getProperties($object) {
    $properties = array();
    try {
        $rc = new \ReflectionClass($object);
        do {
            $rp = array();
            /* @var $p \ReflectionProperty */
            foreach ($rc->getProperties() as $p) {
                $p->setAccessible(true);
                $rp[$p->getName()] = $p->getValue($object);
            }
            $properties = array_merge($rp, $properties);
        } while ($rc = $rc->getParentClass());
    } catch (\ReflectionException $e) { }
    return $properties;
}

我不需要添加元素,因此我删除了该方面并更改了函数以专门打印div。

HTML(gsp)

和模态模板。这将打印模态标题&amp;正文和排除按钮所在的页脚。

<style type="text/css">
   @media screen {
        #printSection {
           display: none;
        }
   }

   @media print {
        body > *:not(#printSection) {
           display: none;
        }
        #printSection, #printSection * {
            visibility: visible;
        }
        #printSection {
            position:absolute;
            left:0;
            top:0;
        }
   }
</style>

我希望能帮助别人!

答案 5 :(得分:3)

我只是使用了一些jQuery / javascript:

HTML:

<h1>Don't Print</h1>

<a data-target="#myModal" role="button" class="btn" data-toggle="modal">Launch modal</a>

<div class="modal fade hide" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"      aria-hidden="true">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
     <h3 id="myModalLabel">Modal to print</h3>
  </div>
  <div class="modal-body">
    <p>Print Me</p>
  </div>
  <div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
    <button class="btn btn-primary" id="printButton">Print</button>
  </div>
</div>

JS:

$('#printButton').on('click', function () {
    if ($('.modal').is(':visible')) {
        var modalId = $(event.target).closest('.modal').attr('id');
        $('body').css('visibility', 'hidden');
        $("#" + modalId).css('visibility', 'visible');
        $('#' + modalId).removeClass('modal');
        window.print();
        $('body').css('visibility', 'visible');
        $('#' + modalId).addClass('modal');
    } else {
        window.print();
    }
});

这里是the fiddle

答案 6 :(得分:0)

这是一个没有Javascript或插件的解决方案 - 在标记中只有一些css和一个额外的类。 此解决方案使用BootStrap在打开对话框时向正文添加类的事实。我们使用此类隐藏正文,并仅打印对话框。

为确保我们能够确定页面的主体,我们需要在div中包含主页内容中的所有内容 - 我使用了id =“mainContent”。下面的示例页面布局 - 带有主页面和两个对话框

<body>
 <div class="container body-content">

  <div id="mainContent">
       main page stuff     
  </div>
  <!-- Dialog One -->
  <div class="modal fade in">
   <div class="modal-dialog">
    <div class="modal-content">
          ...
    </div>
   </div>
  </div>

  <!-- Dialog Two -->
  <div class="modal fade in">
   <div class="modal-dialog">
    <div class="modal-content">
          ...
    </div>
   </div>
  </div>

 </div>
</body>

然后在我们的CSS打印媒体查询中,我使用display:none隐藏我不想显示的所有内容 - 即打开对话框时的mainContent。我还使用特定的类noPrint在页面的任何不应显示的部分上使用 - 比如操作按钮。在这里,我也隐藏了页眉和页脚。您可能需要调整它以获得您想要的确切。

@media print {
    header, .footer, footer {
        display: none;
    }

    /* hide main content when dialog open */
    body.modal-open div.container.body-content div#mainContent {
        display: none;
    }

    .noPrint {
        display: none;
    }
}

答案 7 :(得分:0)

我面临两个问题 问题1:所有领域都是一个接一个地出现 当用于从弹出窗口打印时,在页面底部发出2个空格。

我通过

解决了这个问题

对所有正文*元素进行显示无,其中大多数都会隐藏可见性,从而创建空间以避免隐藏可见性

    @media print {
        body * {
           display:none;
        width:auto;
        height:auto;
        margin:0px;padding:0px; 
        }
        #printSection, #printSection * {
            display:inline-block!important;
        }
        #printSection {
            position:absolute;
            left:0;
            top:0;  
            margin:0px; 
            page-break-before: none;
            page-break-after: none;
            page-break-inside: avoid;      
        }
#printSection .form-group{

      width:100%!important;
      float:left!important;
      page-break-after: avoid;
    }
#printSection label{
        float:left!important;
        width:200px!important;
        display:inline-block!important;
      }

#printSection .form-control.search-input{
        float:left!important;
        width:200px!important;
        display: inline-block!important;
      }
}

答案 8 :(得分:0)

您可以从此源下载printThis lib https://github.com/jasonday/printThis/blob/0a7f799693af8a8303bf0b8df0efc80c2694af81/printThis.js 并将其包含到您的html页面

调用以下jquery打印所有内容,包括不可见的内容。如果您有多个css文件,则可以在数组中包含css文件。

var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

public static IWebHost BuildWebHost(string[] args) =>
  WebHost
    .UseConfiguration(new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())

    .AddJsonFile($"appsettings.json", true, true)
    .AddJsonFile($"appsettings.{environmentName}.json", true, true)

    .Build()
  )
  .UseStartup<Startup>()
  .Build();

答案 9 :(得分:0)

所以我有一个 React 应用程序,它作为一个 webcomponent 存在于多个遗留站点上。这些解决方案都不是我正在寻找的。接受的答案有缺点。假设我们有这个 CSS:

@media print {
  body * {
    visibility:hidden;
  }
  #printSection, #printSection * {
    visibility:visible;
  }
  #printSection {
    position:absolute;
    left:0;
    top:0;
  }
}

body * {visibility : hidden} 将阻止用户按 CTRL+P 打印页面。

这也没有考虑到多个打印 UX 工作流程,以防用户可能需要从位于同一页面上的模态和抽屉打印页面。这是一种罕见的情况,但同样没有考虑到

解决办法

我选择的解决方案是在主体上应用顶级 CSS 类。在我的 React Modal 组件中,我使用了 useEffect 调用

import React, { useEffect } from 'react'

export const ModalPane = (props) => {
  useEffect(() => {
    const body = document.querySelector('body')
    if (body) {
      body.classList.add('hide-on-print')
    }
    return () => {
      if (body) {
        body.classList.remove('hide-on-print')
      }
    }
  }, [])

  const handlePrint = () => {
    // add any prework or analytics tracking here etc
    window.print()
  }

  return (
    <div className="print-me">
      <h1>Modal content stuff here</h1>
      <button type="button" onClick={handlePrint}>Print</button>
    </div>
  )
}

一旦这个模态被渲染(也就是用户正在查看预期的模态),只会打印模态的内容。他们是按下打印按钮还是按下 CTRL+P 都没有关系

这会在 body 元素上应用一个名为 hide-on-print 的类。然后应用此媒体样式,该样式专门针对此打印 UX 实例(您可以为其他特定打印查询向正文添加更多类)

@media print {
  body.hide-for-print {
    visibility: hidden !important;
  }
  body.hide-for-print .print-me {
    visibility: visible;
  }
}

TLDR

使用仅在呈现时应用 hide-for-print 类的 react useEffect 组件。将@print 媒体查询包装在此类后面。这可以处理所有预期的 UX 打印用例,并且可以扩展到任何其他特定的打印 UX 用例

答案 10 :(得分:-1)

@media print{
	body{
		visibility: hidden; /* no print*/
	}
	.print{
		
		visibility:visible; /*print*/
	}
}
<body>
  <div class="noprint"> <!---no print--->
  <div class="noprint"> <!---no print--->
  <div class="print">   <!---print--->
  <div class="print">   <!---print--->


</body>