jQuery – Обработка событий

Александр Мальцев
78K
2
Содержание:
  1. Обработка событий с помощью методов jQuery
  2. Как повесить несколько событий на один элемент
  3. Программный вызов события
  4. jQuery - Событие загрузки страницы (ready)
  5. jQuery - Событие загрузки (load)
  6. jQuery - События мыши
  7. jQuery – События клавиатуры
  8. jQuery – События элементов формы
  9. jQuery - Событие прокрутки (scroll)
  10. jQuery - Событие изменения размеров окна (resize)
  11. jQuery - Отмена стандартного поведения события
  12. Добавление событий к динамически созданным объектам
  13. jQuery - Удалить обработчик события
  14. Создание пользовательского события
  15. Комментарии

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

Событие – это «сигнал», возникающий в браузере, который сообщает вам, что что-то произошло для того, чтобы вы могли с ним взаимодействовать.

Например, событие click возникает при клике пользователем на DOM-элементе. Кроме click, в браузере генерируются множество других событий. Более детально познакомиться с ними можно в этой статье. Здесь же мы остановимся на рассмотрение методов, которые предоставляет библиотека jQuery для работы с ними.

Обработка событий с помощью методов jQuery

jQuery - Синтаксис функции on

Перед тем как переходить к добавлению элементам обработчиков событий, эти элементы сначала необходимо получить. Узнать о том, как найти нужные элементы на странице можно в статье jQuery - Выбор элементов.

В jQuery повесить событие (слушатель событий) на определённый элемент можно с помощью функций on и one, а также кратких записей on.

// функция on
.on(events,handler);
// функция one
.one(events,handler);

// events - событие или список событий через пробел, при наступлении которых необходимо выполнить обработчик (handler)
// handler - функция (обработчик события)

// краткая запись функции on
.event(handler);

// event - название события (можно использовать для обработки только тех событий, для которых в jQuery создана такая краткая запись)

Функция one отличается от on только тем, что она выполняет обработчик при наступлении указанного события только один раз.

Например, добавим с помощью функции on событие click для всех элементов с классом btn:

// использование в качестве обработчика анонимной функции
$('.btn').on('click', function() {
  // действия, которые будут выполнены при наступлении события...
  console.log($(this).text());
});

// использование обычной функции в качестве обработчика
var myFunction = function() {
  console.log($(this).text());
}
$('.btn').on('click', myFunction);

Вышеприведённый код, записанный с использованием короткой записи функции on:

$('.btn').click(function() {
  // действия, которые будут выполнены при наступлении события...
  console.log($(this).text());
});

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

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

$('#demo').on('click', function(e){
  // e – объект Event, содержащий дополнительную информацию о произошедшем событии
  // часто используемые свойства объекта Event
  e.preventDefault(); //отменить выполнение действия по умолчанию
  e.stopPropagation(); //остановить дальнейшее всплытие события
  // e.type – получить тип события
  // e.target – ссылка на элемент, на котором произошло событие
  // e.currentTarget - ссылка на текущий элемент (для которого сработал обработчик). Это свойство, как правило, равно функции this.
  // e.currentTarget === this
  // e.which – код клавиши (для мыши), код кнопки или символа (для клавиатуры)
  //e.pageX, e.pageY – координаты курсора, относительно левого верхнего угла документа
});

Пространство имён

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

Например:

// событие click в пространстве имён first
$('#demo').on('click.first',function(){
  console.log('1 обработчик события click');
});
// событие click в пространстве имён second
$('#demo').on('click.second',function(){
  console.log('2 обработчик события click');
});

Пространство имён - это очень удобная вещь. Она используется, например, когда вам необходимо вызвать не все события, а только с определённым именем.

// вызвать событие click в пространстве имён first
$('#demo').trigger('click.first');

// вызвать событие click в пространстве имён second
$('#demo').trigger('click.second');

Также с его помощью очень просто удалять определённые события:

//удалить обработчики события click в пространстве имён first
$('#demo').off('click.first');

//удалить обработчики события click в пространстве имён second
$('#demo').off('click.second');

Описание и примеры использования функций trigger и off рассматриваются в статье немного ниже.

Передача дополнительных данных в обработчик

При необходимости вы можете передать данные в обработчик события (посредством указания дополнительного аргумента в функции on). Доступ к переданным данным внутри обработчика осуществляется через объект Event.

Осуществляется это так (пример):

<div id="content"></div>
<button id="showContent1">Показать контент 1</button>
<button id="showContent2">Показать контент 2</button>
...

<script>
$('#showContent1').on('click', {title:'Заголовок 1', content: 'Содержимое 1...'}, function(e){
  var output = '<b>'+e.data.title+': </b>' + e.data.content;
  $('#content').html(output);
});
$('#showContent2').on('click', {title:'Заголовок 2', content: 'Содержимое 2...'}, function(e){
  var output = '<b>'+e.data.title+': </b>' + e.data.content;
  $('#content').html(output);
});
</script>

Как повесить несколько событий на один элемент

Пример использования одного обработчика для нескольких (2 или более) событий:

$('#id').on('keyup keypress blur change', function(e) {
  console.log(e.type); // тип события
});

// или так
var myFunction = function() {
  ...
}

$('#id')
  .keyup(myFunction)
  .keypress(myFunction)
  .blur(myFunction)
  .change(myFunction);

Для каждого события своя функция:

$("#id").on({
  mouseenter: function() {
    // обработчик события mouseenter...
  },
  mouseleave: function() {
    // обработчик события mouseleave...
  },
  click: function() {
    // обработчик события click...
  }
});

Пример использования в jQuery несколько обработчиков (функций) на одно событие:

$("#demo").click(function(){
  console.log('1 обработчик события click');
});
$("#demo").click(function(){
  console.log('2 обработчик события click');
});

Например, узнать в какой очерёдности будут выполняться события можно так:

var eventList = $._data($('#demo')[0], 'events');
console.log(eventList);

Программный вызов события

Для вызова события из кода в jQuery есть 2 метода:

  • trigger - вызывает указанное событие у элемента.
  • triggerHandler - вызывает обработчик события, при этом само событие не происходит.
$('#header').on('click',
  function() {
    console('Произошёл клик на элементе #header');
  }
});

// программный вызов события click элемента
$('#header').trigger('click');
// короткая запись данного вызова
$('#header').click();
// вызов обработчика события click у выбранного элемента
$('#header').triggerHandler('click');

jQuery - Событие загрузки страницы (ready)

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

Самая короткая запись события загрузки страницы в jQuery выглядит так:

$(function(){
  // действия, которые необходимо выполнить после загрузки документа...

});

Но, можно использовать и более длинную запись:

$(document).ready(function(){
  // действия, которые необходимо выполнить после загрузки документа...

});

jQuery - Событие загрузки (load)

Событие load браузер генерирует элементу, когда он и все вложенные в него элементы были полностью загружены. Данное событие предназначено только для элементов, в которых присутствует URL: image, script, iframe и window.

