tom c
tom c

Reputation: 329

Starting and ending functions in javascript

I am playing around with a short little code to see if I can get a function going while the user has their mouse down and then end it when they bring their mouse up. For this example I am trying to increment a number that I am displaying on the screen as the user moves their mouse while holding the button down. I want it to freeze and stop once they release the button, however the counter just resets and the count continues from 0 even though the button is not being pressed...

function dragInit(state, e) {
    var i = 0;
    $(document).on("mousemove", function() {
        if (state) {
            i+=1;
            $('#debug').text(i); //Show the value in a div
        }
    });
}

$(document).ready(function() {

$(document).on(
    {mousedown: function(e) {
        var state = true;
        dragInit(e, state);
    },
    mouseup: function(e) {
        var state = false;
        dragInit(e, state);
    }
    });
});

As an aside, is there a way I can display whether a variable is true or false onscreen? When I try it just says [object Object].

Upvotes: 2

Views: 809

Answers (4)

SomeShinyObject
SomeShinyObject

Reputation: 7801

You could do something like this:

function dragInit() {
    $(document).on("mousemove", function () {
        if (eventState.state) {
            eventState.count += 1;
            $('#debug').text(eventState.count); //Show the value in a div
        }
    });
}

// Create an object to track event variables
var eventState = {
    count:0, //replaces your previous 'i' variable
    state: false //keeps track of mouseup or mousedown
};

$(document).ready(function () {

    $(document).on({
        mousedown: function (e) {
            eventState.state = true;
            dragInit(); //don't need to pass anything anymore
        },
        mouseup: function (e) {
            eventState.state = false;
            dragInit(); //don't need to pass anything anymore
        }
    });
});

jsFiddle

Or keep everything together as one object

var dragInit = function () {
    var count = 0;
    var state = false;
    var action = function () {
        $(document).on("mousemove", function () {
            if (state) {
                count += 1;
                $('#debug').text(count); //Show the value in a div
            }
        })
    };

    $(document).on({
        mousedown: function (e) {
            state = true;
            action(); //don't need to pass anything anymore
        },
        mouseup: function (e) {
            state = false;
            action(); //don't need to pass anything anymore
        }
    });
}

$(document).ready(function () {
    var obj = new dragInit();
});

jsFiddle 2

Example in response to comment

jsFiddle: This shows why the following code snippets differ in execution.

// Works
$(document).on("mousemove", function () {
    if (state) {

    }
})

// Doesn't
if (state) {
    $(document).on("mousemove", function () {

    });
}

Upvotes: 2

Walter Macambira
Walter Macambira

Reputation: 2605

There are a lot of mistakes in your code. I suggest you to read more basic concepts before starting to use jQuery.

The order of the parameters passed to dragInit() is wrong on both mouseup and mousedown event bindings.

The reason your counter is restarting is because your variable i is local, so it exists only during the function context it is declared in.

You are making the same mistake with the state variable, but in this case it is completely unnecessary to declare it.

Consider making your counter a global (even though it is not a good practice).

I can't provide you code because I am answering from my phone. A solution would be create a mousemove event that checkes whether the mouse button is pressed before incrementing your counter.

Hope I helped

Upvotes: 3

PSL
PSL

Reputation: 123739

Less code, You just need this.

Use jquery on and Off to turn on and off mousemove event.

Counter Reset http://jsfiddle.net/kRtEk/

$(document).ready(function () {
    var i = 0;
    $(document).on({
        mousedown: function (e) {

            $(document).on("mousemove", function () {

                $('#debug').text(i++); //Show the value in a div
            });

        },
        mouseup: function (e) {
            i = 0;
            $('#debug').text(i);
            $(document).off("mousemove");
        }
    });
});

W/O Reset http://jsfiddle.net/gumwj/

$(document).ready(function () {
    var i = 0;
    $(document).on({
        mousedown: function (e) {
             $(document).on("mousemove", function () {
                 $('#debug').text(i++); //Show the value in a div
            });

        },
        mouseup: function (e) {
            $(document).off("mousemove");
        }
    });
});

WithNoCounter http://jsfiddle.net/F3ESx/

$(document).ready(function () {

    $(document).on({
        mousedown: function (e) {
             $(document).on("mousemove", function () {
              $('#debug').data('idx',parseInt($('#debug').data('idx')|0)+1).text($('#debug').data('idx')); //Show the value in a div
            });

        },
        mouseup: function (e) {
            $(document).off("mousemove");
        }
    });
});

Upvotes: 2

Brandt Solovij
Brandt Solovij

Reputation: 2134

Assuming you are married to Jquery (nothing wrong with that) - check out and consider entirely re-thinking your approach leveraging the ".one()" (http://api.jquery.com/one/) method.

edit: and if that taste doesn't sit well - familiarize yourself with the "deferred" object (http://api.jquery.com/category/deferred-object/)

lots of ways to approach this via jquery - what you decide in the end depends on what you really intend to do with this.

Upvotes: 0

Related Questions