Подгрузка контента при прокрутке (бесконечная лента)

Пример реализации «Бесконечной ленты» с применением PHP, БД MySQL, и JQuery Ajax.

Формирование списка
Первый PHP-скрипт выводит только первые 12 записей из таблицы `prods` (записей может быть и больше, главное чтобы высота блока была больше высоты окна браузера).

Ниже, списка товаров выводится
<div id="showmore-triger">, который выполняет роль индикатора загрузки с гифкой ajax-loader.gif и того что пользователь уже доскроллил до этого элемента.

<?php
// Кол-во элементов
$limit = 12; 
 
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'логин', 'пароль');
 
// Получение записей для первой страницы
$sth = $dbh->prepare("SELECT * FROM `prods` LIMIT {$limit}");
$sth->execute();	
$items = $sth->fetchAll(PDO::FETCH_ASSOC);	
 
// Кол-во страниц 
$sth = $dbh->prepare("SELECT COUNT(`id`) FROM `prods`");
$sth->execute();
$total = $sth->fetch(PDO::FETCH_COLUMN);
$amt = ceil($total / $limit);
?>
	
<div id="showmore-list">
	<div class="prod-list">
		<?php foreach ($items as $row): ?>
		<div class="prod-item">
			<div class="prod-item-img">
				<img src="/images/<?php echo $row['img']; ?>" alt="">	
			</div>
			<div class="prod-item-name">
				<?php echo $row['name']; ?>		
			</div>
		</div>
		<?php endforeach; ?>
	</div>
</div>
 
<div id="showmore-triger" data-page="1" data-max="<?php echo $amt; ?>">
	<img src="ajax-loader.gif" alt="">
</div>


CSS-стили:
#showmore-triger {
	text-align: center;
	padding: 10px;
	background: #ffdfdf;
}
 
/* Вывод товаров */
.prod-list {
	overflow: hidden;
	margin: 0 0 20px 0;
}
.prod-item {
	width: 174px;
	height: 230px;
	float: left;
	border: 1px solid #ddd;
	padding: 20px;
	margin: 0 20px 20px 0;
	text-align: center;
	border-radius: 6px;
}
.prod-item-img {
	width: 100%;
}
.prod-item-name {
	font-size: 13px;
	line-height: 16px;
}
 
.prod-list .prod-item:nth-child(3n) {
	margin-right: 0
}


JS-скрипт подгрузки контента
В нём отслеживается скроллинг страницы и в нужный момент отправляется AJAX-запрос на /ajax.php?page=x с номером следующей страницы, который возвращает следующую страницу записей, далее они вставляются в общий список.

При выводе всех страниц из БД, элемент с id="showmore-triger" удаляется методом JQuery remove() – он удаляет элемент из дерева DOM, а также все его JS-события.

<script src="/jquery/2.1.1/jquery.min.js"></script>
 
<script>
var block_show = false;
 
function scrollMore(){
	var $target = $('#showmore-triger');
	
	if (block_show) {
		return false;
	}
 
	var wt = $(window).scrollTop();
	var wh = $(window).height();
	var et = $target.offset().top;
	var eh = $target.outerHeight();
	var dh = $(document).height();   
 
	if (wt + wh >= et || wh + wt == dh || eh + et < wh){
		var page = $target.attr('data-page');	
		page++;
		block_show = true;
 
		$.ajax({ 
			url: '/ajax.php?page=' + page,  
			dataType: 'html',
			success: function(data){
				$('#showmore-list .prod-list').append(data);
				block_show = false;
			}
		});
 
		$target.attr('data-page', page);
		if (page ==  $target.attr('data-max')) {
			$target.remove();
		}
	}
}
 
$(window).scroll(function(){
	scrollMore();
});
	
$(document).ready(function(){ 
	scrollMore();
});
</script>

Код файла ajax.php
Скрип получает обрабатывает переменную $_GET['page'] и нужны записи из БД.

<?php
// Кол-во элементов
$limit = 12; 
 
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'логин', 'пароль');
 
// Получение записей для текущей страницы
$page = intval(@$_GET['page']);
$page = (empty($page)) ? 1 : $page;				
$start = ($page != 1) ? $page * $limit - $limit : 0;
$sth = $dbh->prepare("SELECT * FROM `prods` LIMIT {$start}, {$limit}");
$sth->execute();	
$items = $sth->fetchAll(PDO::FETCH_ASSOC);				
 
foreach ($items as $row) {
	?>
	<div class="prod-item">
		<div class="prod-item-img">
			<img src="/images/<?php echo $row['img']; ?>" alt="">	
		</div>
		<div class="prod-item-name">
			<?php echo $row['name']; ?>		
		</div>
	</div>
	<?php
}

Добавлено: 10 Января 2022 07:34:19 Добавил: Андрей Ковальчук

Как показать скрыть часть пунктов из списка

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

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

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

<ul class="list">
<li>Пункт номер раз</li>
<li>Пункт номер два</li>
<li>Пункт номер три</li>
<li>Пункт номер четыре</li>
<li>Пункт номер пять</li>
<li>Пункт номер шесть</li>
<li>Пункт номер семь</li>
<li>Пункт номер восемь</li>
<li>Пункт номер девять</li>
<li>Пункт номер десять</li>
</ul>
<div class="show_hide_list">Смотреть все</div>

Тут все просто. Задаем список и присваиваем ему класс list. Можете указать свой, только в скрипте тоже надо будет указать свой новый класс. Так же, обязательно. нужно добавить кнопку, в нашем случаи это просто блок, с классом show_hide_list.

