Пишем всплывающее окно на jQuery

JQuery это один из самых известных и самых популярных JavaScript фреймворков в мире. Сегодня мы напишем свое всплывающее окно на jQuery. Оно будет всплывать под элементом при клике на него.

Автор . Дата: 18.11.2014

Сегодня мы напишем свое всплывающее окно на jQuery. Оно будет всплывать под элементом при клике на него.

Для начала напишем функцию, которая будет возвращать координаты элемента:

jQuery.fn['bounds'] = function () {
    var bounds = {
        left: Number.POSITIVE_INFINITY,
        top: Number.POSITIVE_INFINITY,
        right: Number.NEGATIVE_INFINITY,
        bottom: Number.NEGATIVE_INFINITY,
        width: Number.NaN,
        height: Number.NaN
    };

    this.each(function (i,el) {
        var $el = $(el),
            off = $el.offset();
        off.right = off.left + $el.outerWidth();
        off.bottom = off.top + $el.outerHeight();

        if (off.left < bounds.left)
        bounds.left = off.left;

        if (off.top < bounds.top)
        bounds.top = off.top;

        if (off.right > bounds.right)
        bounds.right = off.right;

        if (off.bottom > bounds.bottom)
        bounds.bottom = off.bottom;
    });

    bounds.width = bounds.right - bounds.left;
    bounds.height = bounds.bottom - bounds.top;
    return bounds;
}

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

jQuery.fn.popupMsg = function(html, timeout)
{
    this.each(function ()
    {
        var $t = $(this);
        var b = $t.bounds();

        var $d = $('<div class="nopadding noclose popupMsg">' + html + '</div>').appendTo(document.body);
        
        $d.css({
                'left': b.left + b.width/2 - $d.outerWidth()/2,
                'top': b.top + b.height + 12,
                'opacity': 0
            });
        $d.animate({'opacity': 1}, 300);
        $d.uniqueId();

        $('<div class="close">x</div>').prependTo($d).click(function() {
            $(document).unbind('click.'+$d.attr('id'));
            $d.animate({'opacity': 0}, 300, function() { $(this).remove(); });
        })

        window.setTimeout(function() {
            $(document).bind('click.'+$d.attr('id'), function(e) {
                if (!$(e.target).closest('#' + $d.attr('id')).length) {
                    $(this).unbind('click.'+$d.attr('id'));
                    $d.animate({'opacity': 0}, 300, function() { $(this).remove(); });
                    e.stopPropagation();
                }
            });
        }, 1);

        if (timeout) {
            var timer = window.setTimeout(function() {
                $d.animate({'opacity': 0}, 300, function() { $(this).remove(); });
            }, timeout);

            $d.hover(
                function(){
                    window.clearTimeout(timer);
                },
                function(){
                    window.clearTimeout(timer);
                    timer = window.setTimeout(function(){
                        $d.animate({'opacity': 0}, 300, function() { $(this).remove(); });
                    }, 1700);
                }
            );
        }
    });
    return this;
};

Рассмотрим её подробнее. Сначала мы получаем указатель на наш элемент и его координаты. Указатель на элемент будет расположен в переменной $t а координаты в b. После чего мы создаем блок нашего всплывающего окна и добавялем его в тело html документа:

var $d = $('<div class="nopadding noclose popupMsg">' + html + '</div>').appendTo(document.body);

После мы располагаем наш блок под элементом:

        $d.css({
                'left': b.left + b.width/2 - $d.outerWidth()/2,
                'top': b.top + b.height + 12,
                'opacity': 0
            });

 Плавно показываем:

$d.animate({'opacity': 1}, 300);

И присваиваем уникальный индентификатор:

$d.uniqueId();

В следующем блоке кода мы добавляем кнопку для закрытия нашего всплывающего окна и вешаем на неё обработчик click, по которому будет происходить плавное закрытие нашего окна:

        $('<div class="close">x</div>').prependTo($d).click(function() {
            $(document).unbind('click.'+$d.attr('id'));
            $d.animate({'opacity': 0}, 300, function() { $(this).remove(); });
        })

Так же мы вешаем обработчик click на весь документ, чтобы при клике не на всплывающем окне оно закрывалось:

        window.setTimeout(function() {
            $(document).bind('click.'+$d.attr('id'), function(e) {
                if (!$(e.target).closest('#' + $d.attr('id')).length) {
                    $(this).unbind('click.'+$d.attr('id'));
                    $d.animate({'opacity': 0}, 300, function() { $(this).remove(); });
                    e.stopPropagation();
                }
            });
        }, 1);

И, если у нас указан таймаут закрытия всплывающего окна, то закрываем его по таймауту:

        if (timeout) {
            var timer = window.setTimeout(function() {
                $d.animate({'opacity': 0}, 300, function() { $(this).remove(); });
            }, timeout);

            $d.hover(
                function(){
                    window.clearTimeout(timer);
                },
                function(){
                    window.clearTimeout(timer);
                    timer = window.setTimeout(function(){
                        $d.animate({'opacity': 0}, 300, function() { $(this).remove(); });
                    }, 1700);
                }
            );
        }

Использовать нашу функцию можно следующим образом:

$('#buy_btn').popupMsg('<div class="added-to-cart"><div class="caption">Товар добавлен в корзину</div><a class="button" href="/personal/cart/">Оформить заказ</a></div>', 5000);

Первым аргументом для неё является html код, который нужно отобразить в всплывающем окне, а вторым таймаут, через который окно будет закрыто. Добавляем стили, и получаем примерно такое красивое окошко: