Search code examples
javascripthtmlmargin

Key code based event listener doesn’t move box correctly, using margins


I am having a problem with a script that I made to allow elements with the ID me to move based on arrow keys, but whenever it’s told to go left it goes right, when told to go right it goes right, when told to go up or down it doesn’t move.

Here is the script:

document.onkeydown = function(event) {
    var kc = event.keyCode;
    var me = document.getElementById('me');

    me.innerHTML = kc;

    var XPos = me.offsetLeft;
    var YPos = me.offsetTop;

    if (kc == '39') {
        me.style.marginLeft = XPos++ + 'px';
    }
    if (kc == '37') {
        me.style.marginLeft = XPos-- + 'px';
    }
    if (kc == '38') {
        me.style.marginTop = YPos-- + 'px';
    }
    if (kc == '40') {
        me.style.marginTop = YPos++ + 'px';
    }
};

A demo is on this website.


Solution

  • There are two mistakes in your code:

    • You are trying to set the position of the box with marginLeft / marginTop – this adds, as the name implies, margins to the div, i.e. additional space around it, thus moving it in the opposite direction that you intend; you should simply use left and top

    • By using e.g. XPos++, you are getting the old value of XPos, and then you increase its value; you should use ++XPos instead, this way, the value is increased before you use it

    Here's an updated, working version of your code:

    document.onkeydown = function(event) {
        var kc = event.keyCode;
        var me = document.getElementById('me');
        me.innerHTML = kc;
        var XPos = me.offsetLeft;
        var YPos = me.offsetTop;
        if (kc == '39') {
            me.style.left = ++XPos + 'px';
        }
        if (kc == '37') {
            me.style.left = --XPos + 'px';
        }
        if (kc == '38') {
            me.style.top = --YPos + 'px';
        }
        if (kc == '40') {
            me.style.top = ++YPos + 'px';
        }
    };
    #me {
        position: absolute;
        left: 100px;
        top: 100px;
        width: 100px;
        height: 100px;
        background-color: blue;
    }
    <div id="me"></div>

    See JSFiddle: https://jsfiddle.net/pahund/sovxsh22/