Управление видимостью (базовые эффекты) в jQuery

Содержание:
  1. Методы jQuery для управления видимостью элементов
  2. Комментарии

Статья, в которой рассмотрим методы jQuery, с помощью которых можно осуществить появления и скрытие элементов.

Методы jQuery для управления видимостью элементов

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

Методы jQuery с помощью которых можно управлять видимостью HTML-элементов на странице можно разделить на 3 основные группы:

  • Функции show (показать), hide (спрятать), toggle (переключить состояние из одного положение в другое) выполняют свои действия за счёт одновременного изменения 2 параметров: размеров (ширины и высоты) и прозрачности.
  • Функции fadeIn (отобразить), fadeOut (исчезнуть), fadeToggle (в зависимости от текущего состояния видимости, прячет или показывает элемент), fadeTo (изменяет состояние прозрачности элемента на заданное) производят свои действия за счёт изменения прозрачности элемента.
  • Функции slideDown (появление элемента), slideUp (исчезновение элемента), slideToggle (отображение или скрытие элемента в зависимости от того, в каком состоянии он сейчас находится) осуществляют своё действие за счёт изменения высоты элемента.
Методы jQuery для отображения и скрытия элементов
Методы jQuery для отображения и скрытия элементов
Демо методов hide, show...

Варианты использования методов jQuery, предназначенных для скрытия и отображения элементов

В jQuery существует три варианта использования методов, предназначенных для появления или исчезнования элементов на странице.

  1. .имяМетода([duration][,complete]) - самый простой вызов функции, который можно использовать без параметров, с одним параметром (длительность анимации) или с двумя (первый указывает длительность анимации, а второй - функцию, которую необходимо вызвать после окончания выполнения анимации).
    JavaScript
    .show([duration][,complete])
    // show - имя метода
    // параметы в скобках являются не обязательными
    // duration - длительность анимации
    // complete -  функция, которая будет вызвана после завершения анимации

    Например, выполним плавное появление блока с идентификатором message с помощью метода show (длительность анимации 1 секунда), а затем скроем его (через 5 секунд после завершения анимации) посредством метода hide:

    $('#message').show(1000, function(){
      setTimeout(function(){
        $('#message').hide(500);
      }, 5000);
    });
  2. .имяМетода([duration][,easing][,complete]) - расширенный вариант 1 способа. Кроме задания времени выполнения анимации и параметра complete, можно ещё указавать тип анимации. По умолчанию в качестве типа анимации используется swing.
    .slideUp([duration][,easing][,complete])
    // slideUp - имя метода
    // параметы в скобках являются не обязательными
    // в этом варианте появился ещё один параметр easing - устанавливает скорость протекания анимации

    Например, отобразим блок (имеющий класс scrollup) на странице после её прокрутки больше чем на 200px.

    $(window).scroll(function() {
      if ($(this).scrollTop()>=200) {
        // длительность анимации - 'slow'
        // тип анимации -  'linear'
        $('.scrollup').fadeIn('slow','linear');
      }
      else {
        // длительность анимации - 'fast'
        // тип анимации -  'swing'
        $('.scrollup').fadeOut('fast','swing');
      }
    });
  3. .имяМетода(options) - универсальный вызов функции. Параметры в этот методе задаются в виде свойств и методов объекта (options).
    .fadeIn({
      имяПараметра1: значение,
      имяПараметра2: значение,
      имяПараметра3: значение,
      ...
    })
    // fadeIn - имя метода

    Например, напишем JavaScript код, который будет скрывать элемент при клике:

    $('pressme').click(function() {
      $(this).slideUp({
        duration: 'slow',
        easing: 'linear'
      });
    });

