0

I want to add data to the current webpage with jQuery before I print the webpage. The reason is that I have a digital CV on my website and don't want to have my personal information on the website available to crawlers etc. I created an XHR request to get my personal information before printing and want to inject the data into HTML. I found this script to find out with jQuery when a user is printing. This works fine in general but the problem is that the script works "too slow", meaning that the data will not be appended before the print dialogue pops up. This is my HTML code:

<div>
    <span id="cvnameplaceholder">My Name</span><br />
    <span id="cvstreetplaceholder"></span><br />
    <span id="cvcityplaceholder"></span><br /><br />
    <span id="cvemailplaceholder"></span>
</div>

And this is the jQuery code which returns an array like {street: 'ABC', city: 'DEF', email: 'mail@example.com}

$(document).ready(function() {
    var beforePrint = function() {
        $.post("./api/RequestHandler.php", {request : "getCVInformation"}, function (response) {
            response = JSON.parse(response);
            $('#cvstreetplaceholder').text(response.street);
            $('#cvcityplaceholder').text(response.city);
            $('#cvemailplaceholder').text(response.email);
        })
     };

    if (window.matchMedia) {
        var mediaQueryList = window.matchMedia('print');
        mediaQueryList.addListener(function(mql) {
            if (mql.matches) {
                beforePrint();
            }
        });
    }

    window.onbeforeprint = beforePrint;
}());

When I hit the print button a second time, the information is there. So is there any possibility to add some text before showing the actual print dialogue?

Drudge
  • 528
  • 1
  • 6
  • 20
  • 1
    Not to rain on your parade, but wouldn't it be easier to just let them download a complete PDF instead that they can either print or save? – Difster Jul 09 '17 at 20:44

2 Answers2

0

A good number of crawlers now also either parse the js, or execute it and parse the result, so this may not keep your info private.

That said, it looks as though your problem is that you're not stopping the event, you're just hooking into it. The event listener is calling beforePrint, but it's not stopping anything else from also triggering on that event - in this case, the actual print dialog.

Additionally, you're loading the data via an ajax request, which is asynch. If you were somehow storing the data in a local javascript variable and populating the page, you might get lucky and have the text loaded in before the print dialog actually opened. But you're running into the same kind of problem that's mentioned on the page linked from that other answer, https://www.tjvantoll.com/2012/06/15/detecting-print-requests-with-javascript/ , where someone had a mix of low and high-res images actually printing. That is, the ajax request is sent before the print event bubbles up and triggers the print dialog, but the response is coming back after the browser's already rendered the page for printing.

You need to use stop the event from propagating (https://api.jquery.com/event.stoppropagation/ ), then re-trigger the print event within the post's callback, after you actually have the info. That's why you're seeing the info in there that second time; it's actually the info you loaded the first time that you're seeing.

Here's an example of catching and blocking the event, then re-triggering it after your data's arrived and been loaded:

$(document).ready(function() {
    var beforePrint = function(e) {
        e.stopPropagation();
        $.post("./api/RequestHandler.php", {request : "getCVInformation"}, function (response) {
            response = JSON.parse(response);
            $('#cvstreetplaceholder').text(response.street);
            $('#cvcityplaceholder').text(response.city);
            $('#cvemailplaceholder').text(response.email);
            window.print();
        });
     };

    if (window.matchMedia) {
        window.matchMedia('print').addListener(function(mql) {
            if (mql.matches) {
                beforePrint();
            }
        });
    }

    window.onbeforeprint = beforePrint;
}());

It's worth noting, though, that as mentioned on that linked page, the onbeforeprint event is IE5+ and Firefox 6+, window.matchMedia is Chrome 9+ and Safari 5.1, while Opera doesn't support either, and both seem to have various unsolved issues. So you very well might still end up with a printed CV that's lacking your contact info.

BrianFreud
  • 7,094
  • 6
  • 33
  • 50
  • I don't get it what I have to do exactly. I added the variable e to the beforePrint function signature and tried to e.stopPropagation(); and to call window.print(); at the end of the function. (Also in the .done() part of the jQuery post request). Could you give me a minimal example of what I have to change? – Drudge Jul 09 '17 at 21:36
  • Take a look now :) – BrianFreud Jul 10 '17 at 00:28
0

I know this does not directly answer the question, but you could iframe in your CV content and use nofollow/noindex to prevent indexing. This solution deals with appending content, but it does not use jQuery.

index.html

<html>
    <head>
        <style>
            iframe {
                border: none;
            }
            .cv {
                display: none;
            }
            @media print {
                .cv {
                    display: block;
                }
            }
        </style>
    </head>
    <div class="cv">
        <iframe src="cv.html"></iframe>
    </div>
</html>

cv.html

<html>
    <head>
        <meta name="robots" content="noindex,nofollow">
    </head>
    <body>
        My CV Details
    </body>
</html>
strictlyk3v
  • 562
  • 5
  • 7