Например, выполнить функцию, когда страница будет полностью загружена (включая картинки):

$(window).on('load', function() {
  // действия после полной загрузки страницы...

});

Например, выведем сообщение в консоль, когда указанное изображение будет загружено:

<img id="image" src="image.png">
...
<script>
$('#image').on('load', function() {
  console.log('Изображение загружено');
});
</script>

jQuery - События мыши

В jQuery для отслеживания действий мыши наиболее часто используют следующие события:

  • mousedown
  • mouseup
  • click
  • mousemove
  • wheel
  • hover
  • mouseenter
  • mouseover
  • mouseleave
  • mouseout

jQuery - Событие клик (click)

Событие click является сложным событием, оно возникает после генерирования событий mousedown и mouseup. Событие mousedown возникает, когда указатель находится над элементом и кнопка мыши нажата. Событие mouseup происходит, когда указатель находится над элементом и кнопка мыши отпущена. Событие click генерируется, когда курсор находится над элементом, и клавиша мыши нажата и отпущена. Эти события могут получать любые HTML элементы.

Например, повесим обработчик на событие onclick элемента window. При наступлении данного события обработчик будет выводить номер нажатой клавиши и координаты курсора:

$(window).on('click', function(e) {
  // обработка события click...
  console.log('Нажата кнопка: ' + e.which); //1 - левая кнопка, 2 - средняя кнопка, 3 - правая
  console.log('Координаты курсора: x = ' + e.pageX + ' ; y = ' + e.pageY);
});

Например, повесим событие onclick на все элементы с классом btn:

$('.btn').on('click', function(){
  // код обработчика события нажатия кнопки
   ...
});
Краткая запись события по клику:
$('.btn').click(function(){
   ...
});

Например, разберем, как можно скрыть блок через некоторое время после события click:

<div class="message">
  ...<a class="hide-message" href="#">Скрыть блок через 5 секунд</a>...
</div>
...
<script>
$('.hide-message').click(function(e){
  e.preventDefault();
  var _this = this;
  setTimeout(function(){
    $(_this).closest('.message').hide();
  }, 5000);
});
</script>

jQuery - Событие при наведении (hover)

jQuery - Событие hover

Событие при поднесении курсора является сложным и состоит из 2 событий:

  • вхождения (mouseenter, mouseover);
  • покидания (mouseleave, mouseout).

События mouseenter и mouseleave в jQuery отличаются от mouseover и mouseout только тем, что они не возникают когда курсор соответственно входит и покидает внутренние элементы прослушиваемого элемента. Другими словами события mouseover и mouseout всплывают, а mouseenter и mouseleave – нет.

Например, изменим цвет элемента списка при поднесении к нему курсора:

<ul id="list">
  <li>Ручка</li>
  <li>Карандаш</li>
  <li>Линейка</li>
</ul>
...
<script>
$('ul>li').
  mouseenter(function(){
    // при вхождении в элемент
    $(this).css('color','orange');
  }).
  mouseleave(function(){
    // при покидании элемента
    $(this).css('color','black');
  });
</script>

Те же самые действия, но использованиям mouseover и mouseout:

$('ul>li').
  mouseover(function(){
    // при вхождении в элемент
    $(this).css('color','orange');
  }).
  mouseout(function(){
    // при покидании элемента
    $(this).css('color','black');
  });

Данные методы необязательно использовать вместе, их можно также применять по отдельности.

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

<div id="count">Количество: <span>0</span></div>
...
<script>
$('#count').mouseenter(function(){
  var count = parseInt($(this).find('span').text());
  count++;
  $(this).find('span').text(count);
});
</script>

Вместо использования mouseenter и mouseleave можно использовать событие hover.

Например, перепишем вышеприведённый пример, используя hover:

$('ul>li').hover(
  function(){
    // при вхождении в элемент
    $(this).css('color','orange');
  },
  function(){
    // при покидании элемента
    $(this).css('color','black');
  }
);

При использовании события hover в jQuery, первый обработчик используется для задания действий при вхождении курсора в элемент (mouseenter), а второй - при покидании (mouseleave).

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

Например:

$('h1').hover(function(){
  console.log('Произошло события входа в элемент или выхода из него');
});

jQuery - Событие движения мыши

Событие mousemove посылается элементу, когда указатель мыши перемещается внутри него. Любой HTML элемент может получать это событие.

$('.target').mousemove(function(e) {
  console.log('Вызван обработчик для события mousemove.');
  console.log('Координаты относительно левого верхнего угла документа: ' + e.pageX + ', ' + e.pageY);
  console.log('Координаты курсора внутри цели: ' + e.offsetX + ', ' + e.offsetY);
});

jQuery - Событие колёсика мыши (wheel)

Прослушивание события прокрутки колёсика (wheel) мышки можно осуществить так:

$(window).on('wheel', function(e) {
  // код обработчика (например)...
  console.log('Количество прокрученных пикселей: ' + e.originalEvent.deltaY);
  if (e.originalEvent.deltaY < 0){
    console.log('Прокручиваем вверх');
  } else {
    console.log('Прокручиваем вниз');
  }

});

Данное событие в отличие от scroll генерируется браузером только для колёсика мышки, при этом неважно прокручивается элемент или нет, т.е. с ним можно работать на элементах с overflow, равным hidden. Еще одно отличие заключается в том, что wheel генерируется до прокрутки, а scroll - после неё.

jQuery – События клавиатуры

При нажатии клавиши клавиатуры браузер генерирует события в следующем порядке:

keydown -> keypress -> keyup
  • keydown (клавиша нажата, но ещё не отпущена);
  • keypress (событие генерируется для букв, цифр и других клавиш, за исключением управляющих) – предназначено для того чтобы получить код символа (события keydown и keyup позволяют узнать только о коде клавиши, но не символа);
  • keyup (генерируется браузером при отпускании клавиши).

Например, напишем обработчик для прослушивания всех событий, которые происходят при нажатии клавиши:

<input id="target" type="text" value="">
...
<script>
$('#target').on('keydown keypress keyup', function(e) {
   console.log('Тип события: ' + e.type); // keydown, keypress, keyup
   console.log('Код нажатой клавиши или символа: ' + e.which); // код символа позволяет получить только keypress
   console.log('Нажата клавиша Alt: ' + e.altKey);
   console.log('Нажата клавиша Ctrl: ' + e.ctrlKey);
   console.log('Нажата клавиша Shift: ' + e.shiftKey);
   console.log('Нажата клавиша Cmd (osMac): ' + e.metaKey);
});
</script>

Пример, в котором показано, как можно прослушать событие keypress и узнать, нажато ли указанное сочетание клавиш:

$(document).keypress("c",
  function(e) {
    if(e.ctrlKey) {
      console.log('Нажато сочетание клавиш Ctrl+c');
    }
});

Пример, как можно прослушать сочетание клавиш Ctrl+Enter:

