Главная » jQuery » Модальное окно с помощью CSS и jQuery

Модальное окно с помощью CSS и jQuery

Рассказывая о различных техниках сайтостроения, было бы нелепо не рассказать, о некоторых способах создания модальных окон. О назначении, полезности и возникающих проблемах использования всплывающих, модальных окон мы рассуждать не будем. Разберем лишь один из многочисленных примеров создания таких окошек.
Бывают ситуации когда нет возможности использовать специальные плагины, например такие как fancybox и prettyPhoto, поэтому стоит понять, как можно создать свое собственное .
 
Модальное окно на jQuery

Давайте посмотрим, как это сделать:

HTML

Начнем с добавления<a></a>тегов со следующими атрибутами:

  • href -#?w=500 указывает ширину окна
  • rel – уникальный атрибут для каждого окна
  • class="poplight" – класс для показа всплывающего окна
<a href="#?w=500" rel="popup_name" class="poplight">См. Окно в действии - Ширина = 500px</a>

Затем нам необходимо создать встроенную разметку для всплывающего окна. Разместить можно в любом месте страницы, ну например в нижней части содержания. Обратите внимание, что идентификатор всплывающего окна соответствует атрибуту rel тега <a></a>
Это и будет связывать ссылку и всплывающее окно вместе.

<div id="popup_name" class="popup_block">
    <h2>Заголовок</h2>
    <p>Любой текст,что душе угодно</p>
</div>

И так, с размещением нашего окна на странице мы разобрались, теперь давайте оформим его с помощью стилей, придадим ему, так сказать, благопристойный вид.
 

CSS Вёрстка

Для пущей ясности, я прописал некоторые пояснения к параметрам стиля нашего окошка. Так как всплывающие окна могут иметь разный размер, мы не указываем в CSS popup_block края окна, вычислить необходимый размер, это как раз задача для .

#fade { 
    display: none;/*--по умолчанию скрыто--*/ 
    background: rgba(7, 87, 207, 0.8);
    position: fixed; left: 0; top: 0;
    width: 100%; height: 100%;
    opacity: .80; 
    z-index: 9999;
}
.popup_block {
    display: none; /*--по умолчанию скрыто--*/
    background: #fff;
    padding: 20px;
    border: 8px solid rgb(134, 134, 134);
    float: left;
    font-size: 85%;
    position: fixed;
    top: 50%; left: 50%;color: #000;
    max-width: 750px;
    min-width: 320px;
    height: auto;
    z-index: 99999;
    /*--CSS3 тень блока--*/
    -webkit-box-shadow: 0px 0px 20px #000;
    -moz-box-shadow: 0px 0px 20px #000;
    box-shadow: 0px 0px 20px #000;
    /*--CSS3 скругление углов--*/
    -webkit-border-radius: 12px;
    -moz-border-radius: 12px;
    border-radius: 12px;
}
.popup_block p {	
    font-weight: 400;
    padding: 0;
    margin: 0;
    color: #000;
    line-height: 1.6;}
.popup_block h2 {
    margin: 0px 0 10px;
    color: rgb(43, 43, 43);
    font-weight: 400;
    text-align: center;
    text-shadow: 1px 1px 2px #0D0C0C;
}	
/* формируем кнопку закрытия */
.close {
    background-color: rgba(61, 61, 61, 0.8);
    border: 2px solid #ccc;
    height: 25px;
    line-height: 20px;
    position: absolute;
    right: -17px;
    font-weight: bold;
    text-align: center;
    text-decoration: none;padding: 0;
    top: -17px;
    width: 25px;
    -webkit-border-radius: 50%;
    -moz-border-radius: 50%;
    -ms-border-radius: 50%;
    -o-border-radius: 50%;
    border-radius: 50%;
    -moz-box-shadow: 1px 1px 3px #000;
    -webkit-box-shadow: 1px 1px 3px #000;
    box-shadow: 1px 1px 3px #000;
}
.close:before {
    color: rgba(255, 255, 255, 0.9);
    content: "X";
    font-size: 12px;
    text-shadow: 0 -1px rgba(0, 0, 0, 0.9);
}
.close:hover {
    background-color: rgba(252, 20, 0, 0.8);
}
.shadow {
    box-shadow:4px 4px 10px #857373;
   -webkit-box-shadow:4px 4px 10px #857373;
   -moz-box-shadow:4px 4px 10px #857373;
    padding:0;
}
/*--фиксированное позиционирование для IE6--*/
*html #fade {
    position: absolute;
}
*html .popup_block {
    position: absolute;
}

С формированием окна и его внешнего вида с помощью css, думаю особых сложностей не возникнет. Стили можете прописать непосредственно на странице HTML, между тегами <head> и </head>, а можете вынести в отдельный файл ваших стилей, обычно это файл style.css, или что-то в этом роде.

 

 