Второй шаг, добавляем стили для нашего списка и кнопки:
ul.list li:nth-child(n+6){display:none;}
.show_hide_list{cursor:pointer;display:inline-block;text-align:center;padding:10px;background:#fc0;}

Главная строка первая, она обязательна, потому как скрывает все пункты, начиная с шестого. Если вы хотите скрывать с седьмого или со второго и тд, то измените на свой. Так же надо будет изменить и в скрипте. Вторая строка - это стили для кнопки Смотреть все. Ей можете задавать свои стили, которые вам нравятся больше.

Теперь мы должны убедится что к сайту уже подключена библиотека jQuery. Если нет, то это нужно сделать.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

Следующий шаг, подключение уже самого скрипта, который будет осуществлять показ, скрытие пунктов из списка. Его нужно подключить после библиотеки, которую мы подключали выше. Можете воспользоваться той же инструкцией с подсказками как это сделать правильно.
jQuery(document).ready(function($){
if($('ul.list').find('li').length > 5){
$('.show_hide_list').click(function(){
$('ul.list li:nth-child(n+6)').slideToggle('');
$(this).toggleClass('opnd_g');
if($(this).hasClass('opnd_g')){
$(this).html('Скрыть');}
else {$(this).html('Смотреть все');}
});
}else{$('.show_hide_list').hide();}
});

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

if($('ul.list').find('li').length > 5){ - Задаем условие. Если у нашего списка, что имеет класс - .list имеются пункты li и их количество больше пяти.
$('.show_hide_list').click(function(){ - Запускаем функцию, которая сработает, если мы нажмем на элемент страницы с классом show_hide_list, то бишь на нашу кнопку, что расположена после списка.
$('ul.list li:nth-child(n+6)').slideToggle(''); - После нажатия показываем пункты с шестого и до последнего. Если вы поменяли количество в стилях, то меняйте и здесь соответственно.
$(this).toggleClass('opnd_g'); - Добавляем нашей кнопке после нажатия класс opnd_g.
if($(this).hasClass('opnd_g')){ - Создаем условие, что если наша кнопка имеет класс opnd_g, то...
$(this).html('Скрыть');} - То меняем текст в кнопке - Смотреть все на Скрыть.
else {$(this).html('Смотреть все');} - Или, если после нажатия на кнопку класса opnd_g нет, то меняем текст на кнопке снова на Смотреть все.
}); - Просто заканчиваем наше условие по нажатию на кнопку.
}else{$('.show_hide_list').hide();} - а это противоположное действие изначальному условию со второй строки, которое задавало действие если пунктов больше 5. То бишь, если пунктов меньше пяти, кнопка Смотреть все - будет скрыта полностью, чтобы не вводить в заблуждение посетителей сайта.

UPD: 11.12.2019

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

Кнопка должна быть сразу под списком! Иначе способ не сработает.

// ЗАМЕНИТЬ ЭТО
$('ul.list li:nth-child(n+6)').slideToggle('');
// НА ЭТО
$(this).prev().children('li:nth-child(n+6)').slideToggle('');

Вот и весь скрипт. Он простенький и справляется с задачей. Теперь вы сможете его если захотите на странице вашего сайта скрыть несколько пунктов вашего списка.

Добавлено: 06 Июня 2021 04:35:41 Добавил: Андрей Ковальчук

Как изменить или отключить чекбокс — Сохранить моё имя, email и адрес сайта в этом браузере для последующих моих комментариев

В связи с тем, что сейчас все больше и больше стран принимает законы об обработке персональных данных, то как и в других системах управления сайта, так и WordPress появляются изменения, чтобы не нарушать дынные законы. Чекбокс о запросе сохранения имя и email, как раз таки, одно из таких изменений. Он работает по следующему принципу - когда посетитель сайта активирует чекбокс и дает свое согласие на хранение своих данных в браузере, в следующий раз, когда он будет находится на страницах того сайта где он его активировал, его персональные данные - имя и email автоматически заполнятся в полях.

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

Для начала рассмотрим вариант с полным отключением чекбокса. Для этого вам нужно добавить в файл функций вашей темы - functions.php, небольшую функцию. Если вы не ориентируетесь в функциях этого файла, то добавляете в самый конец перед закрывающим тегом PHP ?>. Если его нет, то просто в самый конец.

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


/* ОТКЛЮЧАЕМ ЧЕКБОКС */
function comment_hide_checkcdpr( $fields ) {
    unset( $fields['cookies'] );
    return $fields;
}
add_filter( 'comment_form_default_fields', 'comment_hide_checkcdpr' );

Тут все просто, особо разбирать нечего, каких-то настроек нет. Далее разберем вариант, когда чекбокс надо оставить, но подпись к нему изменить. Как и с первым кодом, добавляйте данную функцию туда же.
/* МЕНЯЕТ ТЕКСТ ЧЕКБОКСА */
function comment_change_checkcdpr( $fields ) {
    $fields['cookies'] = '<p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes" />' .
    '<label for="wp-comment-cookies-consent">Сохранить имя и email.</label></p>';
    return $fields;
}
add_filter( 'comment_form_default_fields', 'comment_change_checkcdpr' );

В 2 и 3 строке сам чекбокс и label к нему. Как раз содержимое label, вам и нужно менять. В данном примере стандартная надпись заменена на Сохранить имя и email. Кстати, данный код можно добавить на сайт, если у вас нет чекбокса и вы хотите его иметь.

Еще как бонус, хочу предложить вариант данного кода с дополнительной функцией, проверки сохранял ли данный пользователь ранее данные. Если сохранял - чекбокс будет отмечен. По сути это тот же код, только с маленькими правками.
/* МЕНЯЕТ ТЕКСТ ЧЕКБОКСА И ДЕЛАЕМ ЧЕКБОКС АКТИВНЫМ, ЕСЛИ РАНЕЕ СОХРАНЯЛИСЬ ДАННЫЕ */
function comment_change_checkcdpr( $fields ){
    $user_ca = wp_get_current_commenter();
    $checked = empty( $user_ca['comment_author_email'] ) ? '' : ' checked="checked"';
    $fields['cookies'] = '<p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"' . $checked . ' />' .
    '<label for="wp-comment-cookies-consent">Сохранить имя и email.</label></p>';
    return $fields;
}
add_filter( 'comment_form_default_fields', 'comment_change_checkcdpr' );

Давайте рассмотрим, какие изменения добавлены в этой версии функции.

Во второй строке создаем переменную $user_ca и задаем ей значение - wp_get_current_commenter() .wp_get_current_commenter() - это функция, которая получает имя, почту, URL сайта текущего комментатора из куков.
В третей строке создаем еще одну переменную - $checked и ее значение, это проверка сохраненные ли у данного комментатора в браузере имя и почта к вашему сайту. Если это так, то чекбоксу прописывается параметр checked="checked". То бишь, комментатору который уже давал согласие, не нужно вновь отмечать чекбокс.
Последнее, это выводим нашу переменную $checked в 4 строке в параметрах самого чекбокса.
Вот и весь материал. Он простенький и справляется с задачей. Теперь вы сможете загружать менять или отключать данный чекбокс с проверкой на сохранение персональных данных. Надеюсь, данный материал помог вам.

Добавлено: 28 Мая 2021 07:20:10 Добавил: Андрей Ковальчук

Как изменять стрелки в input number, как задать свои стили

Почему я предлагаю данный урок, потому что если вы создаете посадочные страницы, интересные формы, просто красивые сайты, то использование стандартных полей типа числовых недопустимо. они имеют ужасный вид. Если еще в хроме не так страшно, то в Мозилле - ой как все плохо.

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

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

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

Сам скрипт имеет следующий вид, его подключать надо ниже библиотеки в коде.
<script>
jQuery(document).ready(function($){
    jQuery('<div class="quantity-nav"><div class="quantity-button quantity-up">+</div><div class="quantity-button quantity-down">-</div></div>').insertAfter('.quantity input');
    jQuery('.quantity').each(function() {
      var spinner = jQuery(this),
        input = spinner.find('input[type="number"]'),
        btnUp = spinner.find('.quantity-up'),
        btnDown = spinner.find('.quantity-down'),
        min = input.attr('min'),
        max = input.attr('max');
 
      btnUp.click(function() {
        var oldValue = parseFloat(input.val());
        if (oldValue >= max) {
          var newVal = oldValue;
        } else {
          var newVal = oldValue + 1;
        }
        spinner.find("input").val(newVal);
        spinner.find("input").trigger("change");
      });
 
      btnDown.click(function() {
        var oldValue = parseFloat(input.val());
        if (oldValue <= min) {
          var newVal = oldValue;
        } else {
          var newVal = oldValue - 1;
        }
        spinner.find("input").val(newVal);
        spinner.find("input").trigger("change");
      });
 
    });
});
</script>

Суть скрипта в том, что он добавляет после числового поля блок - quantity-nav, с двумя дочерними блоками quantity-button, которым так же присвоены свои классы - quantity-up и quantity-down. Это будущие две кнопки + и -, что соответственно будут увеличивать и уменьшать числовое значение в поле.

После добавления блока с кнопками для поля, скрипт отслеживает нажатия на кнопки сравнивает с значением в поле и если значение нужно сменить - уменьшить и увеличить, то меняет его. Все просто, кто знаком с jQuery, разберется без проблем.

Само числовое поле, которое есть у вас при верстке нужно обернуть в родительский блок с классом - quantity (Вы можете менять названия классов на свои, но не забывайте менять их в скрипте и в стилях, чтобы все соответствовало!). Выглядеть, это должно примерно так:
<div class="quantity">
  <input type="number" min="1" max="9" step="1" value="1">
</div>

Значения и настройки поля у вас будут свои, но суть понятна. Для корректного отображения - добавляете стили. Примерный набор такой:
.quantity {
  position: relative;
  text-align:center;
  display:inline-block;
}
 
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button
{
  -webkit-appearance: none;
  margin: 0;
}
 
input[type=number]
{
  -moz-appearance: textfield;
}
 
.quantity input {
  width: 45px;
  height: 42px;
  line-height: 1.65;
  float: left;
  display: block;
  padding: 0;
  margin: 0;
  padding-left: 20px;
  border: 1px solid #eee;
}
 
.quantity input:focus {
  outline: 0;
}
 
.quantity-nav {
  float: left;
  position: relative;
  height: 42px;
}
 
.quantity-button {
  position: relative;
  cursor: pointer;
  border-left: 1px solid #eee;
  width: 20px;
  text-align: center;
  color: #333;
  font-size: 13px;
  line-height: 1.7;
  transform: translateX(-100%);
  user-select: none;
  font-weight:bold;
}
 
.quantity-button.quantity-up {
  position: absolute;
  height: 50%;
  top: 0;
  border-bottom: 1px solid #eee;
}
 
.quantity-button.quantity-down {
  position: absolute;
  bottom: -1px;
  height: 50%;
}

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

Добавлено: 04 Мая 2021 07:27:01 Добавил: Андрей Ковальчук

Как подгружать iframe с задержкой

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

Работает все это, следующим образом. Сначала вам нужно добавить сам скрипт. Это обычный JavaScript, который нужно добавить к себе на сайт. Добавлять его можно куда угодно, если вы разбираетесь в верстке и понимаете, что подразумевает под собой фраза - куда угодно.

<script>
window.onload = function(){
    setTimeout(function(){
    document.getElementById('my_ifrm').src = 'https://www.youtube.com/embed/LXb3EKWsInQ';
    },5000);
};
</script>

Так же, вы должны, само собой, добавить сам iframe на сайт ,если он добавлен, то ему надо добавить ID. В данном примере - это my_ifrm.

Допустим, вам надо тоже загрузить с задержкой ролик с ютуба. Вы получаете стандартный код от Youtube и выглядит он примерно так:
<iframe width="560" height="315" src="https://www.youtube.com/embed/LXb3EKWsInQ" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Вам нужно сначала добавить нужный айди для iframe, а так же указать его в скрипте и изъять ссылку с iframe и добавить ее опять же в скрипт. Готовый iframe получится примерно таким:
<iframe width="560" height="315" id="my_ifrm" src=""  frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

Как видите у нас изменилось это - id="my_ifrm" src="". По желанию можете удалить размеры iframe, если задаете их через CSS, а так же другие, лишние параметры Youtube или самого iframe, если знаете для чего они.

Вернемся к самому скрипту. В третей его строке как раз и указан айди нашего iframe и ссылка, которую мы изъяли ранее.
document.getElementById('my_ifrm').src = 'https://www.youtube.com/embed/LXb3EKWsInQ';

В предпоследней строке есть значение 5000 - это 5 секунд в миллисекундах. Это именно то время, после которого будет загружен наш iframe.

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

Подключение выглядит так:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

Сам скрипт имеет следующий вид:
<script>
jQuery(document).ready(function($){
var src   = "https://www.youtube.com/embed/LXb3EKWsInQ"; 
$(function(){
  setTimeout(function(){
    $('#my_ifrm').attr('src',src)
  }, 5000);
});
});
</script>

В скрипте указываете ссылку, как и в предыдущем. Айди элемента, так же можно класс или селектор. Ну и само собой время, задержки перед загрузкой.

Вот и весь скрипт. Он простенький и справляется с задачей. Теперь вы сможете загружать iframe с задержкой.

Добавлено: 15 Апреля 2021 07:21:44 Добавил: Андрей Ковальчук

Как сделать адаптивное видео YouTube на сайте

Если вы размещали код YouTube у себя на сайте то заметили что видео выводится с помощью тега iframe. Обычно код видео имеет примерно такой вид:

<iframe width="560" height="315" src="https://www.youtube.com/embed/TdRllKvKi9k" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

Даже по коду видно что по-умолчанию для видео уже заданы размеры плеера. Изначально размеры такие - 560 пикселей ширина и 315 пикселей высота. На большом экране и при нормальной ширине вашего сайта, такой размер вполне допустимый, но если ширина экрана устройства 420 пикселей? Результат - плеер вылазит за границы видимой части и сайт выглядит криво и неправильно. Как же решить данную задачу?

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

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

Для начала. вам нужно будет разместить код внутри блока. Также блоку присвоим любой класс, например - frame_blc.
<div class="frame_blc">
  <iframe width="560" height="315" src="https://www.youtube.com/embed/Y421bWMelqE" frameborder="0" allowfullscreen></iframe>
</div>

Теперь, нужно добавить универсальные стили, которые и будут адаптировать размер плеера YouTube.
.frame_blc{
  overflow:hidden;
  position:relative;
  padding-bottom:56.25%;
  padding-top:30px;
  height:0;
}
.frame_blc iframe {
  position:absolute;
  width:100%;
  height:100%;
  left:0;
  top:0;
}

По сути мы делаем адаптивным наш родительский блок, а сам плеер делаем с абсолютным позиционированием и растягиваем на всю ширину и высоту относительно родителя. Для блока основным параметром, на который следует обратить внимание, является - padding-bottom:56.25%. Он задает высоту родительского блока для плеера у которого видеоролик имеет соотношения сторон 16:9. Если Ваш видеоролик имеет соотношения 4:3, то параметр будет - padding-bottom:75%.

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

Добавлено: 10 Марта 2021 10:51:52 Добавил: Андрей Ковальчук

Закрытие элемента при клику за его пределами

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

О том как сделать подобные окна, подробно мы останавливаться не будем. На моем сайте есть много статей на подобные темы.

Теперь подробнее о скрипте. Он работает на основе jQuery,поэтому, мы должны убедится что к сайту уже подключена библиотека jQuery. Если нет, то это нужно сделать.

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

После библиотеки нужно подключить наш скрипт.
Выглядит скрипт так:
$(document).mouseup(function (e){
var modalctr = $("#modal_cinw_ctnr");
var modal = $(".modal_cinw");
if (!modal.is(e.target) && modal.has(e.target).length === 0){
modalctr.hide();
}
});

Скрипт имеет важные параметры, настройка которых нужна для корректной работы скрипта.

$(document).mouseup(function (e){ - эта строка определяет, что скрипт будет работать когда отпущена любая из стандартных клавиш мыши.

var modalctr = $("#modal_cinw_ctnr"); - создаем переменную. В данном случаи это родительский контейнер окна. В примере это затемненная область поверх сайта. Иногда такой области нет, все зависит от типа вашего окна или другого элемента который вы хотите скрыть по клику вне его области.
#modal_cinw_ctnr - это айди нашего родительского контейнера. Меняйте на свой нужный.

var modal = $(".modal_cinw"); - создаем вторую переменную. Как раз эта переменная и является нашим окном, нажимая вне его области и будет скрываться именно оно. .modal_cinw - класс нашего окна. Вы можете менять на айди или класс, вашего элемента, что нужно скрыть.

if (!modal.is(e.target) && modal.has(e.target).length === 0){ - в этой строке мы определяем был ли совершен клик по нашему главному элементу, то бишь по окну или нет, а также по его дочерних элементах, что размещены внутри. Если это не они, то переходим далее.

modalctr.hide();
- скрываем наш родительский контейнер, первую переменную - modalctr. То бишь нажимая вне окна, мы скрываем область, что затемняет сайт, внутри которой и лежит окно. Если у вас нет родителя, а нужно скрыть просто элемент из переменной modal. То есть строка будет иметь такой вид - modal.hide();
Далее, просто закрываем скобки.
Если вы настроите все правильно то результат не заставит себя ждать.

На этом все, спасибо за внимание.

Добавлено: 19 Июня 2019 14:04:48 Добавил: Андрей Ковальчук

HTML5 Drag&amp;Drop

Перетаскивание файлов из рабочего стола в браузер одна из наиболее интересных возможностей HTML5. Я опишу как:

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

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

Последние версии Firefox и Chrome поддерживают все функции и превосходно работают с перетаскиванием.
Опера может парсить файлы в JavaScript, но не поддерживает перетаскивание файлов и загрузку с помощю XMLHttpRequuest2
IE и десктоповые версии Safari не поддерживают ничего из нужного API.
HTML и CSS
Далее идет код стандартной формы с инпутом типа файл. Единственное HTML5 нововведение в форме это атрибут “multiple” который позволяет пользователю выбирать любое количество файлов.

Со стороны сервера загрузка файлов будет проводиться средствани PHP, но независимо от того какую технологию вы используете на сервере JavaScript код останется тем же. Скрытое поле MAX_FILE_SIZE определяет 300,000 байт, размер будем проверять и на стороне клиента и на стороне сервера, чтобы предотвротить загрузку огромного размера файлов.

<form id="upload" action="upload.php" method="POST" enctype="multipart/form-data">
        <fieldset>
                <legend>HTML Загрузка Файлов</legend>
                <input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="300000" />
                <div>
                        <label for="fileselect">Выберите файлы для загрузки:</label>
                        <input type="file" id="fileselect" name="fileselect[]" multiple="multiple" />
                        <div id="filedrag" >Или перетащите их сюда</div>
                </div>
                <div id="submitbutton">
                        <button type="submit">Загрузить файлы</button>
                </div>
        </fieldset>
</form>

Элемент #filedrag будет использоваться как облясть в которую необходимо пренести файлы. Элемент в CSS стилях скрыт, но он будет отображаться средствами JavaScript если перетаскивание поддерживается браузером:
*{
     margin: 0px;
}
body{
     background: none repeat scroll 0% 0% #EFEFEF;
}
.wrapper{
     background: none repeat scroll 0% 0% #FFFFFF;
     margin: 150px auto;
     border: 2px solid #3DA8BA;
     padding: 10px;
     width: 500px;
}
fieldset{
        border:2px solid #efefef;
}
#filedrag{
        border-radius: 7px 7px 7px 7px;
        border: 2px dashed #3DA8BA;
        color: #555555;
        cursor: default;
        display: none;
        margin: 1em 0pt;
        padding: 1em 0pt;
        text-align: center;
        background:#f9f9f9;
}
#filedrag.hover {
        border-style: solid;
        box-shadow: 0pt 3px 4px #dbdbdb inset;
}
#messages{
        margin-top:10px;
        padding:5px;
        font-size:14px;
}
#messages p{
        border-bottom:1px solid #efefef;
        margin-bottom:5px;
}

