Javascript 如何使用箭头键移动div

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4950575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:55:42  来源:igfitidea点击:

how to move a div with arrow keys

javascriptjqueryeventshtml

提问by Opoe

I would like to move a div with my arrow keys using jQuery. So right, left, down and up.

我想使用 jQuery 用我的箭头键移动一个 div。所以向右,向左,向下和向上。

Found a demo of what I want to accomplish here

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

I would like to be able to move a div around in another div.

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

How can this be done?

如何才能做到这一点?

回答by ?ime Vidas

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);
#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;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="pane">
  <div id="box"></div>
</div>

Variable explanations:
w- the maximal left/top value that the box can have (to stay within bounds)
x- the distance (in px) that the box moves in each interval
d- this object stores the information on what key is being pressed. For instance, while the user holds down the LEFT ARROW key, d['37']is true. Otherwise it's false. BTW, 37is the key-code for the LEFT ARROW key and this value is stored in the e.whichproperty of the event object. The dobject is being updated on each keydownand keyupevent.

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

An setInterval which is executed every 20ms, updates the left and top CSS properties of the box element. The new values are calculated via the newvfunction.

每 20 毫秒执行一次的 setInterval 更新 box 元素的 left 和 top CSS 属性。新值通过newv函数计算。

The newvfunction will calculate the new left/top value based on a) the old value vand b) the dobject.

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

The expression n < 0 ? 0 : n > w ? w : nensures that the new value is in the permitted bounds (which are 0 to w). If n is < 0, zero will be returned. If n is > w, w will be returned.

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



Live demo: http://jsfiddle.net/simevidas/bDMnX/1299/

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



Update:This code has the same functionality as the original code above. The only difference is that I used more meaningful names for my variables and arguments. As you can see, it looks awful - the original version is clearly better. :P

更新:此代码与上面的原始代码具有相同的功能。唯一的区别是我为变量和参数使用了更有意义的名称。如您所见,它看起来很糟糕 - 原始版本显然更好。: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);

回答by infidel

@?ime Vidas: Your first solution is simply marvelous. (i think the second one is redundant =)

@?ime Vidas:您的第一个解决方案简直太棒了。(我认为第二个是多余的 =)

May i suggest to make two different functions for the vertical and the horizontal width? Because it's highly unlikely that you have to move around a div inside a perfect square and i believe it would be nicer to have something like this:

我可以建议为垂直和水平宽度制作两个不同的功能吗?因为你必须在一个完美的正方形内移动一个 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);
});

This would have been exactly what i was looking for.

这正是我正在寻找的。

If you had a responsive design based on % values it would be recommendable to adjust your setInterval like this:

如果您有基于 % 值的响应式设计,建议您像这样调整 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);

if you do that it adjusts your panes height and width and the box still stops at its border.

如果你这样做,它会调整你的窗格的高度和宽度,并且框仍然停在它的边框处。

i made a fiddle of that here http://jsfiddle.net/infidel/JkQrR/1/

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

Thanks a lot.

非常感谢。

回答by jball

I can't see your demo, but here's a simple "move the box 1px in the direction of the arrow keys" example:

我看不到您的演示,但这是一个简单的“将框沿箭头键方向移动 1px”的示例:

CSS:

CSS:

#wrapper { 
    background-color: gray; 
    height:200px; 
    width: 200px; 
    position:absolute;
}
#mover { 
    background-color: white; 
    border: 1px solid red;  
    height:20px; 
    width: 20px;
    position:relative;
}

Markup:

标记:

<div id="wrapper">
    <div id="mover"></div>
</div>

JS (using jQuery):

JS(使用 jQuery):

$("#wrapper").keydown(function(event) { 
    var $mover = $("#mover");
    //if nothing else will move "mover", then track the 
    //position instead of recalculating it every time:
    //   var moverPos = $mover.position();
    //   var left = moverPos.left;
    //   var top = moverPos.top;
    var addTop = function(diff) {
        $mover.css("top", ($mover.position().top + diff) + "px"); 
        //if using tracked position:
        //   top += diff;
        //   $mover.css("top", top) + "px");
    };

    var addLeft = function(diff) {
        $mover.css("left", ($mover.position().left + diff) + "px");
        //if using tracked position:
        //   left += diff;
        //   $mover.css("left", left) + "px");
    };

    switch(event.keyCode) {
        case 37: //left
            addLeft(-1); break; 
        case 38: //up
            addTop(-1); break;
        case 39: //right
            addLeft(1); break;
        case 40: //down
            addTop(1); break;
    }
});

This is just an example, you may want to add bounds checking, larger movements, smoother animation, number pad support or any number of other things to it, but it should get you started.

这只是一个例子,你可能想要添加边界检查、更大的动作、更流畅的动画、数字键盘支持或任何其他东西,但它应该让你开始。

回答by hojjat.mi

try This Code

试试这个代码

<html>
<head>
     <style>
          #ss{
               background:#ccc;
               height:100px;
               width:100px;
              position: absolute;
              top: 0;
              left: 0;
             }
     </style>
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
    </script>
</head>
<body>
  <div id="ss"></div>
</body>

<script type="text/javascript">     
var $div = $('#ss');
$(document).keydown(function(e) {
     switch (e.which) {
        case 37:
              $div.css('left', $div.offset().left - 10);
              break;
        case 38:
              $div.css('top', $div.offset().top - 10);
              break;
        case 39:
              $div.css('left', $div.offset().left + 10);
              break;
        case 40:
              $div.css('top', $div.offset().top + 10);
              break;
       }
  })
 </script>

 </html>