3

I am more familiar with CSS coding than with Javascript, so when I was tasked to find a way to display Link URLS during print but not on-screen, I ran into a bit of trouble. Using CSS, I can manage what I want just fine, but thanks to Internet Explorer's quirkiness, I've had to find a javascript solution to my problem.

I was able to solve my dilemma with this code to make the link URLs display on print, and then disappear off the page when print preview was closed.

window.onbeforeprint = function(){
var links = document.getElementsByTagName("a");
for (var i=0; i< links.length; i++){
    var theContent = links[i].getAttribute("href");
    if (!theContent == ""){
        links[i].newContent = " [" + theContent + "] ";
        links[i].innerHTML = links[i].innerHTML + links[i].newContent;
        }
    }
}
window.onafterprint = function(){
var links = document.getElementsByTagName("a");
for (var i=0; i< links.length; i++){
    var theContent = links[i].innerHTML;
    if (!theContent == ""){
        var theBracket = theContent.indexOf(links[i].newContent);
        var newContent = theContent.substring(0, theBracket);
        links[i].innerHTML = newContent;
        }
    }
}

However, now my problem becomes that ALL the page link URLs are printed. But, obviously, I don't need to print things like the internal navigation URLs; that just makes the finished product look messy. Is there a way to exclude certain sections of the page, like a UL-list with the ID of Navigation, from the onbeforeprint/onafterprint functions in javascript?

BartoszKP
  • 34,786
  • 15
  • 102
  • 130
kesomon
  • 45
  • 3

1 Answers1

0

getElementsByTagName can be used as a method of any DOM node. Thus:

var links = document.getElementById('showURLs').getElementsByTagName('a');

Using an ID on the parent

Simply replace the variable definition for links in your code with the above. Like so:

window.onbeforeprint = function(){

    var links = document.getElementById('showURLs').getElementsByTagName('a');
    for (var i=0; i< links.length; i++){
        var theContent = links[i].getAttribute("href");
        if (!theContent == ""){
            links[i].newContent = " [" + theContent + "] ";
            links[i].innerHTML = links[i].innerHTML + links[i].newContent;
        }
    }

}

window.onafterprint = function(){

    var links = document.getElementById('showURLs').getElementsByTagName('a');
    for (var i=0; i< links.length; i++){
        var theContent = links[i].innerHTML;
        if (!theContent == ""){
            var theBracket = theContent.indexOf(links[i].newContent);
            var newContent = theContent.substring(0, theBracket);
            links[i].innerHTML = newContent;
        }
    }

}

Excluding children of a specific element

window.onbeforeprint = function(){
    var links = document.getElementsByTagName("a");
    var exclude = document.getElementById("navBar").getElementsByTagName("a");
    for (var i=0; i< links.length; i++) {
        if (!in_array(links[i], exclude)) {
            var theContent = links[i].getAttribute("href");
            if (!theContent == "") {
                links[i].newContent = " [" + theContent + "] ";
                links[i].innerHTML = links[i].innerHTML + links[i].newContent;
            }
        }
    }
}

We get an array of all links on the page and one of links in the exclusion element (here with an ID of "navBar"). Then, when we are looping through the links on the page, we first check if they're in the exclusion array, and only if they're not we act!

For that conditional we use the bool in_array(needle, haystack) function, which returns true if the needle is found in the haystack (an array), false otherwise. This function is actually an adaptation of PHP's native function - see PHP manual.

function in_array(needle, haystack) {
    for (i=0;i<haystack.length;i++) {
        if (haystack[i] == needle) {
            return true;
        }
    }
    return false;
}

See this JSfiddle I created to test it. If you run print preview in your browser, you'll be able to see the links on the right!

Hope this helps :)

Sean Bone
  • 3,368
  • 7
  • 31
  • 47
  • I hope it does, but I'm not sure how to implement your answer to see if it does help, Sean. When I said I was unfamiliar with Javascript, I meant it's been years and years since I barely passed a course in community college. I found the above code on a website which didn't really explain much about how it worked. If you wouldn't mind, could you explain a little more about where and how I would use those suggested variables? – kesomon Jul 10 '13 at 21:25
  • @kesomon this _does_ however limit you to performing this trick only on the links in _one_ element, since it'd based on the ID `'showURLs'`. If you need more flexibility, we can set it up to use a class instead :) – Sean Bone Jul 11 '13 at 15:40
  • Hmm, yes, I think this will help. :) If I've got this right, to make this function, I would need a Div surrounding the area I wanted to affect with the ID of 'showURLs'. and I'm guessing that to use this as a class, it would be 'getElementByClass' instead of 'ByID'? Sounds easy enough! I wonder though, is it reversible? For instance, on the page I need to use this, the entire page would need to be affected to show URLs during printing, _except_ for the contents of one ul-list containing anchor links. – kesomon Jul 11 '13 at 17:10
  • My first thought was maybe an if-statement somewhere? Like, "if URLs are in UL-list ID***, then do not apply function:onbeforeprint" or maybe "if 'a href' is anchor, do not apply" - would that work? – kesomon Jul 11 '13 at 17:11
  • @kesomon question 1: well the main difference between classes and IDs is that you may only have *one* element with a certain ID on a page - that's why the `getElementById` method returns only one element reference. Classes, however, can be present on as many elements as you like. This allows you to perform 'mass operations' on them (for example CSS may set their `color: red;`, and this would influence every element with that class). The `getElementsByClassName` therefeore returns an array of elements with that class. – Sean Bone Jul 12 '13 at 07:18
  • @kesomon Question 2: yes, you're perfectly right! See edit :) – Sean Bone Jul 12 '13 at 07:19
  • @sean-bone re:1) Ahhhh, I see! Yes, that makes sense. re:2) Ooooh. \o/ That is _so_ awesome, and in hindsight I'm facepalming because it looks so obvious and simple. Thank you so much for your help, Sean! :3 – kesomon Jul 12 '13 at 16:27