Для элемента также определенн класс .hover который меняет стили когдо пользователь перетаксивает файлы на элемент. Браузеры не поддерживают стили :hover в этой ситуации, но мы можем добовлять класс спомощю Javascript когда происходит нужное событие.

File API
W3C File API предостовляет несколько объектов которые мы будем использовать:

FileList: предостовляет массив выбранных файлов.
File: предстовляет единственный файл.
FileReader: интерфейс который позволяет нам считать информацию о файле со стороны клиента и использовать в JavaScript.

JavaScript события
Пришло время писать JavaScript код. Мы не будем использовать JavaScript фреймфроков, поэтому напишем пару фуннкций для сохронения нашего времени. Это функция которая достает нужный элемент по ид и функция выводящая сообщения
/* getElementById */
function $id(id) {
        return document.getElementById(id);
}

/* вывод сообщений */
function Output(msg) {
        var m       = $id("messages");
        m.innerHTML = msg + m.innerHTML;
}

Далее проверим поддержку File API и вызовем функцию инициализации Init():
/* проверка поддержки API */
if (window.File && window.FileList && window.FileReader){
        Init();
}
/* инициализация */
function Init(){

        var fileselect   = $id("fileselect"),
                filedrag     = $id("filedrag"),
                submitbutton = $id("submitbutton");

        /* выбор файла */
        fileselect.addEventListener("change", FileSelectHandler, false);

        /* проверка поддержки XHR2 */
        var xhr = new XMLHttpRequest();
        if (xhr.upload){

                /* сброс файла */
                filedrag.addEventListener("dragover", FileDragHover, false);
                filedrag.addEventListener("dragleave", FileDragHover, false);
                filedrag.addEventListener("drop", FileSelectHandler, false);
                filedrag.style.display = "block";

                /* удаление кнопки сабмитта */
                submitbutton.style.display = "none";
        }

}