Виды параметров, которые можно указывать универсальному вызову метода.имяМетода(options):

  • duration - параметр, определяющий длительность выполнения анимации в миллисекундах (число). По умолчанию: 400 мс. Кроме этого данный параметр может принимать следующие строковые значения: 'slow' (медленно), 'normal' (с обычной скоростью), 'fast' (быстро). Тип параметра duration: Number или String.
  • easing - параметр, содержащий строковое название функции (по умолчанию 'swing'), которая будет использоваться для задания скорости выполнения анимации в различных точках. В ядре библиотеки jQuery доступны только 2 функции easing: linear (с постоянной скоростью) и swing (скорость выполнения анимации в начале и конце меньше чем в середине, т.е. медленно -> быстро -> медленно). Тип параметра easing: String.
  • complete - параметр, содержащий функцию, которую необходимо вызвать после окончания выполнения анимации. Тип параметра complete: Function().
  • step - параметр, указывающий функцию, которая будет вызываться перед выполнением каждого кадра анимации. Внутри функции кроме параметра содержащей номер текущего кадра, будет доступен ещё и объект анимации Tween. Это означает то, что вы можете изменить свойства анимации (т.е. свойства объекта Tween) перед тем как они будут установлены. Тип параметра step: Function (Number now, Tween tween).
  • queue - логический параметр с помощью которого можно указать необходимо ли помещать анимацию в очередь. По умолчанию анимация в jQuery выполняется последовательно друг за другом, т.е. новая анимация не начнёт выполняться пока не завершиться предыдущая. Если указать в качестве значения этого параметра значение false, то она начнёт выполняться немедленно, т.е. она не будет помещаться в очередь. Начиная с версии jQuery 1.7 данный параметр в качестве значения также может принимать строку (название очереди). В этом случае анимация не будет запускаться автоматически. Чтобы её запустить необходимо будет вызвать функцию dequeue и указать ей в качестве параметра имя очереди: .dequeue("queuename"). Тип параметра queue: Boolean или String.
  • specialEasing - параметр, который позволяет задать различным CSS свойствам разные функции easing. Задается указанный параметр в формате объекта: {CSS-свойство1: easing-функция; CSS-свойство2: easing-функция ... }. Тип параметра specialEasing: PlainObject.
  • progress - параметр, содержащий функцию, которая будет вызываться после завершения каждого кадра анимации. Тип параметр progress: Function(Promise animation, Number progress, Number remainingMs).
  • start - параметр, содержащий функцию, которая вызывается когда элемент начинает анимацию. Тип параметра start: Function (Promise animation).
  • done - параметр, содержащий функцию, которая вызывается когда элемент завершил анимацию. Тип параметра done: Function (Promise animation, Boolean jumpedToEnd).
  • fail - параметр, содержащий функцию, которая вызывается только тогда когда выполнение анимации не доходит до конца, т.е. завершается неудачей. Тип параметра: Function (Promise animation, Boolean jumpedToEnd).
  • always - параметр, содержащий функцию, которая будет вызвана в момент завершения анимации или её остановки без окончания. Тип параметра always: Function (Promise animation, Boolean jumpedToEnd).

Метод для изменения прозрачности fadeTo

Метод fadeTo отличается от методов show, hide, toggle, fadeIn, fadeOut, fadeToggle, slideDown, slideUp и slideToggle тем, что он предназначен не для скрытия или отображения элементов, а для изменения их прозрачности. Поэтому в отличие от этих методов у него есть дополнительный обязательный параметр opacity. Этот параметр задаёт степень непрозрачности, который необходимо установить выбранным элементам. Задаётся данный параметр посредством числа от 0 до 1. Число 0 – устанавливает полную (100%) прозрачность элемента, а 1 - полную его не прозрачность. Кроме этого методу fadeTo в отличие методов скрытия или отображения элементов необходимо обязательно также задавать длительность выполнения анимации.

Синтаксис использования метода fadeTo:

JavaScript
// 1 вариант
.fadeTo( duration, opacity [, complete ] )
// 2 вариант
.fadeTo( duration, opacity [, easing ] [, complete ] )

Внимание: Метод fadeTo в отличие от методов скрытия и отображения элементов не может принимать в качестве значения параметра объект.

Например, медленно изменим прозрачность текста (содержимое элемента p с классом lead) при поднесении к нему курсора:

JavaScript
$('p.lead').hover(
  function(){
    $(this).fadeTo('slow',0.5);
  },
  function(){
    $(this).fadeTo('normal',1);
  }
);

Комментарии: 29

