Кнопка вверх на jQuery

Кнопка вверх на jquery. Довольно частая задача при разработке сайта. Сегодня мы научимся делать кнопку вверх на jquery.

Сегодня мы с вами научимся делать кнопку вверх на jQuery.

html

Создадим кнопку с 2 классами, первый для оформления, другой для javascript и текстовый узел, который будет визуально обозначать начало страницы.

<p>Content</p>
<div class="up-btn js-scroll-top">Up</div>

css

накинем немного стилей

/*Вспомогательные стили для демонстрации появления кнопки*/
body {
    height: 4000px; /*имитируем много контента на странице*/
}

/*Стили по-умолчанию*/
.up-btn {
    background-color: #444; /*Цвет фона*/
    color: #fff; /*Цвет текста в кнопке*/
    padding: 20px; /*Внутренний отступ*/

    position: fixed; /*Фиксированное позиционирование*/
    bottom: 20px; /*Снизу*/
    right: 20px; /*Справа*/
    cursor: pointer; /*«Рука» при наведении*/

    opacity: 0; /*Прозрачность 0%*/
    visibility: hidden; /*Видимость на странице*/

    transition: .3s all; /*Плавность изменения 3 миллисекунды*/
}

/*Активный класс*/
.up-btn.is-show {
    opacity: 1; /*Прозрачность 100%*/
    visibility: visible; /*Видимость на странице*/
}

/*
Трюк с opacity и visibility нужен, потому что display none и block появляются резко. Им никак не настроишь плавности. А вот opacity и visibility плавность появления настроить можно.
*/

Дали body огромную высоту, для того, чтобы скроллить, это только для примера.

Для кнопки сделали позиционирование внизу справа, по-умолчанию кнопка скрыта. Показывать ее будет дополнительный класс is-show, который мы будем добавлять в js.

javascript

Первое — клик и скроллинг вверх.

(1) Создаем событие клика по классу .js-scroll top
(2) У элемента html и body вызываем функцию. animate и
(3) Анимируем параметр scrollTop: 0
(4) за 1000 мс (1 сек)

Почему scrollTop должен быть 0? Потому, что это означает начало страницы.

$('.js-scroll-top').click(function() { // (1)
     $('html,body').animate({ // (2)
         scrollTop: 0 // (3)
     }, 1000); // (4)
 });

Показ, скрытие кнопки

Какие будут условия для показа и скрытия? Позиция скролла в текущий момент времени. Это мы можем проверить, привязав событие scroll на window — окно браузера.

$(window).scroll(function() {

});

Теперь при прокрутке мы должны получать позицию скролла. Это можно сделать с помощью метода. scrollTop ()

$(window).scrollTop()
if (Если расстояние сверху больше, чем 200 пикселей) {
    добавляем класс, который показывает кнопку
} else {
    удаляем класс, который показывает кнопку        
}
if ($(window).scrollTop() > 200) {
   $('.js-scroll-top').addClass('is-show');
} else {
   $('.js-scroll-top').removeClass('is-show');
}

Все вместе

$('.js-scroll-top').click(function() {
   $('html,body').animate({
       scrollTop: 0
    }, 1000);
});

$(window).scroll(function() {
   if ($(window).scrollTop() > 200) {
     $('.js-scroll-top').addClass('is-show');
   } else {
     $('.js-scroll-top').removeClass('is-show');
   }
});

Демо:

Кнопка вверх на jQuery 1

Sticky footer. Прилипающий футер

Разберем проблему с прилипающим футером.

Ссылка на codepen

Представим, что у на главной странице вашего сайта подвал внизу и все ок, но вот на странице контактов контента мало и подвал находится не внизу страницы, а посередине, как здесь:

Sticky footer. Прилипающий футер 2
Демо проблемы

Как-то я делал javascript реализацию подсчета высоты и автоматическую подстройку, но постоянно возникали проблемы с отступами и я решил, что это необходимо сделать на css.

Решать проблему будем с помощью flex grid.

html