Функция Init():

Устонавливает обработчик события к изменению инпута типа файл.
Отоброжает элемент #filedrag.
Устанавливает обработчики событий “dragover” и “dragleave” для динамического изменения стилей элемента #filedrag.
Устанавливает обработчик события “drop” для элемента #filedrag.
Скрывает кнопку сабмитта формы – он пока не требуется, так как мы будем просто анализировать файлы.
Также вы можете скрыть инпут типа файл, если перетаскивание поддерживается. Но я не буду этого делать чтобы пользователь мог воспользоваться удобным ему вариантом.

Проверка поддержки метода XMLHttpRequest.upload предотврощает проблемы с Оперой. Браузер поддерживает объекты File, FileList и FileReader, но не поддерживает перетаскивание файлов или XMLHttpRequest2. Поэтому мы отоброжаем информацию о файле, но оставляем скрытым элемент #filedrag.

Изменение стилей при переносе
Мало кто испытал перетаскивание файлов в браузер. На самом деле, многие опытные интернет пользователи считают это невозможным. Поэтому написали внутри элемента “перетащите сюда файлы”. А следующая функция будет добвлять класс к элементу, когда файл уже будет находится непосредственно над элементом, тем самым будут меняться стили.
// Файл над нужной областью
function FileDragHover(e){
        e.stopPropagation();
        e.preventDefault();
        e.target.className = (e.type == "dragover" ? "hover" : "");
}