Максим
Максим
Добрый день, Александр. Подскажите пожалуйста, как реализовать такую вещь как ввод текста в поле input с переходом на другую страницу и поиск скрытых блоков на этой странице с нужным значением из input и отображением этих блоков. Понимаю, что вопрос скорее всего простой, но на двух форумах ответа 100-процентного не получил, первая часть кода выполняется, а вот отображение не происходит. 2 страницы «main.html» и «search.html». Нужно, чтобы после ввода текста на первой странице в поле input с id=«who» и клика Enter был переход на страницу «search.html» и на ней появлялись бы скрытые блоки с классом search-none («display:none;» прописан в css) со значением в input, пытаюсь сделать это через localstorage, переход то осуществляется, вроде и в localStorage значение сохраняется, но выборка не проходит, блоки не появляются, подскажите пожалуйста где ошибка? Заранее благодарю.

Вот код.
Скрипт на первой странице:
$(document).on( 'input', '#who', function() {   
  localStorage.setItem('who', $(this).val() );
});  
$('#who').on('keyup', function (e) {
  if (e.key === 'Enter' || e.keyCode === 13) {
    window.location = 'search.html'
  }
});
html-код на странице search.html:
<div class="search-none"><div class="product-item">
  <a href="" class="itemgoodlink">1.Здесь ищет совпадения с input</a>
</div></div>
<div class="search-none"><div class="product-item">
  <a href="" class="itemgoodlink">2.Здесь ищет совпадения с input</a>
</div></div>
Скрипт на странице search.html:
$(document).ready(function () {
  var who = localStorage.getItem('who');
  $('div.product-item').each(function (index, element) {
    if ($(element).text().toLowerCase() == who.toLowerCase()) {
      $(element).closest('.search-none').show();
    }
  });
});
Александр Мальцев
Александр Мальцев
Привет!
Через localStorage как-то не корректно будет. Здесь лучше данные передавать в составе URL (например, через get-параметр who).
Для этого на первой странице следует поместить следующий скрипт:
$('#who').on('keyup', function (e) {
  if (e.key === 'Enter' || e.keyCode === 13) {
    var url = 'search.html?who=' + $(this).val();
    window.location = url;
  }
});
На второй такой:
$(function () {
  var getUrlParameter = function getUrlParameter(sParam) {
    var sPageURL = window.location.search.substring(1),
      sURLVariables = sPageURL.split('&'),
      sParameterName,
      i;
    for (i = 0; i < sURLVariables.length; i++) {
      sParameterName = sURLVariables[i].split('=');
      if (sParameterName[0] === sParam) {
        return typeof sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
      }
    }
    return false;
  };
  var who = getUrlParameter('who');
  $('div.product-item a').each(function (index, element) {
    if ($(element).text().toLowerCase() == who.toLowerCase()) {
      $(element).closest('.search-none').show();
    }
  });
});
Текст с которым сравниваете находиться в . Поэтому нужно использовать $('div.product-item a').
Максим
Максим
Добрый день, спасибо, значение who передается в поле, но блоки нужные не находит, потом сам удалил из css display:none; и попробовал наоборот скрывать методом hide: $(element).closest('.search-none').hide(). тоже не скрывает. Даже добавил еще один блок чисто с текстом, без а, пробовал через него, не находит. Не подскажите, может есть еще какой метод кроме each, который может помочь в этой ситуации?
Александр Мальцев
Александр Мальцев
Привет! Значение, которое будет вводить пользователь с чем будет сравниваться на странице на которую он перешёл? Какие элементы оно должно находить? По названию класса, содержимому элементов?
// div.product-item a - здесь получаем нужные элементы
$('div.product-item a').each(function (index, element) {
  // тут сравнение
  if ($(element).text().toLowerCase() == who.toLowerCase()) {
    // тут действие (что-нужно сделать)
    $(element).closest('.search-none').show();
  }
});
Максим
Максим
Добрый день. Значение сравнивается с текстом, который находится в ссылке в блоке product-item:
1.Здесь ищет совпадения с input

