This little script makes list items selectable and draggable. I'm pretty new to programming in general, and even more so to Javascript. Most of my background is in PHP and some C++. On the large, I don't think this is the proper way to be writing code in JavaScript. I know global variables are bad, but I'm not used to dealing with event handling, I don't know how to maintain constants like that throughout various event calls that aren't otherwise attached to each other. I'm really not sure if I'm doing any of this right.

A more specific question - This script works as is, but if i change `handleDragStart()`'s variable `dragSrc = this;` into `var dragSrc = this;` as it should be, it breaks. When the `handleDrop()` event fires, it returns `dragSrc is not defined`. If anything, I would expect this behavior with the way it is written now, not after adding `var`. I'm a little lost.


    var SELECTED_CLASS_CONST = 'selected';
    var DROP_CLASS_CONST = 'drophover';

    function handleDragStart(e) {

        dragSrc = this;

        e.dataTransfer.effectAllowed = 'move';
        e.dataTransfer.setData('text/html', this.innerHTML);
    }

    function handleDragEnter(e) {

        this.addClass(DROP_CLASS_CONST);
    }

    function handleDragLeave(e) {

        this.removeClass(DROP_CLASS_CONST);
    }

    function handleDragEnd(e) {

        [].forEach.call(draggables, function(drag) {

            drag.removeClass(DROP_CLASS_CONST);
        });
    }

    function handleDragOver(e) {

        if (e.preventDefault) {
            e.preventDefault();
        }
        e.dataTransfer.dropEffet = 'move';

        return false;
    }

    function handleDrop(e) {

        if (e.stopPropagation)
        {
            e.stopPropagation();
        }

        if ( dragSrc != this )
        {
            dragSrc.innerHTML = this.innerHTML;
            this.innerHTML = e.dataTransfer.getData('text/html');
            this.removeClass(DROP_CLASS_CONST);

            if (dragSrc.hasClass(SELECTED_CLASS_CONST) && this.hasClass(SELECTED_CLASS_CONST))
            { return; }
            else { swapClass(dragSrc, this, SELECTED_CLASS_CONST); }
        }
        return false;
    }


    function toggleClass(e) {

        if (e.preventDefault) {
            e.preventDefault();
        }
        this.toggleClass(SELECTED_CLASS_CONST);
    }

    function swapClass(elemA, elemB, c) {

        if (elemA.hasClass(c) || elemB.hasClass(c)) {
            elemA.toggleClass(c);
            elemB.toggleClass(c);
        }
        return;
    }  

    Element.prototype.toggleClass = function(name) {

        if (this.hasClass(name))
        {
            this.removeClass(name);
        }
        else
        {
            this.addClass(name);
        }
    };

    Element.prototype.hasClass = function(name) {

        return new RegExp("(?:^|\\s+)" + name + "(?:\\s+|$)").test(this.className);
    };

    Element.prototype.addClass = function(name) {

        if(!this.hasClass(name))
        {
            this.className = this.className ? [this.className, name].join(' '): name
        }
    };

    Element.prototype.removeClass = function(name) {

        if(this.hasClass(name))
        {
            var curClass = this.className;
            this.className = curClass.replace(new RegExp("(?:^|\\s+)" + name + "(?:\\s+|$)", "g"), "");
        }
    };
    var draggables = document.getElementsByClassName('drag');

    [].forEach.call(draggables, function(drag) {
        drag.addEventListener('dragstart', handleDragStart, false);
        drag.addEventListener('dragenter', handleDragEnter, false);
        drag.addEventListener('dragover', handleDragOver, false);
        drag.addEventListener('dragleave', handleDragLeave, false);
        drag.addEventListener('dragend', handleDragEnd, false);
        drag.addEventListener('drop', handleDrop, false);
        drag.addEventListener('click', toggleClass, true);
    });

I know I could just use jQuery or the myriad of other js libraries, but this is just a project to really learn Javascript thoroughly before moving to a library. At least how to properly structure my code (something I'm still learning how to do in PHP as well...) form closures when necessary, and how to recognize when that is.