views:

131

answers:

2

I am simply trying to create a class that moves a specified DIV when the mouse is on the DIV. My problem seems to be because I am specifying a method of my custom class as the event handler. My question is can I specify the method of an object as an event Handler? Or is there any other way to do this?

<script type="text/javascript">
<!--

    function MovingDIV()
    {
     this.DIV;
     this.posX;
     this.intervalID;
     this.StartDIV = StartDIV;
     this.MoveDIV = MoveDIV;
     this.StopDIV = StopDIV;
    }

    function MovingDIV(DIVname)
    {
     this.DIV = document.getElementById(DIVname);      
    }

    function StartDIV()
    {
         this.intervalID = setInterval(this.MoveDIV, 100);
    }
    function MoveDIV()
    {

        this.posX = parseInt(this.DIV.style.left);

        this.posX += offset;
        this.DIV.style.left = this.posX;
        if(this.posX > 500)
        {
            offset = -50;
        }
        else if(this.posX < 50)
        {
            offset = 50;
        }

    }
    function StopDIV()
    {
     clearInterval(this.intervalID);
    }

    var MyMovingDIV = new MovingDIV("moving_div");
    var test = 123;

//-->
</script>

<div id="moving_div" style="border: 5px outset blue;  width: 160px; background-color: yellow; color: red; position: absolute; left: 400;" onmouseover = "MyMovingDIV.StartDIV()" onmouseout = "MyMovingDIV.StopDIV()">
THE MOVING DIV CLASS
</div>
+1  A: 

Annotated (working) source code follows:

<html>
<head>
<script type="text/javascript">
<!--

    // deleted other constructor, JS doesn't have name overloading
    function MovingDIV(DIVname)
    {
        this.DIV = document.getElementById(DIVname);
        this.posX = null;
        this.intervalID = null;
        // offset was uninitialized
        this.offset = 50;
    }

    // this is the syntax for declaring member functions
    MovingDIV.prototype.StartDIV = function()
    {
        // need to preserve "this" inside of setInterval function, so save
        // it in "self" and pass anonymous function to setInterval
        var self = this;
        this.intervalID = setInterval(function() { self.MoveDIV(); }, 100);
    }

    MovingDIV.prototype.MoveDIV = function()
    {
        // left should have "px" on end so remove it before parseInt
        this.posX = parseInt(this.DIV.style.left.replace(/px/, ""));
        this.posX += this.offset;

        // add "px" to specify units
        this.DIV.style.left = this.posX + "px";

        if(this.posX > 500)
        {
            this.offset = -50;
        }
        else if(this.posX < 50)
        {
            this.offset = 50;
        }

    }

    MovingDIV.prototype.StopDIV = function()
    {
        clearInterval(this.intervalID);
    }

    var MyMovingDIV, test;

    // <div id='moving_div'> does not exist yet
    // need to wait until page has loaded    
    window.onload = function()
    {
        MyMovingDIV = new MovingDIV("moving_div");
        test = 123;
    }

//-->
</script>
</head>

<body>
<div id="moving_div" style="border: 5px outset blue;  width: 160px; background-color: yellow; color: red; position: absolute; left: 400px;" onmo
useover = "MyMovingDIV.StartDIV()" onmouseout = "MyMovingDIV.StopDIV()">
THE MOVING DIV CLASS
</div>
</body>
</html>
John Kugelman
Yep. The closure variable is more commonly known as ‘that’, though, since ‘self’ already has another, different meaning in JavaScript.
bobince
I tried this but still it doesn't work.It seems that it is not able to find the MyMovingDIV.StartDIV() and MyMovingDIV.StopDIV() function in the following line.<div id="moving_div" style="border: 5px outset blue; width: 160px; background-color: yellow; color: red; position: absolute; left: 400;" onmouseover = "MyMovingDIV.StartDIV()" onmouseout = "MyMovingDIV.StopDIV()">THE MOVING DIV CLASS</div>
boogie_dean
Major update, there were lots of issues. Fixed and tested now. Check it out.
John Kugelman
Thanks a bunch!! That was really helpful.I assume that the main problem (among many others) was the way I was defining my class and specifically the class functions. Right?
boogie_dean
Yeah, you had free-floating global functions rather than class methods. You weren't associating `StartDIV`, `MoveDIV`, and `StopDIV` with the `MovingDIV` class.
John Kugelman
+1  A: 
    this.DIV;

This would do nothing. It evaluates to undefined because no such property exists, then throws the undefined value away.

function MovingDIV()

This whole function does nothing (as it is overridden by the next definition of MovingDIV).

this.DIV.style.left = this.posX;

You will need to add +'px' to that to make it work in Standards Mode and cross-browser. Similarly 400px in the style.

As John said, if you are using JavaScript Objects, you have to take care to bind this, generally through some kind of closure (but in the future using Function.bind). I fear from the above constructor though you don't quite grok how JavaScript does objects.

You can simplify an example like this by eschewing anything to do with prototyping/this, and just using a closure to remember the div you're interested in. Until you are ready to understand the details (and, to be honest, brokennesses) of the JS object model you're probably better off this way. eg.:

<script type="text/javascript">

    function slideyElement(element, x, xleft, xright, dx, dt) {
        var interval= null;

        function slide() {
            var x= dx;
            if (x<xleft || x>xright)
                dx= -dx;
            element.style.left= x+'px';
        }

        element.onmouseover= function() {
            interval= setInterval(slide, dt);
        };
        element.onmouseout= function() {
            if (interval!==null)
                clearInterval(interval);
            interval= null;
        };
    };

</script>

<div id="moving_div" style="border: 5px outset blue; width: 160px; background-color: yellow; color: red; position: absolute; left: 400px;">

<script type="text/javascript">
    slideyElement(document.getElementById('moving_div'), 400, 50, 500, 50, 100);
</script>

bobince
Yes I have just started to work with JavaScript and am trying to hold a hold of how objects work. I have already done it the way you have specified in your example. But now as an exercise to understand Objects I would like to do it with the objects.Unfortunately I do not understand the mistakes you have specified in your reply. Do I need to keep just one constructor and get rid of the other?
boogie_dean