Для начала создадим html-код, тут нам понадобиться всего 2 элемента: content и footer. В content будет лежать шапка и контент сайта, отдельно будет футер.

<body>
   <div class="content">
      <p>I am content</p>
   </div>
   <div class="footer">
      <p>I am footer</p>
   </div>
</body>

CSS

body,html {
   height: 100%;
}

body {
   display: flex;
   flex-direction: column;
}

.content {
   flex: 1 0 auto;
}

.footer {
   flex-shrink: 0;
}

Здесь в несколько шагов:

  1. Делаем body, html высоту в 100%, так как при отсутствии контента они не заполняют высоту экрана.
  2. Для body установим flex и направление column, так как нам нужно, чтобы они выстроились в столбик.
  3. Для content укажем flex: 1 0 auto, что дословно:
    — flex-grow: 1;
    — flex-shrink: 0;
    — flex-basis: auto
  4. Подвалу мы запрещаем изменять высоту меньше собственной (shrink).

Готово, проверяем:

Sticky footer. Прилипающий футер 3
Демонстрация

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

sticky footer

Белая полоса справа на сайте. Решение

Белая полоса справа на сайте — частый и сложный вопрос, особенно для начинающих разработчиков.

Видеоурок

В чем проблема

Белая полоса может появляться по многим причинам, но если коротко, это «вывалившиеся» за сайт элементы, либо огромные отступы (margin) вправо.

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

Пришлось повозится, чтобы создать эту ситуацию xD

Обычно пытаешься это решить, а вот создавать — впервые.

Демонстрация проблемы
Проблема

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

Нам нужно их найти. Иногда, они видны сразу, как здесь:

Демонстрация проблемных блоков
Нашли проблемные блоки

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

Удаление секций

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

  • скрытые модальные окно или меню
  • flex или grid сетки
  • заголовки или подзаголовки

Посмотрим на моем примере, что я сделал не так и как исправить ситуацию в моем случае.

У меня 2 проблемы:

css код этого примера
css код этого примера
  1. У flex сетки нет свойства flex-wrap, которое отвечает за переброс элементов, в том случае, если места для них на экране нет
  2. Размер и формат заголовка, Заголовок длинный и без пробелов, нужно либо изменить его, либо уменьшить размер.

Исправим

Исправил заголовок — добавил пробелы.

html код заголовка
Изменил заголовок

Добавил flex-wrap: wrap;

css код
Добавил flex-wrap

Тестируем

Демонстрация исправленного сайта
проблема решена

Плавный скролл на jQuery

Итак, сегодня мы научимся делать плавный скролл на jQuery.

Демо на codepen

Разметка

Создаем 4 кнопки и 4 секции.

<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>

<div>Секция 1</div>
<div>Секция 2</div>
<div>Секция 3</div>
<div>Секция 4</div>

Стили

Создадим внутренние отступы — padding и установим серый фон для каждой второй секции для визуального разделения.

