JQueryを使用して矢印キーでdivを移動したいと思います。右、左、下、上。
私が達成したいことのデモを見つけた ここ
Divを別のdiv内で移動できるようにしたいと思います。
これはどのように行うことができますか?
HTML:
<div id="pane">
<div id="box"></div>
</div>
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:
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);
変数の説明:w
-ボックスが取り得る最大の左/上値(境界内に留まるため)x
-ボックスが各間隔で移動する距離(ピクセル単位)d
-このオブジェクトには、押されているキーに関する情報が格納されます。たとえば、ユーザーが左矢印キーを押している間、d['37']
はtrue
です。それ以外の場合はfalse
です。ところで、37
は左矢印キーのキーコードで、この値はe.which
イベントオブジェクトのプロパティ。 d
オブジェクトは、keydown
およびkeyup
イベントごとに更新されます。
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が返されます。
更新:このコードは、上記の元のコードと同じ機能を備えています。唯一の違いは、変数と引数にわかりやすい名前を使用したことです。ご覧のとおり、それはひどいように見えます-元のバージョンは明らかに優れています。 :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);
@ŠimeVidas:最初の解決策は単に素晴らしいものです。 (私は2番目のものは冗長だと思います=)
縦幅と横幅の2つの異なる関数を作成することを提案できますか?完全な四角形の内側の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);
});
これはまさに私が探していたものでしょう。
%値に基づくレスポンシブデザインがある場合は、次のように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);
これを行うと、ペインの高さと幅が調整され、ボックスは境界線で止まります。
ここでそれをいじった http://jsfiddle.net/infidel/JkQrR/1/
どうもありがとう。
デモは表示されませんが、簡単な「ボックスを矢印キーの方向に1ピクセル移動する」例を次に示します。
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;
}
マークアップ:
<div id="wrapper">
<div id="mover"></div>
</div>
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;
}
});
これは一例にすぎません。境界チェック、大きな動き、スムーズなアニメーション、テンキーのサポートなど、さまざまなものを追加したいと思うかもしれませんが、それで始められるはずです。
このコードを試してください
<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>