как переместить div с помощью клавиш со стрелками - PullRequest
17 голосов
/ 10 февраля 2011

Я бы хотел переместить div с помощью клавиш со стрелками, используя jQuery.Итак, вправо, влево, вниз и вверх.

Нашел демонстрацию того, чего я хочу достичь здесь

Я хотел бы иметь возможность перемещать div в другомdiv.

Как это можно сделать?

Ответы [ 5 ]

37 голосов
/ 10 февраля 2011

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.

setInterval, который выполняется каждые 20 мс, обновляет левый и верхний свойства CSS элемента box.Новые значения вычисляются с помощью функции 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);
7 голосов
/ 07 октября 2013

@ Шиме Видас: Ваше первое решение просто изумительно.(я думаю, что второй является избыточным =)

Могу ли я предложить сделать две разные функции для вертикальной и горизонтальной ширины?Потому что очень маловероятно, что вам придется перемещаться по 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/

Большое спасибо.

3 голосов
/ 10 февраля 2011

Я не вижу вашу демонстрацию, но вот простой пример "переместите окно на 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;
}

Markup:

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

Это всего лишь пример, вы можете добавить к нему проверку границ, большие движения, плавную анимацию, поддержку числовых клавиш или любое другое, но это должно помочь вам начать.

1 голос
/ 29 мая 2013

Чтобы сделать это повторно и немного удобным, я написал плагин для этой проблемы:

https://github.com/rhermann/moveByKeys

Веселитесь с ним.

0 голосов
/ 04 мая 2017

попробуйте этот код

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...