如何用箭头键移动div

Opo*_*poe 18 html javascript jquery events

我想使用jQuery用箭头键移动div.所以正确,左,下,上.

找到了我想在这里完成的演示

我希望能够在另一个div中移动div.

如何才能做到这一点?

Šim*_*das 38

HTML:

var pane = $('#pane'),
    box = $('#box'),
    w = pane.width() - box.width(),
    d = {},
    x = 3;

function newv(v,a,b) {
    var n = parseInt(v, 10) - (d[a] ? x : 0) + (d[b] ? x : 0);
    return n < 0 ? 0 : n > w ? w : n;
}

$(window).keydown(function(e) { d[e.which] = true; });
$(window).keyup(function(e) { d[e.which] = false; });

setInterval(function() {
    box.css({
        left: function(i,v) { return newv(v, 37, 39); },
        top: function(i,v) { return newv(v, 38, 40); }
    });
}, 20);
Run Code Online (Sandbox Code Playgroud)

CSS:

#pane {
  position: relative;
  width: 300px;
  height: 300px;
  border: 2px solid red;
}

#box {
  position: absolute;
  top: 140px;
  left: 140px;
  width: 20px;
  height: 20px;
  background-color: black;
}
Run Code Online (Sandbox Code Playgroud)

JavaScript的:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="pane">
  <div id="box"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

变量说明:
w- 框可以具有的最大左/顶值(保持在边界内)
x- 框在每个间隔中移动的距离(以px为单位)
d- 此对象存储有关正在按下的键的信息.例如,当用户按下左箭头键时,d['37']true.不然吧false.BTW 37是LEFT ARROW键的键码,该值存储在e.which事件对象的属性中.该d对象被更新每个keydownkeyup事件.

每20ms执行一次的setInterval会更新box元素的左侧和顶部CSS属性.新值通过newv函数计算.

newv函数将根据a)旧值v和b)d对象计算新的左/上值.

该表达式n < 0 ? 0 : n > w ? w : n确保新值在允许的范围内(即0 to w).如果n <0,则返回零.如果n> w,则返回w.


现场演示:http://jsfiddle.net/simevidas/bDMnX/1299/


更新:此代码与上面的原始代码具有相同的功能.唯一的区别是我为变量和参数使用了更有意义的名称.正如您所看到的,它看起来很糟糕 - 原始版本显然更好.:P

var pane = $('#pane'),
    box = $('#box'),
    maxValue = pane.width() - box.width(),
    keysPressed = {},
    distancePerIteration = 3;

function calculateNewValue(oldValue, keyCode1, keyCode2) {
    var newValue = parseInt(oldValue, 10)
                   - (keysPressed[keyCode1] ? distancePerIteration : 0)
                   + (keysPressed[keyCode2] ? distancePerIteration : 0);
    return newValue < 0 ? 0 : newValue > maxValue ? maxValue : newValue;
}

$(window).keydown(function(event) { keysPressed[event.which] = true; });
$(window).keyup(function(event) { keysPressed[event.which] = false; });

setInterval(function() {
    box.css({
        left: function(index ,oldValue) {
            return calculateNewValue(oldValue, 37, 39);
        },
        top: function(index, oldValue) {
            return calculateNewValue(oldValue, 38, 40);
        }
    });
}, 20);
Run Code Online (Sandbox Code Playgroud)

  • 没有任何不尊重的意图,但尽管这个代码功能非常好(非常好),变量名称让我觉得我是一个模糊的代码竞争.读取代码很困难,因为除了`pane`和`box`之外没有任何有意义的名称(并且堆叠的三元运算符没有帮助).但就像我说的那样,它确实很好用. (4认同)

inf*_*del 7

@ŠimeVidas:你的第一个解决方案简直太棒了.(我认为第二个是多余的=)

我可以建议为垂直和水平宽度制作两种不同的功能吗?因为你不太可能在一个完美的正方形内移动一个div,我相信这样的东西会更好:

$(function () {
var pane = $('#pane'),
box = $('#box'),
wh = pane.width() - box.width(),
wv = pane.height() - box.height(),
d = {},
x = 5;

function newh(v,a,b) {
    var n = parseInt(v, 10) - (d[a] ? x : 0) + (d[b] ? x : 0);
    return n < 0 ? 0 : n > wh ? wh : n;
}

function newv(v,a,b) {
    var n = parseInt(v, 10) - (d[a] ? x : 0) + (d[b] ? x : 0);
    return n < 0 ? 0 : n > wv ? wv : n;
}

$(window).keydown(function(e) { d[e.which] = true; });
$(window).keyup(function(e) { d[e.which] = false; });

setInterval(function() {
    box.css({
        left: function(i,v) { return newh(v, 37, 39); },
        top: function(i,v) { return newv(v, 38, 40); }
    });
}, 20);
});
Run Code Online (Sandbox Code Playgroud)

这本来就是我想要的.

如果您有基于%值的响应式设计,建议您调整setInterval,如下所示:

setInterval(function() {
    box.css({
        left: function(i,v) { return newh(v, 37, 39); },
        top: function(i,v) { return newv(v, 38, 40); }
    });
    wh = pane.width() - box.width();
    wv = pane.height() - box.height();
}, 20);
Run Code Online (Sandbox Code Playgroud)

如果你这样做它会调整你的窗格高度和宽度,盒子仍然停在边框.

我在这里做了一个小提琴http://jsfiddle.net/infidel/JkQrR/1/

非常感谢.