В свою очередь product-item находится в составе директории из 4 блоков, главный из которых search-none.
Элементы, которые необходимо найти это буквы нижнего регистра по названию класса.
Уже все перепробовал и отдельный класс ссылке назначал и скрипты другие отключал, не показывает блоки.
Максим
Максим
Может быть проблема в том, что внутри input есть еще один блок: . Хотя я менял все в коде на livesearch вместо who, тоже ничего не происходит, уже не знаю, где еще искать ошибку. Консоль по этой строке $(element).closest('.search-none').show(); никаких действий не показывает.
Александр Мальцев
Александр Мальцев
Собрал часть задачи на codepen.io: codepen.io/itchief/pen/dyNaYQE
Всё работает. В переменную who поместил то, что приходит с первой страницы.
Максим
Максим
Добрый день, да, работает, но только когда совпадение абсолютно точное со всем текстом, а если в who задается только часть слова из текста, например «вид» или «настол» из «Камера видеонаблюдения настольная», то процесс не запускается. Извиняюсь, возможно, я изначально не совсем корректно задал вопрос, что именно надо. За предыдущие ответы большое спасибо!
Кайрат
Кайрат
Здравствуйте помогите пожалуйста решить проблему имеется основное меню в котором при нажатии на ссылку появляется выпадающее меню реализовано с помощью jquery .slideToggle(), проблема в том что при нажатии на другую ссылку основного меню появляется следующее навигационное меню а прошлое открытое не исчезает, помогите решить эту проблему а так же чтоб выпадающее меню сворачивалось при нажатии на другие элементы страницы jsfiddle.net
Александр Мальцев
Александр Мальцев
Привет. Для этого нужно другие открытые меню закрыть с помощью slideUp:
$('.menu__link').click(function () {
  $('.menu .sub:visible').not($(this)).slideUp();
  $(this).next('.sub').slideToggle();
});
$(document).on('click', function (e) {
  if (!$(e.target).closest('.menu').length) {
    $('.menu .sub:visible').slideUp();
  }
});
Пример: jsfiddle.net/itchief/1ywfortp/
Роман
Роман
Здравствуйте. На разных страницах сайта вставлены разные видео. Хочется скрывать их в зависимости от размера экрана.
Вставил такой блок
<div id="video-container-..."></div>
( на разных страницах разный id, вместо звездочек)
Пытаюсь выводить видео таким скриптом
window.onload = function () {
	if (window.innerWidth >= 1024)
		document.getElementById('video-container-...').innerHTML = '<video autoplay muted loop id="myVideo"><source src="/bitrix/templates/prok/video/....mp4" type="video/mp4"></video>'
};

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

Заранее спасибо
Александр Мальцев
Александр Мальцев
Здравствуйте.
Если правильно понял, то так:
window.onload = function () {
  if (window.matchMedia('screen and (min-width: 1024px)').matches) {
    const $elem = document.querySelector('[id^="video-container-"]');
    const numId = $elem.id.substring(16);
    $elem.innerHTML = `<video autoplay muted loop id="myVideo"><source src="/bitrix/templates/prok/video/${numId}.mp4" type="video/mp4"></video>`
  };
}
Nik
Nik
Добрый день Александр! Подскажите как можно по простому реализовать на jQuery исчезновение кнопки «Редактировать», через определенное количество времени (время задается вручную в коде). Эта кнопка для редактирования пользователем созданного им тикета, выводится через модификатор:
[!+modx.user.id:is=`[[*createdby]]`:then=`<a href="/zadat-vopros.html?tid=[[*id]]" class="btn">Редактировать</a>`]
Суть в том, чтобы пользователь не смог уже редактировать написанное им по прошествии времени
Александр Мальцев
Александр Мальцев
Привет!
Задать интервал можно через setTimeout:
// например, через 5 секунд
window.setTimeout(function () {
  $('[href^="/zadat-vopros.html?tid="]').hide();
}, 5000);
Nik
Nik
Спасибо!
Алексей
Алексей
Александ, здравствуйте! Подскажите, пожалуйста, у меня тех. задание, в котором сначала описаны условия:
5. Используйте атрибут `data-plugin ="… "` HTML для инициализации подключаемых модулей для элементов, как описано в файле примера `main.js`
— Пользовательские плагины НЕ ДОЛЖНЫ быть прикреплены к элементам путем прямого вызова плагина в селекторе `$ (selector) .plugin ()`
— Все плагины JS должны быть повторно использованы (должны работать, если прикреплены к нескольким элементам).
С этим более менее понятно.