.section {padding: 70px 0;}
.section:nth-child(2n) {background-color: #eee;}

Что получилось

Плавный скролл на jQuery 4
Это скриншот, не кликайте

Интерактив

В jQuery создаем событие клика на кнопку, предварительно проставив классы с префиксом js-. Это делается, чтобы в случае замены классов оформления, код поведения остался цел.

<!-- Установили классы для js  -->
<button class="js-scroll-trigger">1</button>
<button class="js-scroll-trigger">2</button>
<button class="js-scroll-trigger">3</button>
<button class="js-scroll-trigger">4</button>
// Написали обработчик клика
$('.js-scroll-trigger').click(function() {
  // code
});

Сейчас нам нужно понять, к какому именно элементу нужно скроллить. Я буду хранить это в data-атрибуте. Это такой атрибут, который вы можете назвать, как душе угодно:

  • data-vasya
  • data-lays
  • data-id

И хранить там информацию. Я буду хранить там селектор элемента, к которому будем скроллить.

<!-- Проставили кнопкам селекторы элементов -->
<button class="js-scroll-trigger" data-scroll="#section-1">1</button>
<button class="js-scroll-trigger" data-scroll="#section-2">2</button>
<button class="js-scroll-trigger" data-scroll="#section-3">3</button>
<button class="js-scroll-trigger" data-scroll="#section-4">4</button>

<!-- Проставили секциям id -->
<section id="section-1">Секция 1</section>
<section id="section-2">Секция 2</section>
<section id="section-3">Секция 3</section>
<section id="section-4">Секция 4</section>

Тепер в javascript при клике на кнопку мы будем получать этот атрибут.

var scrollName = $(this).attr('data-scroll');

Что дальше? Нужно найти элемент с таким селектором в dom-дереве. Это можно сделать так:

var scrollName = $(this).attr('data-scroll'),
    scrollElem = $(scrollName);

И последний шаг — узнать расстояние от верха страницы до нашего элемента. В этом нам поможет метод offset () и его свойство top

var scrollName = $(this).attr('data-scroll'),
    scrollElem = $(scrollName),
    scrollTop = scrollElem.offset().top;

Отлично! Осталось добавить анимацию скролла. За это в jQuery отвечает функция animate (), первым аргументом она принимает массив параметров, которые нужно анимировать, второй аргумент — время в миллисекундах, за которое нужно выполнить анимацию.

Мы будем анимировать параметр scrollTop. Вы можете спросить, почему мы указали html и body в качестве элементов для анимации?

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

  1. Браузеры Firefox и IE используют ‘html’
  2. Браузеры в «классе webkit» например: Safari, Chrome используют ‘body’.
var scrollName = $(this).attr('data-scroll'),
    scrollElem = $(scrollName),
    scrollTop = scrollElem.offset().top;

$('html, body').animate({
  scrollTop: scrollTop
}, 500);

В итоге скролл идет 500 мс. Проверим?

Демо скролла
Демо скроллинга

Javascript код

$('.js-scroll-trigger').click(function() {
   var scrollName = $(this).attr('data-scroll'),
       scrollElem = $(scrollName),
       scrollTop = scrollElem.offset().top;
   
   $('html, body').animate({
      scrollTop: scrollTop
   }, 500);
});

Делаем всплывающую панель на javascript

В это статье мы создадим всплывающую панель на javascript. Для хранения состояния будет использовать localStorage.

Сначала покажу, как работает:

Делаем всплывающую панель на javascript 5
Код для версии с анимацией в конце статьи, анимацю пока не объявнил.

Весь код для копирования в конце статьи.

Ссылка на codepen

Зачем нам что-то хранить? Пару дней назад на моем сайте происходил редизайн. Я хотел уведомить пользователя о том, чтобы он не пугался поехавшей верстки и просто очистил кеш нажатием ctrl+f5.

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

html

Первым делом — html. Мы создаем фиксированную панель внизу экрана с текстом и кнопками. Так же добавляем класс для скрытия панели.

<div class="notification js-notification hidden">
  <div class="container">
     <div class="notification-text">
	 Мы используем куки-файлы. Продолжая использовать наш сайт, вы соглашаетесь с этим.
     </div>
     <button class="notification-btn js-notification-btn">OK</button>
  </div> 
</div>

.js-notification мы добавляем для того, чтобы не использовать для javascript те классы, на которых висит оформление. Мы можем забыть об этом и поменять классы — интерактив сломается. Видя приставку js-, мы не будем менять класс зная, что на нем функционал в js.

.hidden мы добавили сразу же. Дело в том, что пока мы не поняли, смотрел он уже наше сообщение или нет, панель должна быть скрыта, чтобы она не показывалось в самом начале, пока javascript просматривает хранилище. Панель покажется быстрее, чем сообразит javascript.

css

.container {
    max-width: 1170px;
    width: 100%;
    margin: 0 auto;
    padding: 0 25px;
    box-sizing: border-box;
}
.notification .container {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.notification {
    position: fixed;
    bottom: 15px;
    right: 15px;
    z-index: 200;
    background-color: #000;
    color: #fff;
    width: 100%;
    max-width: 600px;  
    border-radius: 16px;
    padding: 0 20px;  
}
.notification.hidden {
    display: none; 
}
.notification-text {
    max-width: 70%;
}
.notification-btn {
    padding: 10px 15px; 
    border: none;
    border-radius: 3px;
    color: #fff;
    cursor: pointer;
    background-color: transparent;
    font-size: 50px;
    margin-left: auto;
}

По css ничего сложного. Думаю многие поймут и справятся. Если будут вопросы — пишите в комментариях или в личку.

javascript

Часто, чтобы написать какой-то код, нужно проговорить его вслух:


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

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

Если (записи в хранилище нет) {
  удалить класс у блока
}

клик по кнопке ({
  добавить запись в хранилище
  добавить класс, скрывающий панель
})

Когда сложная ситуация, помогает разобраться.

Я немного отвлекся, приступим к js:

// Переменные для панели и кнопки
var panel = document.querySelector('.js-notification'),
    panelButton = panel.querySelector('.btn');

Заметьте, переменная panelButton написана по-другому. Она начинается не с document, а с panel (первая переменная), это означает я ищу этот элемент не во всем документе, а только в панели. То есть буду искать ее среди потомков элемента с классом «.js-notification».

Напишем проверку хранилища. Я буду хранить наше сообщение под именем «cookie-message»:

именем «cookie-message»:

if (localStorage['cookie-message'] == undefined) {
  panel.classList.remove('hidden');
}

Если в хранилище нет записи — добавляем класс hidden

И последнее — клик по кнопке:

panelButton.addEventListener('click', function() {
  localStorage['cookie-message'] = true;
  panel.classList.add('hidden');
});

Добавляем событие клика. После клика записываем значение «cookie-message» в хранилище на true и добавляем панели класс, который ее скроет.

Мы установили true, в итоге в следующее посещение проверка на undefined в предыдущем блоке даст false и удаление скрывающего класса не сработает.

Все вместе:

var panel = document.querySelector('.js-notification'),
    panelButton = panel.querySelector('.btn');

   if (localStorage['cookie-message'] == undefined) {
    panel.classList.remove('hidden');
   }
   
   panelButton.addEventListener('click', function() {
      localStorage['cookie-message'] = true;
      panel.classList.add('hidden');
   });

Итоговый код

В итоговый код я добавил строки анимации появления/скрытия. Я объясню их в статье позже.

html

<div class="notification js-notification hidden">
  <div class="container">
     <div class="notification-text">
	 Мы используем куки-файлы. Продолжая использовать наш сайт, вы соглашаетесь с этим.
     </div>
     <button class="notification-btn js-notification-btn">OK</button>
  </div> 
</div>

css

.container {
    max-width: 1170px;
    width: 100%;
    margin: 0 auto;
    padding: 0 25px;
    box-sizing: border-box;
}
.notification .container {
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.notification {
    position: fixed;
    bottom: 30px;
    right: 0;
    z-index: 200;
    background-color: #000;
    color: #fff;
    width: 100%;
    max-width: 600px;  
    border-radius: 16px;
    padding: 0 20px;  
    transition: .3s all;
    opacity: 1;
    transform: translateY(0)    
}
.notification.hidden {
    opacity: 0;
    z-index: -1;
    transform: translateY(25px)
}
.notification-text {
    max-width: 70%;
}
.notification-btn {
    padding: 10px 15px; 
    border: none;
    border-radius: 3px;
    color: #fff;
    cursor: pointer;
    background-color: transparent;
    font-size: 50px;
    margin-left: auto;
}

Javascript

document.addEventListener('DOMContentLoaded', function() {
    var panel = document.querySelector('.js-notification'),
        panelButton = panel.querySelector('.js-notification-btn');

    if (localStorage['cookie-message'] == undefined) {
        setTimeout(function(){
            panel.classList.remove('hidden');
        },2000)
    }

    panelButton.addEventListener('click', function() {
        localStorage['cookie-message'] = true;
        panel.classList.add('hidden');
    });    
})