Стикер. Создаем плагин для jQuery.

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

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

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

Чтобы лучше объяснить принцип работы, я сделал демонстрационную страничку. По-умолчанию стикер находится около левого края окна, но вы можете переместить его в любую часть страницы. Если вы оставите его за пределами текста (над белым полем), то он плавно прижмется к краю страницы.

Demo
Source

Теперь перейдем к реализации.

Прежде всего, рассмотрим общий принцип перемещения блока по странице.

Для того чтобы перемещение блока не влияло на другие элементы на странице, он должен быть не связан с ними. Для этого используется CSS определение position: absolute.

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

Например, так.

#sticker {
    position: absolute;
    top: 200px;
    left: 0;
}

Сделать элемент перемещаемым (draggable) мы можем с помощью jQuery UI.

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

Рассмотрим, разметку HTML страницы.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <title>jQuery widget</title>

    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    
    <link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body>
    <div id="content">
        <!-- основное содержимое страницы -->
    </div>
    
    <div id="sticker">
        <img src="sticker.png" alt="sticker" />
    </div>
    
    <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
    <script type="text/javascript" src="js/jquery-ui-1.7.1.custom.min.js"></script>
    <script type="text/javascript" src="js/sticker.jquery.js"></script>
    <script type="text/javascript">
        $(function() {
            $("#sticker").sticker({stickingZone: 100, speed: 50});
        });
    </script>
</body>
</html>

Начало страницы самое обычное. Мы подключили файл со стилями и добавили какое-то содержимое.

Затем создали блок стикера (строки 17-19).

После этого подключили три js файла. Первый – библиотека jQuery, второй – плагин jQuery UI, третий – с нашим плагином (его мы создадим чуть ниже).

И сразу же обратите внимание на использование плагина (строка 26).

Чтобы превратить блок в стикер, нужно вызвать для него метод sticker, который принимает 2 параметра:

stickingZone – максимальное расстояние от стикера до края страницы при котором стикер будет «прилипать» к этому краю (в пикселах);

speed – скорость перемещения стикера при «прилипании» (если точнее, это время за которое стикер сместится к краю страницы, в миллисекундах).

Оба параметра не обязательные и если их опустить будут использованы значения, установленные по-умолчанию (30px и 300 мс).

Теперь создадим файл с CSS стилями (styles.css).

#sticker {
    position: absolute;
    width: 50px;
    height: 150px;
    top: 200px;
    left: 0;
}

.ui-draggable {
    cursor: move;
}

Зачем нужно абсолютное позиционирование я уже рассказывал, сейчас обратите внимание на второе правило, которое установлено для класса ui-draggable. Этот класс присваивает стикеру плагин jQuery UI после того, как мы делаем его перемещаемым (draggable). С его помощью очень удобно контролировать внешний вид элемента. В данном случае мы просто изменяем вид курсора.

Наконец, займемся плагином 😉

Прежде всего, обратите внимание на название файла. Оно должно начинаться с имени плагина после которого нужно добавить .jquery.js.

(function($) {
    $.fn.sticker = function(options) {
        var settings = $.extend({
            speed: 300
            , stickingZone: 30
        }, options||{});
        var element = $(this);
        element.draggable({ containment: 'parent' });
        element.bind('dragstop', function(event, ui) {
            var rightDistance = $(window).width() - ui.position.left - element.width();
            var leftDistance = ui.position.left;
            if (leftDistance < settings.stickingZone) {
                element.animate({left : "0"}, settings.speed);
            }
            if (rightDistance < settings.stickingZone) {
                var leftCorner = $(window).width() - element.width();
                element.animate({left : leftCorner + "px"}, settings.speed);
            }
        });
        return element;
    }
})(jQuery);

Взгляните на первую и последнюю строки плагина. Мы объявили функцию, которая принимает в качестве параметра $, и сразу же вызвали её с параметром jQuery.

С помощью такого приёма мы получаем возможность использовать внутри нашего плагина функцию $ и при этом не создаём проблем другим библиотекам (например, prototype), которые также используют $.

После этого мы создаем новый метод sticker (строка 2) (его название должно совпадать с названием плагина).

На этом этапе плагин создан, и его можно использовать. Правда он ничего не делает.

Исправляем этот недостаток.

1) Если при вызове плагина были указаны параметры, заменяем ими значения, установленные по-умолчанию (строки 3-6).

2) Сохраняем текущий элемент в переменной element.

3) Делаем этот элемент перемещаемым (draggable) (строка 8), параметр containment: 'parent' указывает, что стикер нельзя перемещать за границы родительского элемента.

4) Назначаем обработчик события dragstop (строки 9-19), которое возникает после того как пользователь отпустит стикер.

5) Принцип работы обработчика очень простой. Мы рассчитываем расстояния от стикера до правого и левого края страницы. А после этого сравниваем его с заданным значением (stickingZone). Если условие выполняется, перемещаем стикер к краю страницы. Для этого используем метод animate, в параметрах которого передаем координаты левого края стикера и время, за которое он должен переместиться.

6) Возвращаем текущий элемент (строка 20). Если этого не сделать, плагин работать будет, но мы не сможем использовать цепочки вызовов.

Как видите, плагин для jQuery создать совсем не сложно. Главное понимать, как получить желаемый эффект. В остальном, плагин не на много отличается от обычного метода.

Если возникли вопросы или замечания, пишите в комментариях, обсудим 😉