Дальше:
Напишите плагин jQuery для применения анимации к кнопке.
1. Добавьте фиксированную кнопку в правом верхнем углу экрана.
2. Создайте многоразовую анимацию, которая будет затемнять кнопку: элемент масштабируется с 1 до 0,6 и скрывается справа налево, см. Прикрепленные инструкции animation-instructions.jpg
3. Создайте многоразовую анимацию, которая будет постепенно появляться на кнопке: анимация, противоположная постепенному исчезновению, см. Animation-instructions.jpg
4. Применяйте анимацию постепенного появления, когда пользователь перемещает курсор в верхнюю половину экрана. Скройте кнопку, используя анимацию «постепенного исчезновения», когда пользователь перемещает курсор в нижнюю половину экрана.
Написал, отталкиваясь от mousemove

Дальше:
Создание формы…
3. Если при отправке проверка прошла успешно, то предотвратить перезагрузку страницы и скрыть форму с помощью анимации «постепенное исчезновение» и показать сообщение об успехе с помощью «плавного появления».
Сделайте плавный переход, например. сообщение об успешном завершении должно исчезать одновременно (одновременно) с исчезновением формы, сообщение об успешном завершении должно отображаться на месте, где была форма.

Не могу понять, как применить плагин анимации, который я сделал для кнопки, к данной форме по клику на кнопку? Или мне нужно функции анимации писать отдельными плагинами, но тогда теряется условие — Пользовательские плагины НЕ ДОЛЖНЫ быть прикреплены к элементам путем прямого вызова плагина в селекторе `$ (selector) .plugin ()`
Иван
Иван
Здравствуйте!
Подскажите, есть ли на вашем сайте статья, как можно отследить появление класса у элемента и выполнить действие если этот класс появился? Я начал использовать отложенную загрузку и мне необходимо совершить действие как только у первого изображения появился класс lazy.
Александр Мальцев
Александр Мальцев
Здравствуйте! Следить за изменением класса у элемента можно с помощью API Mutation Observer.
Например:
<!-- Некоторый элемент, у которого каждые 2 секунды будем переключать класс foo
<div id="my-elem">...</div>

<script>
// получим элемент #my-elem
const $myElem = document.querySelector('#my-elem');
// будем переключать класс foo у элемента $myElem каждые 2 секунды
setInterval(() => {
  $myElem.classList.toggle('foo');
}, 2000);
// создазим новый экзмепляр MutationObserver
const mutationObserver = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    // получим элемент
    const $target = mutation.target;
    // в зависимости от того содержит элемент класс foo или нет, выведим то или иное сообщение в консоль 
    if ($target.classList.contains('foo')) {
      console.log('К элементу был добавлен класс foo');
    } else {
      console.log('У элемента был удалён класс foo');
    }
  });
});
// настраиваем mutationObserver так, чтобы он начал прослушивание изменения в HTML-элементе $myElem
mutationObserver.observe($myElem, {
  attributes: true,
});
</script>
Иван
Иван
Спасибо Александр! Даже и не знал про такую функцию, круто! В голове была только идея делать проверку через небольшой промежуток времени. Теперь буду этим способом пользоваться.
Эрик
Эрик
Здравствуйте, Александр. Не подскажите, как реализовать открытие/закрытие элемента при нажатии на него? Открыть получается, а вот закрыть нет.Прилагаю код открытия javascript. Надо реализовать закрытие.
<script type="text/javascript">
$(document).ready(function (){
    $('#main > dt').click(function (){
        $('#podmain > div').hide();
        var i=$(this).data('id');
        $('#podmain'+i).fadeIn();
    });
});
</script>
Александр Мальцев
Александр Мальцев
Здравствуйте! Тут одного кода не достаточно. Для более точного ответа, пример необходимо представить, например, на CodePen.
Как открыть элемент при нажатии на него, если он скрыт, вообще не понятно.
А вот скрыть можно.
// например, элемент с классом btn при нажатии на него
$('.btn').click(function(){
    $(this).hide();
});
Ещё пример, но с помощью добавления к элементу класса:
// например, элемент с классом btn при нажатии на него
$('.btn').click(function(){
    $(this).addClass(hide);
});
В этом варианте необходимо добавить ещё код в CSS:
.hide {
    display: none;
}
Архаил
Архаил
Добрый день Александр, подскажите пожалуйста как можно скрыть все элементы на странице с одним классом. Т.е. я кликнул на элемент с классом .elemItem и мне надо чтобы скрипт прошелся по странице и скрыл элементы с таким же классом .elemItem. Пробовал скрывать по id элемента, но скрипт скрывает мне только первый элемент(обработка только первого уникального id), к остальным он не доходит.
Александр Мальцев
Александр Мальцев
Здравствуйте, Архаил!

