1

When a user chooses "File > Print" on a browser such as Firefox or Internet Explorer, or clicks on a link that runs the below javascript

window.print();

Is there a way to conditionally check for this mode and disable SOME javascript.

I am trying to do this because I have a plugin that adds in its own custom markup for rounded borders and even in a print specific stylesheet I can not override the styling for these, I dont want the borders to appear when printing out the page.

EDIT: Unrelated to the plugin there are style changes done via javascript that is used to create a tabbed user interface and I have done print specific CSS to override the styling and it works fine when I use the Firefox web developer toolbar > CSS > Display CSS by Media type > Print.. but when I print it out it doesn't work, the javascript takes over and changes the styling.. if I disable javascript completely then the printing obviously works fine again.

Thanks

Pricey
  • 5,799
  • 12
  • 60
  • 84
  • 1
    Why can't you just display:none in the print specific stylesheet ? – Julien Roncaglia Sep 01 '10 at 15:20
  • I have tried already, the nodes are not standard and the display:none !important; css changed nothing. – Pricey Sep 01 '10 at 15:24
  • @Pricey: you probably don't have this problem any more, but I thought I would let you know that modern browsers have a better solution. See my answer below for details. – Andy E Jan 15 '13 at 21:43

2 Answers2

19

There's a universal solution for this, along with a bit of hackery for older browsers. You can override the print() method in all browsers:

(function (oldPrint) { 
    window.print = function () {
        document.getElementById("hideThis").style.display = 'none';
        oldPrint();
    }
})(window.print);

The problem here is that it will not fire for users pressing Ctrl+P or accessing the file menu to print. Internet Explorer has a solution by way of the onbeforeprint event:

if ("onbeforeprint" in window) {
    var hideEl = document.getElementById("hideThis");
    window.onbeforeprint = function () { 
        hideEl.style.display = 'none';
    }
    window.onafterprint = function () {
        hideEl.style.display = '';
    }
}

As for other browsers, you can add an event listener to a print MediaQueryList as detailed by TJ VanToll in another answer:

if (window.matchMedia) {
    var mqList = window.matchMedia("print"),
        hideEl = document.getElementById("hideThis");

    mqList.addListener(function (mql) {
        hideEl.style.display = mql.matches ? 'none' : '';
    }); 
}

And putting it all together:

(function () {
    var hideEl = document.getElementById("hideThis");

    // HTML5 spec, IE 5.5+, Firefox 6.0+
    if ("onbeforeprint" in window) {
        window.onbeforeprint = function () { 
            hideEl.style.display = 'none';
        }
        window.onafterprint = function () {
            hideEl.style.display = '';
        }
    }

    // Chrome 9+, Opera 12.1+, Safari 5.1+
    else if (window.matchMedia) {
        var mqList = window.matchMedia("print");

        mqList.addListener(function (mql) {
            hideEl.style.display = mql.matches ? 'none' : '';
        }); 
    }

    // Your fallback method, only working for JS initiated printing
    else {    
        (function (oldPrint) { 
            window.print = function () {
                hideEl.style.display = 'none';
                oldPrint();
            }
        })(window.print);
    }
})();
Community
  • 1
  • 1
Andy E
  • 338,112
  • 86
  • 474
  • 445
  • See a workaround for other browsers [at this newer SO answer](http://stackoverflow.com/a/11060206/71650) – Nathan Jan 15 '13 at 21:01
  • @Nathan: thanks, I've updated the answer and credited your source. – Andy E Jan 15 '13 at 21:41
  • Cool, I'm impressed as always. – Nathan Jan 15 '13 at 22:37
  • The "all together" solution doesn't work in latest Firefox (v32) because although it supports window.matchMedia, printing causes a clone of the document to be created, so the event handler is never called. See [this Mozilla bug report](https://bugzilla.mozilla.org/show_bug.cgi?id=774398). I worked around this by testing for onbeforeprint and onafterprint support, then using this in preference to window.matchMedia – DaveAlden Oct 06 '14 at 12:15
3

You can do:

window.old_print=window.print
window.print=function() {
    alert('doing things');
    window.old_print();
}

but this will only catch calls to print() from inside the page javascript.

Did you try putting !important on print-specific stylesheet?

aularon
  • 11,042
  • 3
  • 36
  • 41
  • Both answers make it pretty clear that I can't cover every case so I am in a bit of a pickle. Thanks for the help. – Pricey Sep 01 '10 at 15:34