JavaScript и jQuery: перемещение блоков

Владимир | | HTML, JavaScript, Web разработка.

jquery blocks movement

В этот раз я покажу пример небольшого скрипта, позволяющего перемещать HTML блоки на странице.

Когда возникает подобная задача, первое что приходит в голову (по крайней мере мне 😉 ) – использовать готовые плагины. Например, jQuery Sortable. Что ни говори, решение довольно удобное, от пользователя требуется только перетащить объект с помощью мышки.

Но тут есть один недостаток. Если размеры блоков, которые нужно перемещать достаточно большие (например, больше половины высоты окна браузера), то пользоваться такими плагинами становится не удобно.

В такой ситуации, на мой взгляд, лучше добавить к каждому блоку ссылки «Вверх» и «Вниз» с помощью которых и будет выполняться перемещение блоков.

Именно такой вариант мы рассмотрим в этой статье.

Посмотреть результат можно на демонстрационной страничке

Demo

И, если есть желание, можете скачать архив с исходниками.

Source

Начнём с разметки страницы

Чтобы сделать блоки достаточно большими я просто разместил в них картинки, точнее в данном случае каждая картинка представляет собой отдельный блок.

<!DOCTYPE html>

<html>
<head>
    <meta charset="utf-8" />
    <title>Перемещение блоков с помощью JS</title>
    <link rel="stylesheet" type="text/css" href="styles.css" />
</head>

<body>
    <div id="images">
        <img src="images/1t.jpg" alt="картинка 1" />
        <img src="images/2t.jpg" alt="картинка 2" />
        <img src="images/3t.jpg" alt="картинка 3" />
    </div>

    <script src="http://yandex.st/jquery/1.4.4/jquery.js"></script>
    <script src="main.js"></script>
</body>
</html>

Как видите, разметка предельно простая. На странице находятся три картинки и подключены два JS файла (библиотека jQuery и наш скрипт main.js, с кодом для перемещения блоков).

Обратите внимание, я не вставлял ссылки «Вверх», «Вниз» на страницу. Перемещение блоков выполняется с помощью JavaScript, поэтому если у пользователя отключена поддержка JS, то и ссылки видеть ему не нужно.

Теперь рассмотрим перемещение блоков

Скрипт main.js.

$(function() {
    var images = $('img');
    images.wrap('<div class="controls" />');
    $('<a class="down" href="#">Вниз</a>').insertAfter(images);
    $('<a class="up" href="#">Вверх</a>').insertAfter(images);
    
    $('.up').click(function() {
        var currentImgBlock = $(this).parent();
        var prevImgBlock = currentImgBlock.prev();
        swap(currentImgBlock, prevImgBlock);
        return false;
    });
    
    $('.down').click(function() {
        var currentImgBlock = $(this).parent();
        var nextImgBlock = currentImgBlock.next();
        swap(nextImgBlock, currentImgBlock);
        return false;
    });
});

function swap(a, b) {
    if (a.size() > 0 && b.size() > 0) {
        a.insertBefore(b);
    }
}

Прежде всего, необходимо добавить ссылки. И, чтобы было удобнее выполнять перемещение, вокруг каждого изображения создадим div и ссылки будем добавлять в него.

Все эти операции выполняются с помощью четырёх строк кода (строки 2-5). В результате для каждого получим такую разметку.

<div class="controls">
    <img alt="картинка 1" src="images/1t.jpg">
    <a href="#" class="up">Вверх</a>
    <a href="#" class="down">Вниз</a>
</div>

Теперь назначаем обработчики для ссылок «Вверх» и «Вниз».

Код этих обработчиков практически одинаков, за исключением того, что при клике по ссылке «Вверх» мы должны получить текущий блок (в котором находится ссылка) и предыдущий, а при клике по ссылке «Вниз» — текущий и следующий.

После этого, передаём эти блоки функции swap, которая и выполняет их перемещение. Обратите внимание, что порядок в котором передаются блоки важен. Функция использует метод insertBefore, поэтому первым необходимо передавать блок, который должен оказаться выше.

Как видите, ничего сложного. Наверное, имеет смысл при клике по ссылке запускать какую-нибудь анимацию, чтобы было видно направление перемещения, но это тема отдельной статьи.

Если есть вопросы, замечания или советы, пишите. Буду рад обсудить!

Успехов!

  • Pingback: Tweets that mention JavaScript и jQuery: перемещение блоков -- Topsy.com()

  • Как сделать чтоб выбранная последовательность сохранялась юзером и оставалась такой же при следующем заходе?

    • Вам надо организовать сохранение сортировки пользователя, в куки, xml, бд и т.д.

    • Добавлю, что решать эту задачу для «общего случая» смысла нет. Потому что потом все равно придется «привязываться» к конкретному фреймворку или CMS.

    • Руслан

      И все же? Мне тоже интересно как сохранять последовательность!

      • Хорошо, давайте разбираться.

        Прежде всего, нужно как-то различать пользователей. Для этого используются различные скрипты аутентификации (например, ввод логина и пароля).

        Дальше нужно где-то на сервере сохранить данные сортировки и связать их с соответствующим пользователем. В большинстве случаев для этого будет использована БД. Но где именно хранить в ней порядок сортировки зависит от ее структуры. Возможно вам нужно будет создать дополнительную таблицу, или дополнительное поле в существующей таблице, или обойдетесь уже созданными полями.

        Затем нужно обеспечить передачу данных на сервер. Проще всего это сделать с помощью обычной формы со скрытым полем, в которое нужно записать порядок сортировки. Поле должно обновляться при каждом клике по стрелке.

        Какая из этих частей вас интересует?

        Думаю, вы уловили суть проблемы. Сама по себе сортировка никому не нужна, её имеет смысл использовать как одну из возможностей основного приложения. Поэтому и «подстраивать» её придется под это приложение.

  • Максим

    Вообще-то плагин sortable не так уж и плох, если б не его position:absolute . Если б было relative — он бы был намного удобней.

    • А я и не говорил, что он плох. Просто сам метод перетаскивания объектов не удобно использовать если объекты большие, т.к. область в которую нужно поместить объект легко может оказаться за пределами окна браузера.

      • Максим

        Я потому и говорю, что там position:relative нужен. У меня есть свое решение которое лишено подобных недостатков, но оно было написано на чистом javascript без jquery и его надо переписать.

        • В некоторых случаях решение на чистом JS может быть преимуществом.

  • Sergmix07

    Доброго времени суток! Очень помогла статься, но остался маленький вопросик! У меня в блоке находится iframe(TinyMCE) при перемещении блоков его содержимое исчезает, не подскажете как можно решить этот вопрос?

    • Никогда не пробовал двигать TinyMCE, поэтому не знаю с чем именно связана проблема. Но, в любом случае, можно сохранить его содержимое в какой-то переменной и восстановить его после перемещения.

      • Sergmix07

        Спасибо за ответ!

        • Evgeny

          И что получилось так сделать? 

        • Я не пробовал.

  • Технология 19-го века.