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

IT技术 javascript printing twitter-bootstrap modal-dialog
2021-02-21 23:25:44

我正在使用 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“打印”中添加一个新按钮,然后单击它,我希望打印该模态。我说 javascript 会被使用是对的吗?如果是这样,我如何告诉 javascript 只打印打开的模式,而不是其他模式?

所有帮助表示赞赏。

6个回答

另一种解决方案

这是基于Bennett McElwee下面提到同一问题中回答的新解决方案

使用 IE 9 & 10、Opera 12.01、Google Chrome 22 和 Firefox 15.0 进行测试。
jsFiddle 示例

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已经回答了一个类似的问题:仅打印 <div id="printarea"></div>?

使用 JavaScript存在一个问题:用户无法看到预览 - 至少在 Internet Explorer 中!

@BennettDill你可以添加一个类<BODY>通过JavaScript如果当前显示的模式:if (modalShown) { body.classList.add('printModal'); }然后,您添加body.printModal到 CSS 规则中,因此它们仅在您实际打印模态对话框时生效。
2021-04-20 23:25:44
但是,如果您在原始可打印区域上有一个带有可打印区域的模态弹出窗口呢?
2021-04-30 23:25:44
@waspinator 调用printElement(yourContainer);,修改您的子元素并最终调用window.print(). printElement()仅准备打印过程,但不会触发打印本身。
2021-05-02 23:25:44
@MattSull87 我添加了另一个解决方案 - 这应该会更好!这是一个例子:jsfiddle.net/95ezN/1
2021-05-06 23:25:44
@waspinator 我的“打印”元素(您提供给的元素printElement())及其子元素没什么特别的。只需使用getElementById()querySelector[All]()
2021-05-07 23:25:44

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

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/

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

这很好用。也可以按元素 ID 选择。
2021-04-21 23:25:44

我建议你试试这个 jQuery 插件打印元素

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

好的,它现在工作正常!那是因为 GitHub 没有发送正确的 MIME 类型,然后 IE 10 会阻止脚本。在这里工作 jsFiddle
2021-04-26 23:25:44
真的吗 ?我还没有尝试过 IE10,但它不适用于 IE10 听起来很奇怪。我在 IE7-9 上使用它没有问题。您是否在其他浏览器上尝试过以确保不会错过其他内容?
2021-05-01 23:25:44
恕我直言,这是最好的解决方案,减少了麻烦和代码添加。只需在您的 javascript 之后包含此文件code.jquery.com/jquery-migrate-1.0.0.js以避免浏览器错误。
2021-05-03 23:25:44
网站上的样品并没有对我的IE 10(Windows 8的RTM)工作。
2021-05-15 23:25:44
使用 printElement 时,请确保设置 popup-setting 以便它不会使用 iFrame,因为根据我的经验,它在 IE 中无法正常工作。 $(elementToPrintId).printElement({printMode: 'popup'});
2021-05-15 23:25:44

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

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 -->
@Massa,我也在与此作斗争。似乎问题position: fixed出在模态的 。我找到的解决方案是,在打印时,将模态的位置更改为absolute 设置bottom: auto.
2021-04-20 23:25:44
嗨,您的解决方案很好,但就我而言,我的模态内容高于后页高度,因此,在打印视图中,我的模态内容被部分剪切。你有什么解决办法吗?示例:打印版本需要 2 页所有模态内容,但它只考虑一页(因为背景“主体”页面的高度)。
2021-04-22 23:25:44
@Massa:您是否找到了将模态内容打印到多个页面的解决方案。
2021-05-14 23:25:44

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

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

CSS

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

<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>

将它添加到站点范围的 CSS 中会杀死站点其他部分的打印功能。我从ComFreak接受的答案中得到了这个(基于Bennett McElwee 的答案),但它是使用 ':not' 功能从fanfavorite 's answer on Print <div id=printarea></div> 修改的?. 我选择了“显示”而不是“可见性”,因为我的不可见正文内容会创建额外的空白页面,这是我的用户无法接受的。

js

这对于我的 javascript,从ComFreak对这个问题的公认答案进行了修改。

function printDiv(div) {    
    // Create and insert new print section
    var elem = document.getElementById(div);
    var domClone = elem.cloneNode(true);
    var $printSection = document.createElement("div");
    $printSection.id = "printSection";
    $printSection.appendChild(domClone);
    document.body.insertBefore($printSection, document.body.firstChild);

    window.print(); 

    // Clean up print section for future use
    var oldElem = document.getElementById("printSection");
    if (oldElem != null) { oldElem.parentNode.removeChild(oldElem); } 
                          //oldElem.remove() not supported by IE

    return true;
}

我不需要附加元素,所以我删除了那个方面并将函数更改为专门打印一个 div。

HTML (gsp)

和模态模板。这将打印模态页眉和正文并排除按钮所在的页脚。

<div class="modal-content">
    <div id="print-me"> <!-- This is the div that is cloned and printed -->
        <div class="modal-header">
            <!-- HEADER CONTENT -->
        </div>
        <div class="modal-body">
             <!-- BODY CONTENT -->
        </div>
    </div>
    <div class="modal-footer">
                                 <!-- This is where I specify the div to print -->
        <button type="button" class="btn btn-default" onclick="printDiv('print-me')">Print</button>
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    </div>
</div>

我希望能帮助别人!

@Hairgami_Master 很高兴能帮到你!我花了很长时间才开始工作,所以不分享是错误的。
2021-04-18 23:25:44
谢谢卡拉!这个解决了我遇到的一个棘手问题。此外,如果您取消打印功能,然后再次尝试打印,@comFreek 的解决方案会导致我出错(不是他的代码,这是 Angular 的事情)。
2021-04-25 23:25:44