- Popups with Javascript — A quick introduction
- Opening a popup
- Passing data between windows
- Demo
- Попап на чистом JS. Модальное окно без jQuery
- HTML-структура модального окна
- Стилизация всплывающего окна на чистом JS
- Показ всплывающего окна при клике
- Скрытие попап окна при клике на крестик
- Прячем попап окно на чистом js при клике на фон
Popups with Javascript — A quick introduction
We all know how annoying popups are. But have you ever thought how these popups work? How do popups interact with their parent windows? This article provides a quick introduction to working with popups in Javascript.
Opening a popup
A popup is just a new browser window that is usually displayed over the existing one. Javascript has a method to open a new window and control its behaviour.
window.open(url, name, features)
The open method is defined on the global window object. Hence it’s only available on the client side. The first argument is the URL to open. The second argument is either the name or target of the window. The window target is similar to the target attribute in the HTML anchor tag. A target of _blank opens the window separately and that of _self replaces the current page.
The third argument is the most useful of all. It is a comma separated list of features that we want the window to have. We can control the height, width, positioning, statusbar, menubar, scrollbar and many other things. For a complete list, refer to w3schools here. An example to open a popup is shown below:
window.open('https://google.com', 'Google', 'scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no, width=0,height=0,left=-1000,top=-1000')
This opens Google in an unresizable popup with no scrollbars, statusbar, toolbar, menubar which is centered on the screen.
Passing data between windows
We can only interact with the popup through the window that created it (parent window). The open() method returns a reference to the child window which we can use to alter the contents of the popup and programatically control it. There’s very limited control when it comes to opening popups with a different domain URL due to security reasons. For example, you can’t just inject a script in a website by opening it in a popup. With same domain popups, you can perform all operations on them just like you normally would.
let childPopup1 = window.open('https://google.com', 'google') // childPopup1 references the window object of the newly opened window // for example you can close the popup like so childPopup1.close() let childPopup2 = window.open('', 'My Popup') // childPopup2 opens a blank page // this is not cross-domain, hence you can do stuff like this childPopup2.document.write(``)
In order to pass data from child window to the parent window, there is a property window.opener which refers to the parent window object. You can use this to communicate events/data from child to parent window.
The parent HTML file is given above. One thing to note here is that every function or variable you define in the outermost scope is defined as a property on the window object (when run in browser). Hence the greet function can be called in two ways: greet(‘abc’) or window.greet(‘abc’) .
The child HTML file when opened inside of a popup can refer to the parent via window.opener and access the greet function in there. You can define functions in the parent window and invoke them from the child window, essentially passing events between the two.
Demo
I’ve put together a simple demo to show how popups can be used to login users. You can find it on glitch by clicking here. The source code is available on Github here. I’ll explain the main parts of the app here.
It is an Express powerd application using Handlebars to render the views. The homepage has a button that opens a popup which leads to a login screen where the user can enter their credentials and the response of the API is sent back to the home page which then handles successful/unsuccessful login attempts. The homepage view code is given below:
When the popup is closed, it sets a key in localStorage which tells the main window what action to take. If the login was successful, the main window confirms this by making an API call to obtain user’s profile using the cookie that was set by the server. This ensures that the screens after the homepage can only be accessed by a logged in user.
Enter any random credentials
The login page’s code is pretty self explanatory here: it runs the popupClosed function (from the parent window) when it gets closed. On a successful/unsuccessful login, it also sets a key in localStorage for some extra information. This means that if the key was not present in localStorage , the popup was force closed by the user and the UI can update accordingly. Similar is the case with other statuses.
I hope this quick introduction was useful and informative. If you have any doubts, comment below.
Попап на чистом JS. Модальное окно без jQuery
Приветствую, друзья, сегодня я покажу, как создать попап на чистом js. В данном всплывающем окне вы можете разместить что угодно. Например, форму для обратной связи (как в данном примере) или любой другой контент. Так же мы реализуем несколько способов скрытие модального окна. Первый способ — скрытие попап окна при клике на фон, а второй — при клике на крестик. Пример того, что вы получите в итоге, можно посмотреть по ссылке на codepen .
HTML-структура модального окна
Для начала создадим HTML разметку для нашего всплывающего окна на чистом JavaScript. Тут все достаточно просто, так что я просто размещу код. Единственное, что стоит упомянуть — вы можете вместо формы разместить любой HTML код.
Так же вам нужно добавить кнопку, при клике на которую нужно открывать окно. В моем случае, это тег с классом ‘open-popup’ .
Стилизация всплывающего окна на чистом JS
Далее необходимо стилизовать наш попап на чистом js. CSS код так же достаточно простой. Большинство кода это вовсе стилизация формы, которая никак не влияет на само окно. Важный код для урока я вынесу в самое начало вставки с кодом. Так же я отмечу её с помощью комментариев.
/* Важная часть */ .popup__bg < position: fixed; top: 0; left: 0; width: 100%; height: 100vh; background: rgba(0,0,0,0.5); opacity: 0; // Скрываем фон и сам попап pointer-events: none; // Запрещаем ему быть целью событий transition: 0.5s all; >.popup__bg.active < // При добавлении класса 'active' opacity: 1; // Показываем фон и попап pointer-events: all; // Возвращаем события transition: 0.5s all; >.popup < position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0); // Центрируем и масштабируем в 0 само окно background: #fff; width: 400px; padding: 25px; transition: 0.5s all; >.popup.active < // При добавлении класса 'active' transform: translate(-50%, -50%) scale(1); // Так же центрируем и плавно увеличиваем transition: 0.5s all; >/* Конец важной части */ /* Далее код для стилизации формы */ .close-popup < position: absolute; top: 10px; right: 10px; cursor: pointer; >.popup label < width: 100%; margin-bottom: 25px; display: flex; flex-direction: column-reverse; >.popup .label__text < font-size: 14px; text-transform: uppercase; font-weight: 500; color: #cfd0d3; margin-bottom: 5px; >.popup input < height: 45px; font-size: 18px; border: none; outline: none; border-bottom: 1px solid #cfd0d3; >.popup input:focus < border-bottom: 1px solid #2982ff; >.popup input:focus + .label__text < color: #2982ff; >.popup textarea < resize: none; width: 100%; height: 150px; border: none; outline: none; border-bottom: 1px solid #cfd0d3; font-size: 18px; padding-top: 5px; >.popup textarea:focus < border-bottom: 1px solid #2982ff; >.popup textarea:focus + .label__text < color: #2982ff; >.popup button < width: 100%; height: 45px; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 18px; border: 2px solid #2982ff; background: #2982ff; cursor: pointer; text-transform: uppercase; transition: 0.5s all; >.popup button:hover
Показ всплывающего окна при клике
Теперь переходим к самому интересному. Будем писать JavaScript код для модального окна. Для начала, создадим переменные, в которые мы поместим все DOM-елементы, которые нам понадобятся в будущем.
let popupBg = document.querySelector('.popup__bg'); // Фон попап окна let popup = document.querySelector('.popup'); // Само окно let openPopupButtons = document.querySelectorAll('.open-popup'); // Кнопки для показа окна let closePopupButton = document.querySelector('.close-popup'); // Кнопка для скрытия окна
Далее напишем код, для появления модального окна на чистом JavaScript. Для начала, нужно повесить обработчик события клика ( addEventListener ) на каждую кнопку открытия окна. При клике — указываем, что для фона и для самого окна нужно добавить класс ‘active’ . А так же предотвращаем стандартное поведение браузера, что бы при клике на ссылку браузер не прыгал вверх странички.
openPopupButtons.forEach((button) => < // Перебираем все кнопки button.addEventListener('click', (e) =>< // Для каждой вешаем обработчик событий на клик e.preventDefault(); // Предотвращаем дефолтное поведение браузера popupBg.classList.add('active'); // Добавляем класс 'active' для фона popup.classList.add('active'); // И для самого окна >) >);
Скрытие попап окна при клике на крестик
Тут код очень простой. Указываем, что при клике на крестик, нужно убрать активные классы с фона и самого окна.
closePopupButton.addEventListener('click',() => < // Вешаем обработчик на крестик popupBg.classList.remove('active'); // Убираем активный класс с фона popup.classList.remove('active'); // И с окна >);
Прячем попап окно на чистом js при клике на фон
Теперь разберемся как спрятать попап при клике на фон. Нужно повесить обработчик клика на весь документ. Далее необходимо передать событие (е). Если цель события (клик) — это фон окна, то мы так же убираем активные классы с фона и окна.
document.addEventListener('click', (e) => < // Вешаем обработчик на весь документ if(e.target === popupBg) < // Если цель клика - фот, то: popupBg.classList.remove('active'); // Убираем активный класс с фона popup.classList.remove('active'); // И с окна >>);
Спасибо, что прочитали. Если у вас остались вопросы — задавайте их в Telegram-канале или в комментариях на YouTube. Так же буду благодарен, если вы прочитаете другие мои статьи:
Full Stack разработчик, Frontend: Vue.js (2,3) + VueX + Vue Router, Backend: Node.js + Express.js. Раньше работал с РНР, WordPress, написал несколько проектов на Laravel. Люблю помогать людям изучать что-то новое)