advanced javascript syntax questions, what is going on in the code here?

Hi,

I'm using Yahoo UI Drag and drop utilities written in javascript for client side drag and drop functionality in my web app.  I'm going through some example code, and i'm having a difficult time understanding what's going on because I'm fairly new to javascript and see some unfamiliar syntax.  Some links to advanced javascript tutotrials covering this type of syntax would be great.  I haven't found any yet.  The code is below.  A few parts in general are :

what is yahoo.extend? (YAHOO.extend(YAHOO.example.DDList, YAHOO.util.DDProxy,) it looks like the declaration is a function, but then it's passing in DDList, DDProxy, and a long section of code as parameters.  What is going on here?

Also, I see 'goto' like syntax before functions are defined.  Is this just another way of defining a function?
ie (startDrag: function(x, y) {...).

Lastly, after the previous function definitions (assuming they are actually function definitions), I see commas... like it's just listing out a bunch of functions.  Why the commas?

The full code listing is below.  You can copy and paste the code into an htm file and see some nice drag and drop javascript functionality... I'm just trying to figure out how it works.  Thanks!


<html>
<head>
<style type="text/css">
 
div.workarea { padding:10px; float:left }
 
ul.draglist { 
    position: relative;
    width: 200px; 
    height:240px;
    background: #f7f7f7;
    border: 1px solid gray;
    list-style: none;
    margin:0;
    padding:0;
}
 
ul.draglist li {
    margin: 1px;
    cursor: move; 
}
 
ul.draglist_alt { 
    position: relative;
    width: 200px; 
    list-style: none;
    margin:0;
    padding:0;
    /*
       The bottom padding provides the cushion that makes the empty 
       list targetable.  Alternatively, we could leave the padding 
       off by default, adding it when we detect that the list is empty.
    */
    padding-bottom:20px;
}
 
ul.draglist_alt li {
    margin: 1px;
    cursor: move; 
}
 
 
li.list1 {
    background-color: #D1E6EC;
    border:1px solid #7EA6B2;
}
 
li.list2 {
    background-color: #D8D4E2;
    border:1px solid #6B4C86;
}
 
#user_actions { float: right; }
 
</style>
<!-- Dependencies --> 
<script type="text/javascript" src="http://yui.yahooapis.com/2.4.1/build/yahoo-dom-event/yahoo-dom-event.js" ></script>
 
<!-- Drag and Drop source file --> 
<script type="text/javascript" src="http://yui.yahooapis.com/2.4.1/build/dragdrop/dragdrop-min.js" ></script>
 
<!-- Source file -->
<script src="http://yui.yahooapis.com/2.4.1/build/animation/animation-min.js"></script>
 
<script type="text/javascript">
 
(function() {
 
var Dom = YAHOO.util.Dom;
var Event = YAHOO.util.Event;
var DDM = YAHOO.util.DragDropMgr;
 
//////////////////////////////////////////////////////////////////////////////
// example app
//////////////////////////////////////////////////////////////////////////////
YAHOO.example.DDApp = {
    init: function() {
 
        var rows=3,cols=2,i,j;
        for (i=1;i<cols+1;i=i+1) {
            new YAHOO.util.DDTarget("ul"+i);
        }
 
        for (i=1;i<cols+1;i=i+1) {
            for (j=1;j<rows+1;j=j+1) {
                new YAHOO.example.DDList("li" + i + "_" + j);
            }
        }
 
        Event.on("showButton", "click", this.showOrder);
        Event.on("switchButton", "click", this.switchStyles);
    },
 
    showOrder: function() {
        var parseList = function(ul, title) {
            var items = ul.getElementsByTagName("li");
            var out = title + ": ";
            for (i=0;i<items.length;i=i+1) {
                out += items[i].id + " ";
            }
            return out;
        };
 
        var ul1=Dom.get("ul1"), ul2=Dom.get("ul2");
        alert(parseList(ul1, "List 1") + "\n" + parseList(ul2, "List 2"));
 
    },
 
    switchStyles: function() {
        Dom.get("ul1").className = "draglist_alt";
        Dom.get("ul2").className = "draglist_alt";
    }
};
 
//////////////////////////////////////////////////////////////////////////////
// custom drag and drop implementation
//////////////////////////////////////////////////////////////////////////////
 
YAHOO.example.DDList = function(id, sGroup, config) {
 
    YAHOO.example.DDList.superclass.constructor.call(this, id, sGroup, config);
 
    this.logger = this.logger || YAHOO;
    var el = this.getDragEl();
    Dom.setStyle(el, "opacity", 0.67); // The proxy is slightly transparent
 
    this.goingUp = false;
    this.lastY = 0;
};
 
YAHOO.extend(YAHOO.example.DDList, YAHOO.util.DDProxy, {
 
    startDrag: function(x, y) {
        this.logger.log(this.id + " startDrag");
 
        // make the proxy look like the source element
        var dragEl = this.getDragEl();
        var clickEl = this.getEl();
        Dom.setStyle(clickEl, "visibility", "hidden");
 
        dragEl.innerHTML = clickEl.innerHTML;
 
        Dom.setStyle(dragEl, "color", Dom.getStyle(clickEl, "color"));
        Dom.setStyle(dragEl, "backgroundColor", Dom.getStyle(clickEl, "backgroundColor"));
        Dom.setStyle(dragEl, "border", "2px solid gray");
    },
 
    endDrag: function(e) {
 
        var srcEl = this.getEl();
        var proxy = this.getDragEl();
 
        // Show the proxy element and animate it to the src element's location
        Dom.setStyle(proxy, "visibility", "");
        var a = new YAHOO.util.Motion( 
            proxy, { 
                points: { 
                    to: Dom.getXY(srcEl)
                }
            }, 
            0.2, 
            YAHOO.util.Easing.easeOut 
        )
        var proxyid = proxy.id;
        var thisid = this.id;
 
        // Hide the proxy and show the source element when finished with the animation
        a.onComplete.subscribe(function() {
                Dom.setStyle(proxyid, "visibility", "hidden");
                Dom.setStyle(thisid, "visibility", "");
            });
        a.animate();
    },
 
    onDragDrop: function(e, id) {
 
        // If there is one drop interaction, the li was dropped either on the list,
        // or it was dropped on the current location of the source element.
        if (DDM.interactionInfo.drop.length === 1) {
 
            // The position of the cursor at the time of the drop (YAHOO.util.Point)
            var pt = DDM.interactionInfo.point; 
 
            // The region occupied by the source element at the time of the drop
            var region = DDM.interactionInfo.sourceRegion; 
 
            // Check to see if we are over the source element's location.  We will
            // append to the bottom of the list once we are sure it was a drop in
            // the negative space (the area of the list without any list items)
            if (!region.intersect(pt)) {
                var destEl = Dom.get(id);
                var destDD = DDM.getDDById(id);
                destEl.appendChild(this.getEl());
                destDD.isEmpty = false;
                DDM.refreshCache();
            }
 
        }
    },
 
    onDrag: function(e) {
 
        // Keep track of the direction of the drag for use during onDragOver
        var y = Event.getPageY(e);
 
        if (y < this.lastY) {
            this.goingUp = true;
        } else if (y > this.lastY) {
            this.goingUp = false;
        }
 
        this.lastY = y;
    },
 
    onDragOver: function(e, id) {
    
        var srcEl = this.getEl();
        var destEl = Dom.get(id);
 
        // We are only concerned with list items, we ignore the dragover
        // notifications for the list.
        if (destEl.nodeName.toLowerCase() == "li") {
            var orig_p = srcEl.parentNode;
            var p = destEl.parentNode;
 
            if (this.goingUp) {
                p.insertBefore(srcEl, destEl); // insert above
            } else {
                p.insertBefore(srcEl, destEl.nextSibling); // insert below
            }
 
            DDM.refreshCache();
        }
    }
});
 
Event.onDOMReady(YAHOO.example.DDApp.init, YAHOO.example.DDApp, true);
 
})();
</script>
 
 
</head>
<body>
 
 
<div class="workarea">
  <h3>List 1</h3>
  <ul id="ul1" class="draglist">
    <li class="list1" id="li1_1">list 1, item 1</li>
    <li class="list1" id="li1_2">list 1, item 2</li>
    <li class="list1" id="li1_3">list 1, item 3</li>
  </ul>
</div>
 
<div class="workarea">
  <h3>List 2</h3>
  <ul id="ul2" class="draglist">
    <li class="list2" id="li2_1">list 2, item 1</li>
    <li class="list2" id="li2_2">list 2, item 2</li>
    <li class="list2" id="li2_3">list 2, item 3</li>
  </ul>
</div>
 
 
 
 
 
 
</body>
</html>

Open in new window

LVL 7
prosh0tAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

vs1784Commented:
Its using Yahoo drag and drop library.

May be you want to look at its documentation here

http://developer.yahoo.com/yui/dragdrop/

Hope it helps.

Thanks
0
prosh0tAuthor Commented:
Hi, Thanks for the reply.

I've intended to use the library and I'm familiar with it.  I'm just going through this example and I'm confused by the javascript syntax.  So my question more lies with what is going on in the javascript code rather than what the yahoo library is.

Thanks
0
HonorGodSoftware EngineerCommented:
Well, you are seeing some non-trivial, advanced JavaScript here.
This should be recognized by the fact that just inside the script tag we see some "unusual" syntax.  Specifically:

<script type="text/javascript">
 
(function() {
...
})();
</script>

What does this mean?  Well, it means that an anonymous global function is being defined, and invoked.

The reason it is being invoked is to allow it to be executed to allocate and initialize objects, and setup the environment (e.g., event handlers) to allow the page to react to the user actions (e.g., mouse clicks, and movement).

One of the side effects of this type of construct is called closure, which is described a little in this question:

http://www.experts-exchange.com/Q_23093328.html

Unfortunately, this topic is not trivial, and it requires study.

Good luck
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
prosh0tAuthor Commented:
Thanks!
0
HonorGodSoftware EngineerCommented:
Thank you for the grade, and points.
Good luck.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.