Анализирование перетащенных или выбранных файлов
Будем использовать функцию FileSelectHandler() не зависимо от того обин или несколько файлов были выбранны или перетащенны на элемент #filedrag:
// выбор файла
function FileSelectHandler(e){

        FileDragHover(e);

        // проходимся по объекту FileList 
        var files = e.target.files || e.dataTransfer.files;

        // парсим все объекты типа File
        for (var i = 0, f; f = files[i]; i++){
                ParseFile(f);
        }

}

Функция:

Вызываем функцию FileDragHover() чтобы убрать стиля при hover и предотвратить выполнение событий браузера. Это очень важно, так как браузер может попытаться отобразить файл
Проходимся по объекту FileList.
Наконец функция проходит по всем объектам типа File в объекте FileList и передает их как аргумент в функцию ParseFile()
function ParseFile(file) {
        Output(
                "<p>File information: <strong>" + file.name +
                "</strong> type: <strong>" + file.type +
                "</strong> size: <strong>" + file.size +
                "</strong> bytes</p>"
        );
}

Функция выводит информация используя три основные свойства представленные объектом File только для чтения.

.name: имя файла (не включая путь к файлу)
.type: MIME тип, например: image/jpeg, text/plain, и т.д.
.size: размер файла в байтах

Добавлено: 13 Июля 2018 07:48:30 Добавил: Андрей Ковальчук

Структурированные теги HTML5

В HTML5 добавили несколько интересных и полезных тегов для структурирования вашей разметки. Многие из этих тегов заменят типичные элементы div которые мы часто используем. Начнем перечисление тегов:

