首页 > 解决方案 > JavaScript vs jQuery 数学行为?

问题描述

我正在尝试用 javascript 构建游戏。我有这个功能来移动一个角色:

    document.addEventListener('keydown', function(e){
        let p = document.getElementById('player'), x = p.offsetLeft, y = p.offsetTop;
        console.log({x,y});
        switch( e.keyCode ) {
            case 37:
                x -= 1.5;
            break;
            case 38:
                y -= 1.5; 
            break;
            case 39:
                x += 1.5;
            break;
            case 40:
                y += 1.5;
            break;
        }
        console.log({x,y});
        p.setAttribute('style', `left: ${x}px; top:${y}px;`);
    });

这是相同的功能,但用 jQuery 编写:

    $(document).on('keydown', function(e) {
        let x = $('#player').offset().left, y = $('#player').offset().top;
        switch(e.keyCode) {
            case 37:
                x -= 1.5;
            break;
            case 38:
                y -= 1.5; 
            break;
            case 39:
                x += 1.5;
            break;
            case 40:
                y += 1.5;
            break;
        }
        $('#player').css({
            top: y + "px",
            left: x + "px" 
        });
    });

为什么用 vanilla javascript 编写的函数将对象向右移动的速度比向左移动的速度快,而 jQuery 在两个方向上的移动速度相同?编辑:忘了提,这只发生在这个特定的值 1.5 上,因为假设 1 就可以了。

标签: javascriptjquery

解决方案


jQueryoffset()能够处理半个像素:

在某些情况下,与维度相关的 API(包括 .offset())返回的数字可能是小数。代码不应假定它是整数。http://api.jquery.com/offset/

offsetLeft 和 offsetTop 仅适用于整数,因此将 1.5 向上舍入为 2,因此在每一步(在两个方向上)将对象移动得更远:

left 是一个整数,表示从最近的相对定位的父元素到左侧的偏移量(以像素为单位)。 https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft

document.addEventListener('keydown', function(e){
        let p = document.getElementById('player'), x = p.offsetLeft, y = p.offsetTop;
        console.log("vanilla: ", x, y);
        switch( e.keyCode ) {
            case 37:
                x -= 1.5;
            break;
            case 38:
                y -= 1.5; 
            break;
            case 39:
                x += 1.5;
            break;
            case 40:
                y += 1.5;
            break;
        }
        p.setAttribute('style', `left: ${x}px; top:${y}px;`);
    });

    $(document).on('keydown', function(e) {
        let x = $('#jqPlayer').offset().left, y = $('#jqPlayer').offset().top;
        console.log("jQuery: ", x, y);

        switch(e.keyCode) {
            case 37:
                x -= 1.5;
            break;
            case 38:
                y -= 1.5; 
            break;
            case 39:
                x += 1.5;
            break;
            case 40:
                y += 1.5;
            break;
        }
        $('#jqPlayer').css({
            top: y + "px",
            left: x + "px" 
        });
    });
div.obj {position:absolute; border: 1px solid}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="obj" id="player">vanilla</div>

<div class="obj" id="jqPlayer">jQuery</div>

作为确认,如果你坚持整数,差异就会消失:

document.addEventListener('keydown', function(e){
        let p = document.getElementById('player'), x = p.offsetLeft, y = p.offsetTop;
        switch( e.keyCode ) {
            case 37:
                x -= 2;
            break;
            case 38:
                y -= 2; 
            break;
            case 39:
                x += 2;
            break;
            case 40:
                y += 2;
            break;
        }
        p.setAttribute('style', `left: ${x}px; top:${y}px;`);
    });

    $(document).on('keydown', function(e) {
        let x = $('#jqPlayer').offset().left, y = $('#jqPlayer').offset().top;
        switch(e.keyCode) {
            case 37:
                x -= 2;
            break;
            case 38:
                y -= 2; 
            break;
            case 39:
                x += 2;
            break;
            case 40:
                y += 2;
            break;
        }
        $('#jqPlayer').css({
            top: y + "px",
            left: x + "px" 
        });
    });
div.obj {position:absolute; border: 1px solid}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="obj" id="player">vanilla</div>

<div class="obj" id="jqPlayer">jQuery</div>


推荐阅读