Настройка JQuery

Для полноценной работы модального окна, необходимо подключить jQuery, кто не знаком с работой этой библиотеки можете прочитать JQUERY — ВВОДНАЯ.

Ну, а мы пойдем дальше. Вы можете скачать самую последнюю версию JQuery с сайта библиотеки, или же использовать размещенный в недрах Google отдельный файл, подключив его к документу, в разделе перед закрывающим тегом </body>, разместив такую строку:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

После последнего обновления 15.01.2017, тестировал работу скрипта вплоть до версии jQuery 3.1.1, полёт нормальный ))).

Так же нам понадобится сам плагин, его тоже подключаем к странице, всё там же перед тегом </body>:

<script type="text/javascript" src="dm-modal.js"></script>

В следующем шаге рассмотрим начинку и функции плагина jquery, для активации нашего всплывающего окна, код содержит некоторые пояснения, для лучшего понимания того, что мы делаем.
 

Плагин JQuery

$(document).ready(function(){
   //При нажатии на ссылку с классом poplight и href атрибута тега <a> с #
	$('a.poplight[href*=\\#]').click(function() {
		var popID = $(this).attr('rel'); //получаем имя окна, важно не забывать при добавлении новых менять имя в атрибуте rel ссылки
		var popURL = $(this).attr('href'); //получаем размер из href атрибута ссылки
 
   //запрос и переменные из href url
		var query= popURL.split('?');
		var dim= query[1].split('&');
		var popWidth = dim[0].split('=')[1]; //первое значение строки запроса
 
   //Добавляем к окну кнопку закрытия
		$('#' + popID).fadeIn().css({ 'width': Number( popWidth ) }).prepend('<a href="#" title="Закрыть" class="close"></a>');
 
   //Определяем маржу(запас) для выравнивания по центру (по вертикали и горизонтали) - мы добавляем 80 к высоте / ширине с учетом отступов + ширина рамки определённые в css
		var popMargTop = ($('#' + popID).height() + 80) / 2;
		var popMargLeft = ($('#' + popID).width() + 80) / 2;
 
		//Устанавливаем величину отступа
		$('#' + popID).css({ 
			'margin-top' : -popMargTop,
			'margin-left' : -popMargLeft
		});
		//Добавляем полупрозрачный фон затемнения
		$('body').append('<div id="fade"></div>'); //div контейнер будет прописан перед тегом </body>.
		$('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn(); //полупрозрачность слоя, фильтр для тупого IE
 
		return false;
	});
   //Закрываем окно и фон затемнения
        $(document).on('click', 'a.close, #fade', function() { //закрытие по клику вне окна, т.е. по фону...
        $('#fade , .popup_block').fadeOut(function() {
        $('#fade, a.close').remove();  //плавно исчезают 
    });   
    return false;    
   });  
});

Заключение:

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

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

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

Обновление: Версия dm-modal.js v1.3 (15.01.2017)
Исправлено: Заменена устаревшая функция .live(), используется синтаксис href*=\\#. Теперь плагин работает с актуальными версиями библиотеки jQuery

На этом всё! Надеюсь, получился еще один полезный урок.

С Уважением, Андрей .

Буду всем признателен, если поддержите проект — добавив блог в исключения AdBlock и поделитесь ссылкой на запись в своих соц-сетях:

Вы можете оставить отзыв, подписаться на обновленияОбновления блога по RSSRSS или Обновления блога на TwitterTwitter !

150 комментариев
  1. Алексей:

    Добрый день!

    В header-e шаблона opencart есть следующее:

    Туда же, в хедер, вставляю див с модальным окном или формой,

    Заголовок

    Любой текст,что душе угодно

    Но в обоих случаях оно торчит на странице видимым куском, а не появляется по клику на картинку... Что-то я упустил, а что — не могу понять...

    Ответить
  2. Dmitriy:

    Доброго всем здоровица. У меня наверное дебильный вопрос, просто я в это деле новичёк.

    У меня сайт работает на движке Модекс. В нём следующая структура:

    Шаблоны

    Дополнительные поля

    Чанки

    Сниппеты

    Плагины

    Категории

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

    Я создал чанк, например ,в нём вверху прописал например:

    См. Окно в действии — Ширина = 500px

    затем ниже

    Заголовок

    Любой текст,что душе угодно

    затем в стили прописал ваш код

    В нужное мне место на сайте я подключил этот чанк, но

    куда прописывать

    //Когда вы нажмете на ссылку с классом poplight и HREF начинается с a # 
    $('a.poplight[href^=#]').click(function() {
        var popID = $(this).attr('rel'); //Get Popup Name
        var popURL = $(this).attr('href'); //Получить Popup HREF и определить размер
     
        //Запрос и  Переменные от HREF URL
        var query= popURL.split('?');
        var dim= query[1].split('&amp;');
        var popWidth = dim[0].split('=')[1]; //Возвращает первое значение строки запроса
     
        // Добавить кнопку "Закрыть" в наше окно, прописываете прямой путь к картинке
        $('#' + popID).fadeIn().css({ 'width': Number( popWidth ) }).prepend('&lt;a href="#" rel="nofollow"&gt;&lt;/a&gt;');
     
        //Определяет запас на выравнивание по центру (по вертикали по горизонтали)мы добавим 80px к высоте / ширине, значение полей вокруг содержимого (padding) и ширину границы устанавливаем в CSS
        var popMargTop = ($('#' + popID).height() + 80) / 2;
        var popMargLeft = ($('#' + popID).width() + 80) / 2;
     
        //Устанавливает величину отступа на Popup
        $('#' + popID).css({
            'margin-top' : -popMargTop,
            'margin-left' : -popMargLeft
        });
     
       //Постепенное затемнение фона
        $('body').append(''); //Добавляем fade тегу body.
        $('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn(); //Постепенное исчезание слоя - .css({'filter' : 'alpha(opacity=80)'}) используется для фиксации в IE , фильтр для устранения бага тупого IE 
     
        return false;
    });
     
    //Закрыть всплывающие окна и затемненный фон
    $('a.close, #fade').live('click', function() { //При нажатии на кнопку или затемненный фон.
        $('#fade , .popup_block').fadeOut(function() {
            $('#fade, a.close').remove();
        });
        return false;
    });
    });

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

    Ответить
    • driver:

      Код, что вы привели в комментарии, это содержимое исполняемого плагина jQuery. Заключите его в <script type="text/javascript">.....</script>, получится должно следующее:

      <script type="text/javascript">
      $(document).ready(function(){						   		   
      	//При нажатии на ссылку с классом poplight и href с a # 
      	$('a.poplight[href^=#]').click(function() {
      		var popID = $(this).attr('rel'); //Получить имя popup
      		var popURL = $(this).attr('href'); //Определить размер popup из href				
      		//Запрос и Переменные из HREF URL
      		var query= popURL.split('?');
      		var dim= query[1].split('&');
      		var popWidth = dim[0].split('=')[1]; //Возвращает первое значение строки запроса
       
      		//Добавить кнопку "Закрыть" в наше окно, прописываете прямой путь к картинке кнопки
      		$('#' + popID).fadeIn().css({ 'width': Number( popWidth ) }).prepend('<a href="#" title="Закрыть окно" class="close" rel="nofollow"></a>');		
      		//Определяет запас на выравнивание по центру (по вертикали по горизонтали)мы добавим 80px к высоте / ширине, значение полей вокруг содержимого (padding) и ширину границы устанавливаем в CSS
      		var popMargTop = ($('#' + popID).height() + 80) / 2;
      		var popMargLeft = ($('#' + popID).width() + 80) / 2;
       
      		//Применяем отступы в всплывающем окне
      		$('#' + popID).css({ 
      			'margin-top' : -popMargTop,
      			'margin-left' : -popMargLeft
      		});
      		//Фон слоя затемнения
      		$('body').append('<div id="fade"></div>'); //Добавляем слой затемнения.
      		$('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn(); //Постепенное исчезание слоя - .css({'filter' : 'alpha(opacity=80)'}) используется для фиксации в IE, фильтр для устранения бага тупого IE 
       
      		return false;
      	});
      	//Закрыть всплывающее окно и слой затемнения
      	$('a.close, #fade').live('click', function() { //При нажатии рядом, окно и слой затемнения закрываются 
      	  	$('#fade , .popup_block').fadeOut(function() {
      			$('#fade, a.close').remove();  
      	});	
      		return false;
      	});	
      });
      </script>

      Затем разместите эту конструкцию в подвале вашего шаблона, перед тегом </body>

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

      Ответить
  3. Иван:

    Автор крут молодец, что скачать можно

    Ответить
  4. Аня:

    Здравствуйте. Статья написана очень толково, но мне как новичку некоторые моменты не совсем понятны. У меня на странице много миниатюр картинок, большой размер которых нужно открыть в модальном окне. Где мне разместить ссылку на большие картинки? Иначе у меня открывается просто пустое окно. Заранее спасибо за ответ.

    Ответить
    • driver:

      Здесь:

      <div id="popup_name" class="popup_block"> Сюда картинку.... </div>

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

      Ответить
  5. andr:

    Спасибо! Буду пробовать сейчас.

    Как раз стоит задача сделать вывод видео с ютуба мелкими миниатюрами с всплывающим окном для показа в развернутом режиме на ½ экрана.

    Ответить
    • driver:

      За отзыв спасибо.

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

      То же самое и с модальным блоком видео на чистом CSS

      Ответить
  6. Cartman:

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

    Ответить
  7. Влад:

    Не работает с подгрузкой данных через ajax.

    Берет данные изначалього divа, а потому уже не центруется.

    Ответить
    • driver:

      Здравствуйте, Влад.

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

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

      Удачи!

      Ответить
  8. Александр:

    здравствуйте... можно ли это окно использовать для каталога...? на странице 12 div — блоков. в каждом блоке есть ссылка — подробнее... можно ли подключить все блоки ?

    Ответить
    • driver:

      Здравствуйте, Александр.

      Предусмотрена возможность использования неограниченного количества модальных окон. Главное следите за правильной связкой атрибута rel ссылки активации окна и уникального идентификатора id самого модального div-контейнера

      Так если в ссылке rel="popup-1" она откроет окно с id="popup-1", и так далее, при добавлении очередного модального окна (popup-2, popup-3 и т.п...)

      Это если я вас правильно понял)))

      Ответить
  9. vladimir:

    Добрый день.

    подскажите как в цикле вывести ссылки с окнами, только по каждой ссылке будет открываться вкладка с соответствующими данными

    for($q=0;$q<count($ideas_id);$q++) { <div id="popup_name" class="popup popup_block"> <h2><?=$ideas_name[$q];?> </h2> <p>Любой текст,что душе угодно</p> </div> }

    Ответить
  10. Stanislav:

    Забадалсся на вордпресс вставлять. Можно конкретно что и куда) Большое спасибо за помощь за ранее!

    Ответить
  11. Stanislav:

    В общем при подключении

    Окно работает, но пропадает меню сайта. Если не прописывать выше изложенный скрипт, то окно не работает.

    Как быть подскажите...

    Ответить
    • driver:

      Здравствуйте, Stanislav.

      Скорее всего у вас в теме присутствует какой-либо из элементов(то же меню, почему бы и нет), в работе которого необходима библиотека jQuery. WP автоматом подтягивает свою версию.

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

      Не знаю какая у вас тема, но в WP предусмотрен механизм безопасного подключения скриптов и jQuery в частности. Проверьте файл functions.php вашей темы на наличие такой функции:

      function jquery_init() { if (!is_admin()) { wp_enqueue_script('jquery'); } } add_action('wp_enqueue_scripts', 'jquery_init');

      Если отсутствует, что скорее всего, попробуйте прописать. Делается это для того чтобы избежать конфликт библиотек. Или же не подключайте дополнительную версию:

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

      как расписано в статье.

      Сам плагин, исполняемый js (см. фарш в статье) прописываете в файле темы footer.php в районе закрывающего тега </body>, предварительно обернув в

      <script type="text/javascript">..фарш js..</scrip>, это если не подключаете отдельным файлом dm-modal.js

      Не видя пациента трудно его лечить ))), Надеюсь всё у вас получится.

      Ответить
  12. Павел:

    Здравствуйте.

    Хорошее всплывающее окошко и пользоваться удобно, но вот с jQuery v2.2.4 не работает.

    Можно как-то поправить это или может будет новая версия данного скрипта?

    Спасибо.

    Ответить
    • driver:

      Здравствуйте, Павел.

      В jQuery v2.2.4 больше не поддерживается синтаксис href^=#, чтобы всё работало необходимо заменить его на href*=\\#. Для этого в файле dm-modal.js найдите строку:

      $('a.poplight[href^=#]').click(function()

      и просто замените в ней a.poplight[href^=#] на a.poplight[href*=\\#]

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

      Ответить
      • Ден:

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

        Ответить
      • Ден:

        Я как бы врубаюсь что это через history.pushstate делается, но конкретно к этому примеру не могу применить. Кто поможет, отблагодарю. Маякните на почту 2015500@rambler.ru

        Ответить
Присоединяйтесь к обсуждению!

Отправляя кoммeнтapий, Вы автоматически принимаете правила кoммeнтиpoвaния на этом блоге.

Правила кoммeнтиpoвaния на блоге Dobrovoimaster:

  1. Во избежание захламления спамом, первый кoммeнтapий всегда проходит премодерацию.
  2. В поле "Ваш сайт" лучше указывать ссылку на главную страницу вашего сайта/блога. Ссылки на прочую веб-лабуду (в том числе блоги/сплоги, созданные не для людей) будут удалены.
  3. Не используйте в качестве имени комментатора слоганы/названия сайтов, рекламные фразы, ключевые и т.п. слова. В случае несоблюдения этого условия, имя изменяю на свое усмотрение. Просьба указывать нормальное имя или ник.
  4. Скорее всего, что не информативный и короткий кoммeнтapий вида "Спасибо!", "Интересная статья", будет удален. Исключение составляют знакомые автору блога комментаторы.
  5. Комментарии не по теме безжалостно удаляются.

Подписаться не комментируя

Обновления комментариев по RSS RSS комментариев к этой записи »
Рейтинг@Mail.ru