Можно выполнить так:

<p class="elemItem">1</p>
<p class="elemItem">2</p>
<p class="elemItem">3</p>
<p class="elemItem">4</p>
<p class="elemItem">5</p>

<script>
$('.elemItem').click(function(){
    $('.elemItem').hide();
});
</script>
Архаил
Архаил
Благодарю!
Архаил
Архаил
Добрый день! Подскажите как можно правильно реализовать такой функционал:
Мне необходимо при изменении разрешении экрана добавлять или удалять класс у элемента в зависимости от ширины экрана(если меньше к примеру <768). При изменении экрана использую resize для отслеживания ширины экрана, при нахождении нужной ширины в скрипте прописал поиск элемента по классу, добавляю ему новый класс — owl-carousel, чтобы отработали стили и другой скрипт-js используемый этот класс, но при получении нужной ширины экрана отрабатывает событие- добавляет класс, если экран изменяется еще не раз, он снова добавляет этот же класс несколько раз, событие отрабатывается несколько раз, как сделать чтобы событие resize отработало один раз если ширина экрана ниже указанной? Пытаюсь дописать скрипт который отображает превью изображений в портфолио(не помешаются в блоке, при смещении выглядят не красиво), чтобы при меньшем экране появлялся скролл и можно было скролить превьюшки.
Александр Мальцев
Александр Мальцев
Добрый день!
Пример как это можно сделать:
<div class="myClass"></div>
<div class="myClass"></div>

<script>
    $(window).resize(function(){
        var breakPoint = '768';
        var className = 'owl-carousel';
        var elementClass = '.myClass';
        if ($(this).width() < breakPoint) {
            /* если ширина меньше 768, то удаляем 
               у всех элементов, имеющих класс myClass
               класс owl-carousel (если конечно у них он есть) */
            $(elementClass).each(function(){
                if ($(this).hasClass(className)) {
                    $(this).removeClass(className);
                }
            });
        } else {
            /* если ширина больше или равно 768, то добавляем 
               ко всем элементам, имеющим класс myClass
               класс owl-carousel (если конечно у них их нет) */
            $(elementClass).each(function(){
                if (!$(this).hasClass(className)) {
                    $(this).addClass(className);
                }
            });
        }
    });
    $(window).resize();
</script>
Архаил
Архаил
Александр, Благодарю! Вы лучший!)
Архаил
Архаил
Александр, а вот подскажите, я использую сторонний скрипт карусели, который вызывается на разных контентах в разных страницах, но вот сейчас необходимо его немного видоизменить для карточки товара, лучше создать копию и перенаправить уже по новым классам в копию файла и в нем уже изменить структуру. Скрипт-owl-carousel дополнительно оборачивает контент в свои теги со своими классами, а при изменении ширины экрана мне надо получается каким то образов удалять созданную обертку и классы. Как будет правильно подойти к решению такой задачи?
Александр Мальцев
Александр Мальцев
Не знаю, обычно не изменяю исходные скрипты (если это возможно). Создаю дополнительные и уже в них изменяю логику.