$(document).keydown(function(e) {
  // с поддержкой macOS X
  if ((e.ctrlKey || e.metaKey) && (e.keyCode == 13 || e.keyCode == 10)) {
    // ваши действия...

  }
}

Пример, с использованием событий keydown и keyup:

<input id="name" type="text">
...
<script>
$('#name').
  keydown(function(){
    $(this).css('background-color', 'yellow');
  }).
  keyup(function(){
    $(this).css('background-color, 'pink');
  });
</script>

jQuery – События элементов формы

В jQuery можно выделить следующие события для элементов формы и не только:

  • focus (focusin)
  • blur (focusout)
  • change
  • input (для текстовых элементов формы)
  • select
  • submit

jQuery - События получения и потери фокуса

Событие focus посылается элементу, когда он получает фокус. Данное событие генерируется для элементов input, select и ссылок (a href="..."), а также любых других элементов, у которых установлено свойство tabindex. Получение элементом фокуса обычно осуществляется посредством клика или нажатия клавиши Tab на клавиатуре. Событие focus не всплывает.

Кроме focus есть ещё похожее событие, называется оно focusin. В отличие от focus данное событие всплывает, и оно может, например, использоваться для обнаружения события фокуса родительскими элементами.

Событие blur посылается элементу, когда он теряет фокус. Так же как и focus, событие blur имеет похожее событие focusout. Данное событие отличается от blur тем, что оно может всплывать. Это возможность можно использовать, например, для получения его на родительских элементах, а не только на том элементе, который его вызвал (target).

Например, при получении элементом div события фокуса установим ему фон оранжевого цвета:

<div id="demo"><input type="text"></div>
...
<script>
$('#demo').
  focusin(function(){
    $(this).css('background-color','orange');
  })
  .focusout(function(){
    $(this).css('background-color','inherit');
  });
</script>

Точно такое же выполнить с помощью событий focus и blur не получится, т.к. они не всплывают:

$('#demo input').
  focus(function(){
    $(this).parent().css('background-color','orange');
  })
  .blur(function(){
    $(this).parent().css('background-color','inherit');
  });

jQuery - Событие изменения (change)

Событие change предназначено для регистрации изменения значения элементов input, textarea и select. Для элементов select, checkboxes, и radio кнопок данное событие возникает сразу (т.е. как только пользователь делает какой-то выбор). Но для других элементов данное событие не будет происходить до тех пор, пока этот элемент не потеряет фокус.

Пример использования события change для слежения за состоянием элемента checkbox. Доступность кнопки будет определять в зависимости от того в каком состоянии (checked или нет) находиться флажок:

<input type="checkbox" id="agree">
<button type="submit" id="send" disabled>Отправить</button>
...
<script>
$(function() {
  $('#agree').on('change', function(){
    if (this.checked) {
      $('#send').prop('disabled',false);
    } else {
      $('#send').prop('disabled',true);
    }
   });
});
</script>

Пример, в котором рассмотрим, как получить значение элемента select при его изменении:

<p id="result"></p>
<select id="list">
  <option value="1">Первое значение</option>
  <option value="2">Второе значение</option>
  <option value="3">Третье значение</option>
</select>
...
<script>
$(function() {
  $('#list').on('change', function(){
    var value = $(this).val();
    $('#result').text(value);
  });
});
</script>

Пример, в котором рассмотрим, как получить все выбранные элементы select при его изменении:

<select name="colors" multiple="multiple">
  <option>Зелёный</option>
  <option>Красный</option>
  <option>Синий</option>
  <option>Коричневый</option>
  <option>Фиолетовый</option>
  <option>Серый</option>
</select>
...
<script>
$('select[name="colors"]')
  .change(function () {
    var colors = [];
    $('select[name="colors"] option:selected').each(function() {
      colors.push($(this).text());
    });
    console.log('Выбранные цвета: ' + colors.join());
  })
  .change();
</script>

Пример программного вызова события change для элемента select:

// list - id элемента change
$('#list').trigger('change');
// краткая запись
$('#list').change();
// вызов только обработчика события change
$('#list').triggerHandler('change');

Пример использования события изменения change для получения значения элемента input:

<input type="text" name="name">
...
<script>
$(function() {
  // событие изменения значения input (возникает только после потери фокуса)
  $('input[name="name"]').on('change',
    function(){
      var value = $(this).val();
      console.log(value);
    });
});
</script>

Но кроме события change есть ещё событие input для текстовых элементов. Данное событие в отличие от change генерируется сразу, а не после того как данный элемент потеряет фокус.

Пример, использования события ввода для получения значения элемента input:

$('input[name="name"]').on('input',function(){
  var value = $(this).val();
  console.log(value);
});

Пример, в котором представлен один из способов получения значения элемента textarea:

<textarea name="text"></textarea>
...
<script>
$('textarea[name="text"]').on('input',function(){
  var value = $(this).val();
  console.log(value);
});
</script>

Пример, в котором рассмотрим, как с помощью события change получить значение выбранного элемента input с type, равным radio:

<input type="radio" name="platform" checked="checked" value="windows">Windows
<input type="radio" name="platform" value="linux">Linux
<input type="radio" name="platform" value="macos">macOS
...
<script>
$(function() {
  $('input[name="platform"]').on('change', function(){
    var value = $(this).val();
    console.log(value);
  });
});
</script>

jQuery - Событие выбора (select)

Событие выбора select генерируется браузером, когда пользователь внутри элементов input с type="text" или textarea выделяет текст.

$( "#target" ).select(function() {
  console.log('Вызван обработчик события select');
});

jQuery – Событие отправки формы (submit)

Событие submit возникает у элемента, когда пользователь пытается отправить форму. Данное событие может быть добавлено только к элементам form.

Пример, использования события submit:

<form id="feedback" action="action.php">
  ...
</form>
...
<script>
$('#feedback').submit(function(e) {
  // отменить отправку формы
  e.preventDefault();
  // другие действия, например, для отправки формы по ajax...

});
</script>

Программный вызов отправки формы:

$('#feedback').submit();
$('#feedback').trigger('submit');

jQuery - Событие прокрутки (scroll)

Для отслеживания состояния скроллинга в jQuery используется событие scroll.

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

// краткая запись функции
$(window).scroll(function() {
  // действия при скроллинге страницы...
  if ($(this).scrollTop()>200) {
    $('.scrollup').fadeIn();
  } else {
    $('.scrollup').fadeOut();
  }
});

jQuery - Событие изменения размеров окна (resize)

Для прослушивания события изменения окна браузера используется resize:

Например, создадим обработчик, который будет при изменении окна браузера выводить в конец страницы её ширину и высоту:

$(window).resize(function() {
  $('body').append('<p>Ширина x Высота = ' + window.innerWidth + ' x ' + window.innerHeight + '</p>');
});

jQuery - Отмена стандартного поведения события

Некоторые элементы в HTML имеют стандартное поведение. Например, когда пользователь нажимает на ссылку, он переходит по адресу указанному в атрибуте href. Если вам это действие не нужно, то его можно отменить. Для отмены стандартного поведения необходимо вызвать в обработчике этого события метод preventDefault объекта event.

Например, отменим стандартное поведение всех ссылок на странице, имеющих класс service:

$('a.service').on('click',function(e){
  //отменяем стандартное действие браузера
  e.preventDefault();
  // действия, которые будет выполнять ссылка
  ...
});

Что такое всплытие и как его остановить

jQuery - Как работает метод stopPropagation

Кроме отмены стандартного действия, в механизме событий есть ещё такое понятие как всплытие. Оно заключается в том, что когда браузер генерирует событие, то он это делает не только для текущего элемента (цели), но и для всех его потомков включая родителя:

текущий элемент (цель) -> родительский элемент цели -> прародительский элемент -> ... -> document -> window

В jQuery бывают сценарии, когда в представленной цепочке у какого-нибудь элемента то же есть обработчик для этого события, который выполнять не нужно. И чтобы это событие не распространилось на этот элемент, его необходимо остановить. Для этого в обработчике нужного элемента необходимо вызвать метод stopPropagation объекта event. После вызова этого метода событие остановится, и не будет всплывать.

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

<div class="mark">Некоторый текст...<span class="mark">фрагмент...</span>...продолжение...</div>
...
<script>
$('.mark').on('hover',
  function(e){
    e.stopPropagation();
    $(this).css('color',orange);
  },
  function(e){
    e.stopPropagation();
    $(this).css('color',black);
  }
});
</script>

В данном случае если не указывать метод stopPropagation, то при поднесении курсора к элементу span с классом mark данное событие возникнет не только у него, но и у всех его родительских элементов. А это в этом примере приведёт к тому, что изменится цвет не только текста, заключенного в span, но и всего абзаца.


Если вам необходимо отменить стандартное поведение браузера и остановить всплытие события, то в jQuery вместо вызова двух этих методов можно просто вернуть в качестве результата функции значение false.

$('a').on('click', function(e){
  //e.preventDefault();
  //e.stopPropagation();
  ...
  return false;
});

Добавление событий к динамически созданным объектам

Для того чтобы повесить событие на элемент, которого ещё нет, можно использовать следующую конструкцию функции on:

$(document).on(eventName, selector, handler);

// document или любой другой существующий родительский элемент
// eventName - имя события
// selector - селектор, осуществляющий фильтрацию потомков, для которых необходимо запустить обработчик события
// handler - обработчик события

Это действие можно осуществить благодаря тому, что событие всплывает, и, следовательно, возникает у всех предков этого элемента. А объект, до которого всплывают все события на странице, является document. Поэтому в большинстве случаев выбирают именно его. После этого зная селектор, функция on может программно отобрать среди элементов (элемента, который вызвал это событие (target) и всех его предков включая родителя) те, которые соответствуют ему. И затем для всех отобранных элементов выполнить указанный в функции on обработчик. Действия, посредством которых обработка события переносится на другой элемент (предок), называется в jQuery ещё процессом делегирования события.

Например, добавим событие к элементу, которого ещё нет на странице:

<button id="addButton" type="button">Добавить кнопку</button>

<script>
// при нажатии на элемент с id="addButton" добавить в начало страницы новую кнопку
$('#addButton').on('click', function(e) {
  $('body').prepend('<button class="deleteMe" type="button">Удалить меня</button>');
});
// добавить событие click, которое будет выполнено для элементов, которых ещё нет на странице
$(document).on('click','.deleteMe', function() {
  $(this).remove();
});
</script>

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

Например, запретим в комментариях переходить по внешним ссылкам (такие действия будем перенаправлять на страницу away):

$(document).on('click','#comment a',function(e) {
  if(!(location.hostname === this.hostname || !this.hostname.length)) {
    e.preventDefault();
    location.href='away?link='+encodeURIComponent($(this).attr('href'));
  }
});

jQuery - Удалить обработчик события

Удаление обработчиков события осуществляется с помощью метода off. При этом с помощью него можно удалить только те обработчики, которые добавлены посредством метода on.

Вызов метода off без аргументов снимет у указанных элементов все добавленные к ним обработчики событий.

Например, отключим все обработчики у элементов с классом link:

$('.link').off();

Например, удалим событие click у всех элементов с классом link:

$('.link').off('link');

Специальный селектор (**) позволяет удалить только делегированные события с сохранением не делегированных:

$('.link').off('click','**');

Удалить только указанные делегированные события (с помощью селектора):

// добавление делегированного события
$('ul').on('click','li', function(){
  // выводим в консоль контент элемента li
  console.log($(this).text());
});

// удаление делегированного события
$('ul').off('click','li');

Удалить все обработчики openModal делегированного события click в пространстве имён modal для элементов с классом show:

$('body').on('click.modal', '.show', openModal);

Создание пользовательского события

Для создания пользовательских событий в jQuery используются методы on и trigger.

Принцип создания специального события jQuery рассмотрим посредством следующего примера:

<div class="module">
  <p>...</p>
  <button class="success" type="button">Вызвать пользовательское событие highlight (цвет зелёный)</button>
  <button class="error" type="button">Вызвать пользовательское событие highlight (цвет красный)</button>
</div>
...
<script>
// добавляем ко всем элементам p пользовательское событие, которое будет изменять цвет текста и его содержимое
// получения данных, переданных методом trigger, осуществим посредством аргументов color и title
$('.module p').on('highlight', function(e, color, title) {
  $(this).css('color',color);
  $(this).text('Вызвано пользовательское событие highlight ' +title);
});
// при нажатии на элемент с классом success вызвать кастомное событие highlight и передать ему параметры
$('.success').click(function(){
  // используя второй аргумент передадим данные в обработчик события
  $(this).closest('.module').find('p').trigger('highlight',['green','(цвет зелёный)']);
});
// при нажатии на элемент с классом error вызвать кастомное событие highlight и передать ему параметры
$('.error').click(function(){
  // используя второй аргумент передадим данные в обработчик события
  $(this).closest('.module').find('p').trigger('highlight',['red','(цвет красный)']);
});
</script>

Комментарии ()

  1. Димол
    Вчера в 10:37
    Добрый день!
    Бьюсь с одной проблемой.
    У меня есть несколько меню в виде таблицы. По клику должен быть переход на обработчик событий, ну а дальше все стандартно.
    Если я эти меню сразу устанавливаю на странице, то все проходит штатно. Но мне нужна разная их конфигурация. А вот если я подгружаю отдельные меню из обработчика, то они не работают. Просто нет перехода на обработчик.
    В чем может быть дело?
    1. Александр Мальцев
      Сегодня в 02:02
      Привет!
      В этом случае нужно добавить обработчик на страницу после того, как подгруженные элементы будут вставлены на страницу.
      Другой способ – это воспользоваться делегированием событий (например, повесить обработчик события на document, а далее через второй аргумент передать селектор, который инициировал событие):
      $(document).on('click','.tab', function(){
        ...
      });
      
      1. Димол
        36 минут назад
        Спасибо за ответ, но если с первым вариантом более менее понятно, то с делегированием событий полный мрак.
        Не могли бы Вы пояснить на конкретном примере
        Планируется 5-6 таких таблиц. По клику на любой td вызывается файл tabl.php и он вместе с контентом выводит более низкие таблицы в любой конфигурации. Таблицы возвращаются, но вот клики по ним уже не работают.
        Таблица tab1
        «table class=tab1 tr
        td class=»saity" tabindex=«1»>aa td>
        td class=«saity» tabindex=«5»>bb td>

        td class=«saity» tabindex=«3»>cc td>
        td class=«saity» tabindex=«9»>dd td>
        tr table>

        Таблица tab5
        table class=tab5>tr>
        td class=«saity5» tabindex=«1»>aa2 td>

        td class=«saity5» tabindex=«9»>ddeee td>
        tr table>
        (Немного коряво, но если писать все правильно, то в Предпросмотре вообще ничего не понятно)
        Ну и 5 таких кодов, ведущих на tabl.php только вместо $('.saity'). будет $('.saity2'). и т.д.
        $('.saity').click(function(e){
        e.preventDefault();
        var saityy = $(this).attr('tabindex');
        $.ajax({
        type: «POST»,
        url: «tabl.php»,
        data: «saity=»+saityy,
        success: function(responce){
        $('#content').html(responce);
        }
        });});})
        1. Александр Мальцев
          Только что
          Для того чтобы подсказать желательно иметь «живой» пример.
          Если по-простому, то следует просто добавить обработчик для таблицы после того, как вы её вставите на страницу.
          Т.е. после:
          $('#content').html(responce);
    2. Ная
      02 марта 2021, 17:25
      Добрый день. Подскажите решение. На форме есть поле с календарем, при выборе определенной даты календаря(при изменении текстового поля) открывается другая форма.
      <input type="text" name="Date"/>
      . нужно использовать change или input?
      1. Ная
        03 марта 2021, 13:34
        поле с датой содержит скрипт календаря и запрещено для ручного ввода.
        вся проблема в том, что событие отрабатывается только после повторного ввода даты в поле.
        что нужно изменить, что бы событие происходило сразу после ввода поле нужной даты
        <script>
        $( document ).ready(function() {
         let dateOrange = ['15.03.2021',
                          '23.03.2021',
                          '28.03.2021',
                         ];
         var $orange_d= $('input[name="Date"]') 
        
        $orange_d.on("change", function() {
        //при совпадении даты в поле с датой из списка отображаем нужную форму
            for (var z = 0; z < dateOrange.length; z++) {
            if($(this).val() == dateOrange[z]){
            $orange_d.val("");//очищаем поле        
            $('#rec279982166').hide();
            $('#rec286065219').show();
            t_lazyload_update();
        };
        };
        }).trigger('change');
        });
              
        </script>
        
        1. Александр Мальцев
          03 марта 2021, 15:36
          Привет! В этом случае нужно использовать соответствующее событие используемого календаря.
          1. Ная
            03 марта 2021, 15:56
            а если бы это было просто текстовое поле формы?
            1. Александр Мальцев
              03 марта 2021, 16:05
              Тогда через событие input:
              $orange_d.on("input", function() {
                var val = $(this).val();
                if (dateOrange.indexOf(val) !== -1) {
                  // при совпадении даты...
                }
              });
              
      2. Димол
        11 февраля 2021, 11:32
        Добрый день!
        У меня задача, выбрать по номерам регионов России города.
        Например:
        1 Московская обл
        2 Брянская обл

        47 Бурятия
        и т.д.
        Я сделал это с помощью формы, select и change
        $(document).ready(function(){
          $('#reg_ros').change(function(){
            var id_region = $(this).val();
            $.ajax({
              type: "POST",
              url: "base9.php",
              data: "action=reg_rosz&id_region="+id_region,
              cache: false,
              success: function(responce){
                $('#City').html(responce);
              }
            });
          });
        })
        
        Но это не совсем удобно и некрасиво.
        Как сделать то же самое без формы? Что бы можно было разместить названия регионов в разных местах, а по клику на них в url: отправлялся номер региона и его название.
        Если удастся такое сделать, то у меня сразу появится еще несколько вариантов применения кроме городов.
        1. Александр Мальцев
          13 февраля 2021, 15:54
          Привет!
          Так для этого необязательно использовать форму.
          Можно сделать, например, так:
          <a href="#" data-region-id="1">Московская обл</a>
          <a href="#" data-region-id="2">Брянская обл</a>
          
          <script>
          $(function(){
            $('a[data-region-id]').click(function(e){
              e.preventDefault();
              var id_region = $(this).attr('data-region-id');
              $.ajax({
                type: "POST",
                url: "base9.php",
                data: "action=reg_rosz&id_region="+id_region,
                cache: false,
                success: function(responce){
                  $('#City').html(responce);
                }
              });
            });
          })
          </script>
          
          1. Димол
            14 февраля 2021, 12:42
            Спасибо огромное. Все работает.
            А статья интересная. Сразу все не осилил. Но добавил в закладки для более тщательной проработки.
        2. Tema1995
          10 февраля 2021, 10:30
          Александр, добрый день! Подскажите пожалуйста, как решить проблему! Есть такой скрипт:
          $(document).ready(function () {
            $('.ladder').on('mouseover', function () {
              $(this).find('.banner').fadeIn(500);
            });
            $('.ladder').on('mouseout', function () {
              $(this).find('.banner').fadeOut(500);
            });
          });
          
          При наведении на элемент он показывает баннер с надписью. При убирании курсора с элемента, табличка скрывается. Все работает нормально, но если наводить/выводить курсор на элемент и с элемента очень быстро (быстрее 500 миллисекунд), то события как будто накапливаются и картинка начинает исчезать/появляться столько раз, сколько было произведено ненужных дерганий мыши. Подскажите пожалуйста, как можно этого избежать. Спасибо!
          1. Александр Мальцев
            10 февраля 2021, 16:09
            Привет! Можно добавить stop, чтобы остановить выполнение текущей анимации для элемента:
            $(document).ready(function () {
              $('.ladder').on('mouseover', (function () {
                $(this).find('.banner').stop().fadeIn(500);
              }))
              $('.ladder').on('mouseout', (function () {
                $(this).find('.banner').stop().fadeOut(500);
              }))
            })
            
            1. Tema1995
              10 февраля 2021, 17:09
              Спасибо! Все работает! Не могли бы Вы объяснить только примерно как это работает. Не могу понять. Если здесь $(this).find('.banner').stop().fadeIn(500): когда курсор наводиться на элемент, работает метод stop() и анимация не запускается, то почему срабатывает fadeIn/fadeOut?
              1. Александр Мальцев
                14 февраля 2021, 06:27
                Отлично! Тут всё просто. Т.е. с помощью stop() вы останавливаете текущую анимацию у элемента, если она имеется, а затем запускаете новую с помощью fadeIn или fadeOut.
          2. Максим
            20 мая 2020, 01:36
            Александр, доброго времени суток! Подскажите, пожалуйста.
            Есть ajax.beginform на asp.net mvc 5, в форме есть кнопки при нажатии на которые должен вылазить банальный alert. Мой код не работает, посмотрите? Заранее спасибо)

            <ul class="dropdown-menu">
                @using (Ajax.BeginForm("Subscribe", "Home", new AjaxOptions { UpdateTargetId = "list", InsertionMode = InsertionMode.Replace }))
                                        {
                                            if (Model.SubscribeOnUserList.Any(x => x.LeadUser == item.UserId || x.UserSubscriber == item.UserId))
                                            {
                                                <li>
                                                    <button class="access" name="accessStatus" value="Разрешить" title="Разрешить пользователю просматривать все Ваши ссылки">Полный доступ</button>
                                                </li>
                                                <li>
                                                    <button class="unsubscribe" name="subscribeStatus" value="Отписаться" title="Больше не видеть закладки пользователя">Отписаться</button>
                                                </li>
                                            }
                                            else
                                            {
                                                <li>
                                                    <button class="subscribe" name="subscribeStatus" value="Подписаться" title="Подписаться">Подписаться</button>
                                                </li>
                                            }
                                        }
                                    </ul>
            
            И js код

            $("button.subscribe").click(function () {
                if (!confirm("Подписаться на пользователя? Вы будете видеть публичные закладки этого пользователя")) {
                    return false;
                }
            });
            
            1. Александр Мальцев
              20 мая 2020, 02:06
              Привет! Если элемент «button.subscribe» добавляется на страницу через AJAX, то его изначально нет на странице и такой код конечно работать не будет. Для таких случаев надо обрабатывать событие «click» для document или элемента, который изначально присутствует на странице и в котором находится этот элемент.
              Например:
              $(document).on('click', 'button.subscribe', function () {
                  if (!confirm('Подписаться на пользователя? Вы будете видеть публичные закладки этого пользователя')) {
                      return false;
                  }
              });
              1. Максим
                20 мая 2020, 19:08
                Ооо, спасибо большое, все работает! Теперь буду знать, как это делается!
            2. Roman Matviy
              16 мая 2020, 10:36
              Почему после нажатия на элемент в консоли вообще не показыватся то, что на этот элемент нажали?
              1. Александр Мальцев
                27 мая 2020, 15:13
                В консоли выводятся сообщения только тогда, когда в коде выполняется метод console.log(). Данный метод не связан с тем нажали ли вы на элемент или нет.
                Если вы хотите выводить в консоль элемент при его нажатии, то нужно добавить на страницу следующий скрипт:
                <script>
                $(document).on('click', function(e) {
                  e.stopPropagation();
                  console.log(e.target);
                });
                </script>
                
              2. Alexander
                10 августа 2018, 16:11
                Добрый день!
                Подскажите, как вставить селектор отрицания в on() конструкцию?
                Что то:
                $('div').on('click','div.class:not', function(){});
                Т.е. выбрать элемент div без класса. Я смотрел div:empty и крутил в разном порядке и разных скобках-кавычках, но не могу нащупать. Спасибо!
                1. Александр Мальцев
                  10 августа 2018, 17:10
                  Добрый!
                  Можно вот так:
                  $('div').on('click', 'div:not([class])', function () {});
                  
                2. Amsterdam
                  17 июля 2018, 23:09
                  Доброй ночи

                  Подскажи, пожалуйста, как повесить проверку выполнения двух событий? Например, нужно, что бы функция выполнялась только при условии, если ЛКМ нажата и курсор двинулся, а не при выполнении любого из этих событий.

                  .on('mousedown mousemove', function(e)
                  Срабатывает и при нажатии и при движении мышки…
                  1. Александр Мальцев
                    18 июля 2018, 03:58
                    Во-первых, события в JavaScript имеют асинхронную природу. Во-вторых, они не могут возникнуть одновременно. Т.е. между нажатием и перемещением курсора, или наоборот, всё равно пройдёт какой-то промежуток времени.

                    Если это действительно нужно, то можно воспользоваться следующим приёмом:
                    <div class="container" style="height:200px; background: lime;"></div>
                    ...
                    <script>
                    var 
                      isMouseDown = false,
                      isMouseMove = false,
                      isAction            = false;
                    
                    $('.container').on('mousedown mousemove', function(e) {
                      if (!(isMouseDown || isMouseMove)) {
                        setTimeout(function() {
                          isMouseDown = false;
                          isMouseMove = false;
                          isAction            = false;
                        }, 500);
                      }
                      if (e.type === 'mousedown' && !isAction) {
                        isMouseDown = true;
                      } else if (e.type === 'mousemove' && !isAction) {
                        isMouseMove = true;
                      }
                      if (isMouseDown && isMouseMove && !isAction) {
                        isAction = true;
                        // действия, которые нужно выполнить при наступлении 2 событий...
                        console.log(this);
                      }
                    });
                    </script>
                    
                    500 — это количество миллисекунд, которые начнут отсчитываться после наступления первого события (mousedown или mousemove). В течение этого времени будем ждать наступление второго события. И если оно в течении этого времени произойдёт, то будут выполнены действия, указанные после соответствующего комментария в коде
                    1. Amsterdam
                      18 июля 2018, 09:58
                      И да, не «одновременно», а совместно. Если мы нажали ЛКМ, но не потянули курсор, то событие не должно работать. Так же как с click, это же сложное событие включающее mousedown и mouseup. Мне нужно подобное условие, только с mousedown и mousemove (возможно).

                      Сейчас функция на элементе срабатывает и при обычном движении курсора в области и при нажатии ЛКМ. А требуется что бы срабатывало только при выполнении обоих условий.
                      1. Александр Мальцев
                        18 июля 2018, 16:31
                        В этом случае можно при возникновении события mousemove просто проверять находится ли левая кнопка мыши в нажатом состоянии или нет.
                        $('.element').on('mousemove', function(e){
                          if (e.which === 1) { // нажата ли ЛКМ
                            // код...
                        
                          }
                        });
                        
                        Или нужно какое-то другое поведение?
                        1. Amsterdam
                          18 июля 2018, 17:29
                          Сейчас, получается, срабатывает тоже по нажатию. Т.е. оно зафиксировало движение мышки над элементом, потом, при клике, ловит нажатие ЛКМ.

                          Но нужно, что бы оно ловило движение курсора после нажатия ЛКМ. Т.е. нажали — шевельнули — сработало действие.

                          В целом, пытаюсь реализовать функционал как у слайдеров-каруселей, где зажатой мышкой они листаются, только здесь функцию кручения хотел переложить на уже имеющуюся, которая работает так же по клику на стрелочки.
                          1. Александр Мальцев
                            19 июля 2018, 07:39
                            Пример кода, который будет «ловить» движение курсора после нажатия на кнопку мыши:
                            $('.element').on('mousedown', function(e) {
                            
                              $(this).on('mousemove', function(e) {
                                console.log('moving...');
                                // ...
                              });
                            
                            });
                            
                            $('.element').on('mouseup mouseout', function(e) {
                              $(this).off('mousemove');
                            });
                            
                            Для слайдера, но тут тоже зависит от поведения которое вы хотите на него повесить данный функционал можно организовать ещё так.

                            Т.е. нажали на клавишу мышки, зафиксировали координату X. Отпустили мышку, проверили изменение координаты X. Если она изменилась, то пользователь значит ещё перемещал курсор. Далее в зависимости от величины смещения по X, можно осуществить переход к предыдущему или следующему кадру слайдера.
                            var startX = 0;
                            $('.element').on('mousedown', function(e) {
                              startX = e.pageX;
                            });
                            $('.element').on('mouseup', function(e) {
                              if (e.pageX - startX > 100) {
                                console.log('right...');
                              } else if (startX - e.pageX > 100) {
                                console.log('left...');
                              } 
                            });
                            
                            1. Amsterdam
                              19 июля 2018, 10:03
                              Вот такой вариант, уже совсем практически рабочий):

                              var pageY = 0;
                                  $(function () {
                                      $('.nizina').mousedown(function (event) {
                              
                                          $(this).on('mousemove', function (e) {
                                              if (pageY) {
                                                  if (event.pageY > pageY) {
                              
                                                      console.log('Мышка движется вверх');
                              
                                                  } else if (event.pageY < pageY) {
                                                      console.log('Мышка движется вниз');
                                                  }
                                              }
                                              pageY = event.pageY;
                                          });
                                      });
                                  });
                                  $('.nizina').on('mouseup mouseout', function (e) {
                                      $(this).off('mousemove');
                                  });
                              Только почему то не каждый раз срабатывает корректно. Пару раз движение отлавливает верно, следующий не отлавливает вообще либо не верно (мышка движется вверх — он показывает что вниз)
                              1. Amsterdam
                                19 июля 2018, 08:59
                                Конечная цель — зажать ЛКМ, двинуть курсор вверх — выполнить одну функцию. Зажать ЛКМ, двинуть курсор вниз — выполнить другую функцию (слайдер вертикальный). Ваши решения — почти то нужно. Сейчас попробовал объединить варианты, вставив отслеживание по координате, но пока что то совсем не то похоже получилось. Не работает…

                                $('.element').on('mousedown', function (e) {
                                        startY = e.pageY;
                                        $(this).on('mousemove', function (e) {
                                            if (e.pageX - startY > 100) {
                                                console.log('up...');
                                            } else if (startY - e.pageY > 100) {
                                                console.log('down...');
                                            }
                                        });
                                
                                    });
                                1. Александр Мальцев
                                  19 июля 2018, 13:44
                                  У вас опечатка на 4 строчки. Необходимо e.pageX заменить на e.pageY.
                                  1. Amsterdam
                                    19 июля 2018, 13:48
                                    Спасибо, но это я заметил. Код сейчас уже другой:

                                    var pageY = 0;
                                    $(function () {
                                    $('.nizina').mousedown(function (event) {

                                    $(this).on('mousemove', function (e) {
                                    if (pageY) {
                                    if (event.pageY > pageY) {

                                    console.log('Мышка движется вверх');

                                    } else if (event.pageY < pageY) {
                                    console.log('Мышка движется вниз');
                                    }
                                    }
                                    pageY = event.pageY;
                                    });
                                    });
                                    });
                                    $('.nizina').on('mouseup mouseout', function (e) {
                                    $(this).off('mousemove');
                                    });

                                    Для наглядного примера: jsfiddle.net/mrvo5896/3/

                                    Но не каждый раз срабатывает корректно. Пару раз движение отлавливает верно, следующий не отлавливает вообще либо не верно (мышка движется вверх — он показывает что вниз)
                                    1. Александр Мальцев
                                      19 июля 2018, 13:58
                                      Так не корректно. Нужно сравнить например, когда пользователь «протянул» хотя бы пикселей 50 по вертикали. А так будет срабатывать даже когда пользователь просто «дернул» мышкой.
                                      1. Amsterdam
                                        19 июля 2018, 14:01
                                        Рывок мышью в нужном направлении так же устраивает, только он это направление почему то не всегда верно определяет. Думаете изза того что не сравнивается расстояние?
                                        1. Александр Мальцев
                                          19 июля 2018, 14:36
                                          Поправил ваш код. Порог всё равно какой-то нужно поставить, хотя бы пикселей 10. Ну это уже как пожелаете.
                                          var pageY = 0;
                                          var $debugContainer;
                                          var porog = 10;
                                          $(function () {
                                            $debugContainer = $('#debug');
                                            $('.nizina').on('mousedown', function (e) {
                                              pageY = e.pageY;
                                              $(this).on('mousemove', function (e) {
                                                if (e.pageY > pageY + porog) {
                                                  pageY = e.pageY;
                                                  $debugContainer.html('Мышка движется вниз');
                                                  console.log('Мышка движется вниз');
                                                } else if (e.pageY < pageY - porog) {
                                                  pageY = e.pageY;
                                                  $debugContainer.html('Мышка движется вверх');
                                                  console.log('Мышка движется вверх');
                                                }
                                              });
                                            });
                                          });
                                          $('.nizina').on('mouseup mouseout', function (e) {
                                            $(this).off('mousemove');
                                          });
                                          
                                          1. Amsterdam
                                            19 июля 2018, 15:53
                                            Большое вам спасибо за код. Очень помогаете разобраться… Только дело даже не в задержке. Сейчас понял, что отсчет координаты оно начинает вести от предыдущего значения, и изза этого получается такой глюк.

                                            Кажется, нужно обнулять координаты. Как бы это сделать..?
                                            1. Александр Мальцев
                                              19 июля 2018, 17:01
                                              В исправленном коде всё правильно. Никаких действий по обнулению координат не нужно.
                                              При нажатии кнопки, сохраняем текущую точку, а точнее координату Y в переменную pageY.
                                              Далее при перемещении курсора, например, вниз и наступлении условия e.pageY > pageY + porog, т.е. когда текущая координата больше чем сохранённая в pageY + порог, выполняем, например необходимую функцию. А также обновляем обязательно pageY, чтобы отсчёт шёл для следующего действия уже от этой координаты. Далее при продолжении движения курсора повторяем действия. Т.е. при наступлении условия e.pageY > pageY + porog или e.pageY < pageY — porog выполняем соответствующую функцию и обновляем значение pageY.
                                              При отпускании кнопки или перемещения курсора за пределы элемента удаляем обработчик для события mousemove у соответствующего элемента.

                                              Далее при нажатии кнопки мыши повторяем все действия сначала…
                                              1. Amsterdam
                                                19 июля 2018, 17:32
                                                Так вот потому что отсчет ведется от сохраненной координаты, я думаю, оно так и работает. Вот полный код того, над чем карплю, так сказать, если интересно: jsfiddle.net/mrvo5896/29/

                                                (здесь тянем за .item — оранжевый круг)

                                                Если тянуть выше предыдущей точки «захвата» и в другом направлении, тогда работает не так как задумывалось.
                                                1. Александр Мальцев
                                                  21 июля 2018, 05:30
                                                  Попробуй сделать так:
                                                  var pageY = 0;
                                                  var porog = 10;
                                                  $(function () {
                                                    $('.item').on('mousedown', function (e) {
                                                      pageY = e.pageY;
                                                      $(this).on('mousemove', function (e) {
                                                        if (e.pageY > pageY + porog) {
                                                          pageY = e.pageY;
                                                          var index = parseInt($this.attr('data-state')) + 1;
                                                          if (index <= $this.find('.item').length) {
                                                            $this.attr('data-state', index);
                                                          } else {
                                                            $this.attr('data-state', 1);
                                                          }
                                                          $(this).off('mousemove');
                                                          return;
                                                        } else if (e.pageY < pageY - porog) {
                                                          pageY = e.pageY;
                                                          var index = parseInt($this.attr('data-state')) - 1;
                                                          if (index < 1) {
                                                            $this.attr('data-state', $this.find('.item').length);
                                                          } else {
                                                            $this.attr('data-state', index);
                                                          }
                                                          $(this).off('mousemove');
                                                          return;
                                                        }
                                                      });
                                                    });
                                                  });
                                                  $('.item').on('mouseup mouseout', function (e) {
                                                    $(this).off('mousemove');
                                                  });
                                                  
                                                  Т.е. добавить инструкции прерывающие работу при выполнении одного из условий:
                                                  $(this).off('mousemove');
                                                  return;
                                                  
                                                  1. Amsterdam
                                                    22 июля 2018, 00:50
                                                    Вот это — то что нужно! Шикарно. Спасибо тебе больше! Теперь работает как нужно, красиво.

                                                    Очень помог разобраться.

                                                    Сообщи пожалуйста, куда можно скинуть финансовую благодарность)
                                                    1. Александр Мальцев
                                                      23 июля 2018, 13:57
                                                      Отлично!
                                                      Оставить некоторую сумму в порядке дарения можно на этой странице.
                                                      1. Amsterdam
                                                        24 июля 2018, 08:58
                                                        Финансовую благодарность отправил Александр! Спасибо еще раз.

                                                        Но сейчас обнаружил в нашей работе небольшой нюанс — если курсор отпускаем за пределами кружка, то движение не срабатывает. И что то не получается это поправить. Пробовал сделать, что бы mouseup не отключал работу, но получилось похоже что то невменяемое у меня, не работало…
                                                        1. Александр Мальцев
                                                          24 июля 2018, 14:54
                                                          Тогда можно выполнить немного по-другому. Например, так.

                                                          1. Amsterdam
                                                            24 июля 2018, 16:45
                                                            Спасибо, но так начинает прокручиваться по клику… В принципе я решил проблему иным путем, прикрепив невидимые блоки большого размера, имитирующую область зацепления)
                                                            1. Александр Мальцев
                                                              24 июля 2018, 17:41
                                                              Так тоже можно.
                                                              Но с использованием делегирования решение будет более оптимальным.
                                                              Ага, заметил, что допустил ошибку. Поправил, код здесь.
                                                              1. Amsterdam
                                                                26 июля 2018, 08:08
                                                                Спасибо! Теперь, кажется, все действительно отлично!
                                2. Amsterdam
                                  19 июля 2018, 08:34
                                  Спасибо, это почти то что нужно! Первый вариант выполняет поставленную функцию, а второй как раз то, что планировалось реализовать дальше. Только почему то он не отрабатывает… ничего не происходит по движению вправо / влево…
                                  1. Александр Мальцев
                                    19 июля 2018, 13:46
                                    Да, нет должно.
                                    К слайдеру chiefSlider добавил, работает.
                                    Правда переписал решение, которое вам предложил, на «чистом» JavaScript, т.к. слайдер построен без использования jQuery.
                          2. Amsterdam
                            18 июля 2018, 08:31
                            Большое спасибо за разъяснение. В целом, задача — добиться эффекта перемещения слайда курсором мышки с зажатой ЛКМ. Пытаюсь понять, как это реализовать.
                        2. Олег
                          02 апреля 2018, 19:54
                          Здравствуйте, помогите, нужно добавлять класс к body каждый раз когда открывается меню nav.top_mnu, оно открывается на всю страницу. Класс который нужно добавлять необходим для того чтобы запретить скролинг сайта во время просмотра меню стилем overflow: hidden. Не хватает знаний реализовать. Помогите!
                          1. Александр Мальцев
                            03 апреля 2018, 15:27
                            Здравствуйте!
                            Это зависит от того как оно реализовано.
                            Например, для меню Boostrap 4 Navbar это реализуется так:
                            $('.navbar-collapse').on('show.bs.collapse', function(){
                                $('body').addClass('navbar-open');
                            });
                            $('.navbar-collapse').on('hide.bs.collapse', function(){
                                $('body').removeClass('navbar-open');
                            });
                            
                            Вы можете сделать подобным образом. Для этого вам необходимо добавить в определённые места js-кода вашего меню строчки генерирования событий. Например, такие же как в Boostrap 4 Navbar, т.е. show.bs.collapse и hide.bs.collapse. А затем использовать вышеприведённый код для добавления и удаления класса navbar-open.
                          2. Архаил
                            11 декабря 2017, 14:13
                            Добрый день! Подскажите пожалуйста, почему при клике по элементу, он событие срабатывает только со второго раза?
                            <script type="text/javascript">
                                function l_image (a) {
                                    $('.individColorImg').click(function(){
                                        idClick = $(this).attr('id');
                                        var idCat = idClick.substr(5);
                                        document.getElementById("example_img_" + idCat + "_id").src=a;
                                    });
                                }
                            </script>
                            При клике по цвету меняет изображение. Код в на странице .tpl:
                            <img class="x-img-main" src="../ru/picture/{$itemChild.pic_big}" alt="" id="example_img_{$itemChild.id_gr_pr}_id" />
                            
                            <div class="colorImgsSection">
                                 {foreach $itemChild.id_prod as $item => $itemChildProd}
                                      <a class="colorImgs individColorImg" href="javascript:l_image ('../ru/picture/{$itemChildProd.pic_big}')" id="prod-{$itemChild.id_gr_pr}" >
                                      <span style="background-color: {$itemChildProd['COLOR']};"></span></a>
                                  {/foreach}
                            </div>
                            :
                            1. Архаил
                              12 декабря 2017, 13:56
                              Вопрос закрыт, решил самостоятельно задачу.
                            Войдите, пожайлуста, в аккаунт, чтобы оставить комментарий.