如何用箭头键移动div

时间:2022-01-16 17:27:26

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?

如何才能做到这一点?

5 个解决方案

#1


36  

HTML:

HTML:

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

CSS:

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;
}

JavaScript:

JavaScript的:

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);

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, 37 is the key-code for the LEFT ARROW key and this value is stored in the e.which property of the event object. The d object is being updated on each keydown and keyup event.

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

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 newv function.

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

The newv function will calculate the new left/top value based on a) the old value v and b) the d object.

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

The expression n < 0 ? 0 : n > w ? w : n ensures 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到w)。如果n <0,则返回零。如果n> w,则返回w。


Live demo: 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);

#2


5  

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

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

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.

非常感谢。

#3


3  

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.

这只是一个例子,您可能希望添加边界检查,更大的移动,更平滑的动画,数字键盘支持或任何其他数量的东西,但它应该让你开始。

#4


1  

To make it reuse, and a bit convenient, I wrote a plugin for that issue on:

为了使它重用,并且有点方便,我为这个问题编写了一个插件:

https://github.com/rhermann/moveByKeys

https://github.com/rhermann/moveByKeys

Have fun with it.

玩得开心。

#5


0  

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>

#1


36  

HTML:

HTML:

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

CSS:

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;
}

JavaScript:

JavaScript的:

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);

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, 37 is the key-code for the LEFT ARROW key and this value is stored in the e.which property of the event object. The d object is being updated on each keydown and keyup event.

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

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 newv function.

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

The newv function will calculate the new left/top value based on a) the old value v and b) the d object.

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

The expression n < 0 ? 0 : n > w ? w : n ensures 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到w)。如果n <0,则返回零。如果n> w,则返回w。


Live demo: 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);

#2


5  

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

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

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.

非常感谢。

#3


3  

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.

这只是一个例子,您可能希望添加边界检查,更大的移动,更平滑的动画,数字键盘支持或任何其他数量的东西,但它应该让你开始。

#4


1  

To make it reuse, and a bit convenient, I wrote a plugin for that issue on:

为了使它重用,并且有点方便,我为这个问题编写了一个插件:

https://github.com/rhermann/moveByKeys

https://github.com/rhermann/moveByKeys

Have fun with it.

玩得开心。

#5


0  

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>