3

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

?

1
  • This question is similar to: What is the (function() { } )() construct in JavaScript?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. Commented Nov 12, 2024 at 20:52

5 Answers 5

2

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.

Sign up to request clarification or add additional context in comments.

Comments

2

That is a self-executing anonymous function. Usually it is used to provide scope to variables in Javascript to keep the parent namespace less cluttered (in this case the parent namespace being the global namespace.)

http://markdalgleish.com/2011/03/self-executing-anonymous-functions/

1 Comment

So this thing has a name ("self executing anonymous function").
2

It moves those variables in the local scope to make lookups faster. It also makes window.Code.PhotoSwipe available as PhotoSwipe.

However, usually one wouldn't use window as the first argument but this since that's guaranteed to be the global object (which is window) in a browser when executed in the global scope.

1 Comment

I found this is the exact copy of an example you can download with the library.
0

First line is function declaration. Last one is an automatic call to this function whith arguments. That way the function is declared, called and run itself in one step.

Comments

0

Reformatting:

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

This creates a function taking two arguments (window and PhotoSwipe), which adds an event listener - the second (inner) function - and then immediately calls the outer function with the values window and window.Code.PhotoSwipe as arguments.

Why do this? Javascript is not great at separating scopes, unless you put code inside a function. So inside the main function in the sample, PhotoSwipe can only refer to the second argument passed in.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.