<section></section>

section предназначено для тематический группировки контента, обычно ставится после заголовка, возможно в конце страницы. section может быть вложен в любой другой тег, если понадобится может содержать любое количество типичной разметки.
<header></header>

Используется для указания заголовка для section (разделов), также для группировки заголовков, но может также содержать дополнительную информацию о разделе.
<footer></footer>

footer обычно содержит информацию о разделе, ссылки на похожие документы, копирайты и т.д.
<nav></nav>

Определяет область навигации, как правило список ссылок. nav как правило должен располагаться между section, header и footer
<article></article>

Независимая запись в блоге, журнале и т.д.
<aside></aside>

Указывает вторичную информацию о записи, пояснение что ли.

Использование
Давайте теперь попробуем использовать эти теги для построения обычной страницы блога:
<!DOCTYPE html>
<html>
  <head>
    <title>Стандартный блог</title>
  </head>
  <body>
    <header>
      <h1><a href="#">Стандартный блог</a></h1>
    </header>
    <nav>
      <ul>
        <li><a href="#">Главная</a></li>
        <li><a href="#">Архив</a></li>
        <li><a href="#">О блоге</a></li>
        <li><a href="#">Контакты</a></li>
      </ul>
    </nav>
    <section>
      <article>
        <header>
          <h1><a href="#">Заголовок</a></h1>
        </header>
        <section>
          <p>Тут текст...</p>
        </section>
      </article>
      <article>
        <header>
          <h1><a href="#">Заголовок</a></h1>
        </header>
        <section>
          <p>Тут текст...</p>
        </section>
      </article>
      <article>
        <header>
          <h1><a href="#">Заголовок</a></h1>
        </header>
        <section>
          <p>Тут текст...</p>
        </section>
      </article>
    </section>
    <footer>
      <p>Copyright © 2008 All Rights<p>
    </footer>
  </body>
</html>

Этот пример достаточно многозначен но хорошо показывает места применения нужных тегов.

Добавлено: 13 Июля 2018 07:46:12 Добавил: Андрей Ковальчук

Как открывать перетащенные файлы с помощью HTML5

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

Зачем открывать локальные файлы через JavaScript?
Загрузка файлов через обычные HTML формы очень неудобна. Люди часто используют его допустим при передаче нескольких мегобайт фотографий со своей камеры на сервер. Если предположить что они знают местоположение фотографий, то загрузка может занять несколько минут, но это только если все будет хорошо и форматы и разамеры будут подходящими, а что если нет? До сих пор разработчикам приходилось пологаться на Flash или другие плагины для обеспечение удобства. Предварительная обработка с помощю Javascript‘a имеет ряд преимуществ:

Локальная обработка файлов происходит на много быстрей.
Файлы могут быть проанализированны, чтобы убедиться, что они в правильном формате и ниже, орпеделенного размера.
Такие файлы как картинки могут быть просмотренны перед загрузкой.
Можно обрезать или изменить размер изображения перед загрузкой с помощю canvas.
Объект FileReader.
FileReader является частью W3C File API и предостовляет четыре метода для асинхронной загрузки данных из ссылки к объекту File.

.readAsText(File f, [кодировка]) – считывает файл как строку. По умолчанию в кодировке UTF-8, но можно передать и другой формат.
.readAsDataURL(File f) – как закодированный URL.
.readAsBinaryString(File f) – как двоичный код.
.readAsArrayBuffer(File f) – как объект ArrayBuffer.

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

Асинхронное открытие файлов с помощю Javascipt.
Вот наша исхлдная функция ParseFile() в который предаются выбранные или перетащенные на элемент #filedrag файлы.

function ParseFile(file) {

        Output(
                "<p>Информация о файле: <strong>" + file.name +
                "</strong> тип: <strong>" + file.type +
                "</strong> размер: <strong>" + file.size +
                "</strong> байт</p>"
        );

}

После обновления статуса, мы проверяем является ли переданный файл текстовым (text/plain, text/html, text/css, и т.д.), загружаем его используя метод FileReader.readAsText() и выводим результат:
// выводим текст
if (file.type.indexOf("text") == 0) {
        var reader = new FileReader();
        reader.onload = function(e) {
                Output(
                        "<p><strong>" + file.name + ":</strong></p><pre>" +
                        e.target.result.replace(/</g, "<").replace(/>/g, ">") +
                        "</pre>"
                );
        }
        reader.readAsText(file);
}

Точно также мы можем проверить, если у нас файл является картинкой (image/jpeg, image/gif, image/png и т.д.) загрузить его как data URL используя метод FileReader.readAsDataURL() и передать это все дело как src атрибут для элемента img:
// выводим картинку
if (file.type.indexOf("image") == 0) {
        var reader = new FileReader();
        reader.onload = function(e) {
                Output(
                        "<p><strong>" + file.name + ":</strong><br />" +
                        '<img src="' + e.target.result + '" /></p>'
                );
        }
        reader.readAsDataURL(file);
}

Добавлено: 13 Июля 2018 07:44:47 Добавил: Андрей Ковальчук

Предзагрузка изображения или файла в html5

Позволяет сделать предзагрузку какого-либо файла или целой страницы:

Исходный код этого примера:

<!-- вся страница -->
<link rel="prefetch" href="http://kdg.htmlweb.ru/photo/" />

<!-- только картинка -->
<link rel="prefetch" href="http://kdg.htmlweb.ru/photo/s21.jpg" />

Добавлено: 12 Июля 2018 07:51:25 Добавил: Андрей Ковальчук

Предпросмотр картинки перед загрузкой на сервер на javascript

Исходный код этого примера:

<style>
  .thumb {
    height: 75px;
    border: 1px solid #000;
    margin: 10px 5px 0 0;
  }
</style>

<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>

