javascriptiife

Understanding obscure JavaScript code


I found this code in the <head> section of an HTML page (a collegue made this but he doesn't work here anymore):

(function(window, PhotoSwipe){ 
    document.addEventListener('DOMContentLoaded', function(){
        var options = {},
            instance = PhotoSwipe.attach( window.document.querySelectorAll('#Gallery a'), options );
    }, false);
}(window, window.Code.PhotoSwipe));

While I can understand the central part (from document.addEventListener), I can't understand the first and the last line. What they're doing here? The code is from an open source image gallery called PhotoSwipe. Any pointer is appreciated.

[EDIT]

Is this code the same as:

document.addEventListener('DOMContentLoaded', function(){
        var options = {},
            instance = window.Code.PhotoSwipe.attach( window.document.querySelectorAll('#Gallery a'), options );
    }, false);

?


Solution

  • This is a self-executing protected bit of code. Let's break it down:

    (function(window, PhotoSwipe){
      ...
    }(window, window.Code.PhotoSwipe));
    

    The parenthesis cause our code to be executed on its own, without anything else invoking it.

    This creates references to window and window.Code.PhotoSwipe that cannot be tampered with by outside code. So within our parens, PhotoSwipe is a protected alias of window.Code.PhotoSwipe. And window, though the name doesn't differ, is also a protected reference to the external global window object.

    The next line, the addEventListener line, could be rewritten to bring its anonymous function out as a named function:

    function myFunc() {
      var options = {},
          instance = PhotoSwipe.attach( window.document.querySelectorAll('#Gallery a'), options );
    }
    document.addEventListener('DOMContentLoaded', myFunc, false);
    

    Note, this is functionally the same thing you have in your original code, only we've pulled the function out of the addEventListener call and gave it a name.

    addEventListener attaches a callback function to handler certain events. In this case, we're handling the event DOMContentLoaded. This event is being listened for on the document object. Anytime this event is heard, we respond by calling myFunc.

    The last parameter, false, deals with capturing and bubbling. These are two methods events propagate throughout the DOM. When Capturing, events move from the top of the DOM inward. When Bubbling, they move from the inside of the DOM outward. Using false states you want to handle this in its bubbling phrase.

    Within myFunct, which is called anytime the DOMContentLoaded event happens on the document, we have one line of code which first declares a new object called options. This object is empty, having no members.

    Secondly, you are passing in two arguments to the attach method of the PhotoSwipe object. The first method is a selector. What is does it searches the DOM for elements that match #Gallery a, meaning any anchor element inside an element having the ID "Gallery". That would mean all of the following:

    <div id="Gallery"><a href="#">Foo</a></div>
    

    Or

    <div id="Gallery">
      <div class="picture">
        <a href="#">Open</a>
      </div>
      <div class="picture">
        <a href="#">Open</a>
      </div>
    </div>
    

    This is associated with the empty object that we created. What PhotoSwipe does internally is unknown at this point, since that code is not presented here.