<script type="text/javascript">
  function handleFileSelect(evt) {
    var files = evt.target.files; // FileList object

    // Loop through the FileList and render image files as thumbnails.
    for (var i = 0, f; f = files[i]; i++) {

      // Only process image files.
      if (!f.type.match('image.*')) {
        continue;
      }

      var reader = new FileReader();

      // Closure to capture the file information.
      reader.onload = (function(theFile) {
        return function(e) {
          // Render thumbnail.
          var span = document.createElement('span');
          span.innerHTML = ['<img class="thumb" src="', e.target.result,
                            '" title="', theFile.name, '"/>'].join('');
          document.getElementById('list').insertBefore(span, null);
        };
      })(f);

      // Read in the image file as a data URL.
      reader.readAsDataURL(f);
    }
  }

document.getElementById('files').addEventListener('change', handleFileSelect, false);

Добавлено: 11 Июля 2018 22:05:44 Добавил: Андрей Ковальчук

Модальные окна с красивыми эффектами

Сегодня мы хотим поделиться скриптами модальных окон с красивыми эффектами. Различных вариаций очень много, так что каждый сможет найти своё.

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

На версиях iOS < 6 мобильной версии Safari, могут быть проблемы с отображением.

Структура модального окна делится на контейнер и контент:

<div class="md-modal md-effect-1" id="modal-1">
    <div class="md-content">
        <h3>Modal Dialog</h3>
        <div>
            <p>This is a modal window. You can do the following things with it:</p>
            <ul>
                <li><strong>Read:</strong> Modal windows will probably tell you something important so don't forget to read what it says.</li>
                <li><strong>Look:</strong> modal windows enjoy a certain kind of attention; just look at it and appreciate its presence.</li>
                <li><strong>Close:</strong> click on the button below to close the modal.</li>
            </ul>
            <button class="md-close">Close me!</button>
        </div>
    </div>
</div>
 
...
 
<div class="md-overlay"></div>

Основной контейнер будет отображаться или скрываться (используя класс “md-show”), а внутренний контент будет анимироваться. Оформляем окна следующими селекторами:
.md-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    width: 50%;
    max-width: 630px;
    min-width: 320px;
    height: auto;
    z-index: 2000;
    visibility: hidden;
    backface-visibility: hidden;
    transform: translateX(-50%) translateY(-50%);
}
 
.md-show {
    visibility: visible;
}
 
.md-overlay {
    position: fixed;
    width: 100%;
    height: 100%;
    visibility: hidden;
    top: 0;
    left: 0;
    z-index: 1000;
    opacity: 0;
    background: rgba(143,27,15,0.8);
    transition: all 0.3s;
}
 
.md-show ~ .md-overlay {
    opacity: 1;
    visibility: visible;
}

Для некоторых эффектов добавим класс html элементам. В особенности для применения 3D эффектов. Заметьте это, что мы применяем всё это к всей странице и контенту:
.md-perspective,
.md-perspective body {
    height: 100%;
    overflow: hidden;
}
 
.md-perspective body  {
    background: #222;
    perspective: 600px;
}
 
.container {
    background: #e74c3c;
    min-height: 100%;
}

Для контроля различных эффектов, создадим специальные классы, ответственные за специфический эффект и анимацию. Пример индивидуального эффекта:
/* Effect 5: newspaper */
.md-show.md-effect-5 ~ .md-overlay {
    background: rgba(0,127,108,0.8);
}
 
.md-effect-5 .md-content {
    transform: scale(0) rotate(720deg);
    opacity: 0;
    transition: all 0.5s;
}
 
.md-show.md-effect-5 .md-content {
    transform: scale(1) rotate(0deg);
    opacity: 1;
}

У кнопок воспользуемся атрибутом data-* для того чтобы задать источник контента модального окна:

<button class="md-trigger" data-modal="modal-5">Newspaper</button>

Добавлено: 01 Мая 2018 09:03:26 Добавил: Андрей Ковальчук

Индикатор прогресса HTML5

В HTML5 появился элемент индикатора прогресса, который выводит состояние процесса выполнения определенных задач, например, таких как загрузка данных на сервер.

В данном уроке мы рассмотрим, как добавлять такой элемент в документ, как определять для него стили CSS и анимировать индикатор прогресса.

Начнем.

Основы
Индикатор прогресса добавляется с помощью элемента <progress>. Значение индикатора определяется атрибутами value, min и max:

<progress value="10" max="100"></progress>

Так как базовая реализация использует стандартные формы, то визуальное представление будет зависеть от платформы реализации. Ниже приводится пример того, как выглядит индикатор прогресса в Windows и OSX.

Теперь определим стили для индикатора прогресса, чтобы он выглядел одинаково на любых платформах.

Стили для индикатора прогресса
В таблице стилей мы можем использовать селектор элемента для выбора элемента и добавления правил для элемента <progress>. В ниже приведенном примере мы изменяем фоновый цвет, удаляем обводку и скругляем углы на радиус равный половине высоты элемента.
progress {
    background-color: #f3f3f3;
    border: 0;
    height: 18px;
    border-radius: 9px;
}

Однако, каждый браузер обрабатывает правила немного по своему.

В Firefox стили влияют на полоску индикатора, а на текущее значение не оказывают воздействия.

В Chrome и Safari стили не используются и применяются установки Webkit (в текущий момент времени).

Поэтому потребуется больше действий.

В Chrome и Safari элемент прогресса преобразуется следующим образом.

<progress>
    ? <div> ::-webkit-progress-bar
         ? <div>::-webkit-progress-value

Таким образом для изменения полоски индикатора и текущего значения в браузере нужно добавить псевдо-классы:
progress::-webkit-progress-bar {
    /* стили */
}
progress::-webkit-progress-value {
    /* стили */
}

Firefox также имеет специальный псевдо-класс ::-moz-progress-bar. В отличие от Chrome и Safari данный псевдо-класс ссылается на текущее значение:
progress::-moz-progress-bar {
    /* стили */
}

В завершение представим все селекторы для определения стилей HTML5 индикатора прогресса.
progress {
    /* стили */
}
progress::-webkit-progress-bar {
    /* стили  */
}
progress::-webkit-progress-value {
    /* стили */
}
progress::-moz-progress-bar {
    /* стили */
}


Анимирование прогресса
Теперь рассмотрим, как анимировать индикатор прогресса. Обычно, полоска расширяется слева направо по мере выполнения задачи.

Идея заключается в том, что индикатор прогресса расширяется от 0 и останавливается в момент достижения максимального значения. Мы также будем выводить числовое значение прогресса. Ниже приводится структура HTML.

<progress id="progressbar" value="0" max="100"></progress>

В данном примере мы используем jQuery для анимации индикатора прогресса. Поэтому добавляем jQuery в документ:
<script src="js/jquery.js" type="text/javascript"></script>

Затем мы добавляем скрипт, который выполняет расширение полоски прогресса. Сначала сохраняем элемент индикатора прогресса, текущее и максимальное значения, а также и частоту кадров:
var progressbar = $('#progressbar'),
    max = progressbar.attr('max'),
    value = progressbar.val(),
    time = (1000/max)*5;

Затем мы создаем переменную, которая хранит функцию анимации. В нашем примере она называется loading.
var loading = function() {
 
}

Внутри выше приведенной функции устанавливаем интервал прогресса. Будем увеличивать данное значение на 1 за один кадр — можно увеличивать значение на большую величину, чтобы ускорить ход индикатора.
value += 1;

А затем мы добавляем результат к полоске прогресса.
addValue = progressbar.val(value); 

Мы также показываем значение рядом с индикатором прогресса:
$('.progress-value').html(value + '%');

Затем мы создаем новую функцию для выполнения анимации:
setInterval(function() {
    loading();
}, time);

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

Сохраним выше приведенную функцию в переменной:
var animate = setInterval(function() {
    loading();
}, time);

В переменной loading добавляем условное выражение:
if (value == max) {
    clearInterval(animate);
}

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

Приведем полный код анимации индикатора прогресса:
$(document).ready(function() {
    var progressbar = $('#progressbar'),
        max = progressbar.attr('max'),
        time = (1000/max)*5,   
        value = progressbar.val();
 
    var loading = function() {
        value += 1;
        addValue = progressbar.val(value);
         
        $('.progress-value').html(value + '%');
 
        if (value == max) {
            clearInterval(animate);                   
        }
    };
 
    var animate = setInterval(function() {
        loading();
    }, time);
};

Поддержка в браузерах
Элемент HTML5 для индикатора прогресса поддерживается в следующих браузерах: Firefox 16+, Chrome 8+, Safari 6+ и Opera 11+.

Добавлено: 28 Апреля 2018 15:44:43 Добавил: Андрей Ковальчук

Создаем модальное окно на HTML5 и CSS3

Модальные окна - часто используемый инструмент в арсенале веб мастера. Он очень удачно подходит для решения большого количества задач, таких как вывод форм регистрации, рекламных блоков, сообщений и так далее.

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

HTML5 и CSS3 позволяют создавать модальные окна с необычайной легкостью.

Разметка HTML
Первый шаг на пути к созданию модального окна - простая и эффективная разметка:

<a href="#openModal">Открыть модальное окно</a>
 
<div id="openModal" class="modalDialog">
     
</div>

Мы просто создаем ссылку “Открыть модальное окно”, которая указывает на элемент div openModal, который размещен ниже. Внешний вид формируется стилями в классе modalDialog.

Внутри элемента div размещается содержание модального окна. Также нужно организовать ссылку для закрытия окна. Для примера разместим простой заголовок и несколько параграфов. Полная разметка для нашего примера будет выглядеть следующим образом:
<a href="#openModal">Открыть модальное окно</a>
 
<div id="openModal" class="modalDialog">
    <div>
        <a href="#close" title="Закрыть" class="close">X</a>
        <h2>Модальное окно</h2>
        <p>Пример простого модального окна, которое может быть создано с использованием CSS3.</p>
        <p>Его можно использовать в широком диапазоне, начиная от вывода сообщений и заканчивая формой регистрации.</p>
    </div>
</div>


Стили
Создаем класс modalDialog и начинаем формировать внешний вид:
.modalDialog {
    position: fixed;
    font-family: Arial, Helvetica, sans-serif;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background: rgba(0,0,0,0.8);
    z-index: 99999;
    -webkit-transition: opacity 400ms ease-in;
    -moz-transition: opacity 400ms ease-in;
    transition: opacity 400ms ease-in;
    display: none;
    pointer-events: none;
}

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

Фон будет иметь небольшую прозрачность, а также располагаться поверх всех остальных элементов за счет использования свойства z-index.

В завершении устанавливаем переходы для вывода нашего модального окна и скрываем его в неактивном состоянии.

Может быть вы не знаете свойство pointer-events, но оно позволяет контролировать как элементы будут реагировать на нажатие кнопки мыши. Мы устанавливаем значение его значение для класса modalDialog, так как ссылка не должна реагировать на нажатие кнопки мыши когда активен псевдо класс “:target”.

Теперь добавляем псевдо класс :target и стили для модального окна.
.modalDialog:target {
    display: block;
    pointer-events: auto;
}
 
.modalDialog > div {
    width: 400px;
    position: relative;
    margin: 10% auto;
    padding: 5px 20px 13px 20px;
    border-radius: 10px;
    background: #fff;
    background: -moz-linear-gradient(#fff, #999);
    background: -webkit-linear-gradient(#fff, #999);
    background: -o-linear-gradient(#fff, #999);
}

Псевдо класс target изменяет режим вывода элемента, поэтому наше модальное окно будет выводиться при нажатии на ссылку. Также мы изменяем значение свойства pointer-events.

Мы определяем ширину модального окна и положение на странице. Также определяем градиент для фона и скругленные углы.

Закрываем окно
Теперь нужно реализовать функционал закрытия окна. Формируем внешний вид кнопки:
.close {
    background: #606061;
    color: #FFFFFF;
    line-height: 25px;
    position: absolute;
    right: -12px;
    text-align: center;
    top: -10px;
    width: 24px;
    text-decoration: none;
    font-weight: bold;
    -webkit-border-radius: 12px;
    -moz-border-radius: 12px;
    border-radius: 12px;
    -moz-box-shadow: 1px 1px 3px #000;
    -webkit-box-shadow: 1px 1px 3px #000;
    box-shadow: 1px 1px 3px #000;
}
 
.close:hover { background: #00d9ff; }

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

Добавлено: 28 Апреля 2018 10:19:21 Добавил: Андрей Ковальчук