- Что делать, когда “this” теряет ссылку на контекст
- Вложенные функции (Nested Functions)
- that/self
- Стрелочные функции (Arrow function)
- Функции обратного вызова (Method as callback)
- Стрелочная функция
- React-компоненты (React Components)
- Не использовать “this»
- Заключение
- Функция jQuery onclick не работает [дублировать]
- 18 ответов
- Примечание:
- Почему $(this) не работает?
- 5 ответов 5
- Всё ещё ищете ответ? Посмотрите другие вопросы с метками jquery или задайте свой вопрос.
- Похожие
- Подписаться на ленту
- JQuery на клик не работает после изменения DOM
- 3 ответа
- Почему эта функция щелчка jQuery не работает?
Что делать, когда “this” теряет ссылку на контекст
Привет, Хабр! Представляю вашему вниманию перевод статьи «What to do when “this” loses context» автора Cristi Salcescu.
Лучший способ избежать потери контекста this – не использовать this. Однако, это не всегда возможно. Например, мы работаем с чужим кодом или библиотекой, которые используют this.
Литерал объекта, функция-конструктор, конструктор объектов класса в системе прототипов. Псевдопараметр this используется в системе прототипирования для того, чтобы дать доступ к свойствам объекта.
Давайте рассмотрим несколько случаев.
Вложенные функции (Nested Functions)
this теряет ссылку на контекст внутри вложенных функций.
У метода doSomething() две вложенные функции: doAnotherthing() и log(). При вызове service.doSomething(), this теряет ссылку на контекст во вложенной функции.
Один из способов решения проблемы – метод bind(). Взгляните на следующий код:
bind() создает новую версию функции, которая при вызове уже имеет определенное значение this.
function doAnotherThing()< /*…*/>.bind(this) создает версию функции doAnotherThing(), которая берет значение this из doSomething().
that/self
Другой вариант – объявить и использовать новую переменную that/self, которая будет хранить значение this из метода doSomething().
Мы должны объявлять let that = this во всех методах, использующих this во вложенных функциях.
Стрелочные функции (Arrow function)
Стрелочная функция даёт нам еще один способ решения этой проблемы.
Стрелочные функции не создают собственный контекст для this, а используют значение this окружающего контекста. В примере выше она использует значение this родительской функции.
Недостаток этого способа в том, что мы не можем задать имя стрелочной функции. Имя функции играет важную роль, так как повышает читабельность кода и описывает её назначение.
Ниже представлен тот же код с функцией, выраженной через имя переменной:
Функции обратного вызова (Method as callback)
this теряет ссылку на контекст при использовании метода в качестве функции обратного вызова. Посмотрим на следующий класс:
Давайте разберем ситуации, в которых метод service.doSomething() используется как коллбэк-функция.
Во всех случаях выше this теряет ссылку на контекст.
Мы можем использовать bind() для решения этой проблемы. Ниже приведен код этого варианта:
Стрелочная функция
Еще один способ – создание стрелочной функции, которая вызывает service.doSomething().
React-компоненты (React Components)
В компонентах this теряет ссылку на контекст, когда методы используются в качестве коллбэков для событий.
В качестве решения мы можем создать новые функции в конструкторе, которые будут использовать bind(this).
Не использовать “this»
Нет this — нет проблем с потерей контекста. Объекты могут создаваться с помощью фабричных функций (factory functions). Посмотрите на этот пример:
Контекст остается если использовать метод в качестве коллбэка.
Заключение
this теряет ссылку на контекст в различных ситуациях.
bind(), использование переменной that/self и стрелочные функции — это способы решения проблем с контекстом.
Фабричные функции дают возможность создавать объекты без использования this.
Источник
Функция jQuery onclick не работает [дублировать]
У меня была такая же проблема в прошлом на многих сайтах, которые я сделал здесь на работе. Единственный гарантированный способ удостовериться, что пользователь получил письмо, — это дать пользователю возможность добавить вас в безопасный список. Любой другой метод действительно будет только тем, что может помочь с ним и не гарантируется.
18 ответов
Начиная с jQuery 1.7, вы должны использовать jQuery.fn.on :
До этого рекомендуется использовать live() :
Однако live() устарел в 1.7 в пользу on() и полностью удален в 1.9. Подпись live() :
. может быть заменена следующей on() сигнатурой:
Например, если ваша страница динамически создавала элементы с именем класса dosomething , вы привязывали бы событие к родительскому, который уже существует (здесь есть нуль проблемы, вам нужно что-то, что существует для привязки, не привязка к динамическому контенту), это может быть (и самый простой вариант) — document . Хотя иметь в виду document , возможно, не самый эффективный вариант .
Любой родитель, который существует в момент привязки события, прекрасен. Например,
Любой родитель, который существует в момент привязки события, и если ваша страница динамически создавала элементы с помощью кнопки имени класса, вы привязывали бы событие к родительскому, который уже существует
Это чистое решение для JavaScript без каких-либо библиотек или плагинов:
Кредит относится к Dave и Sime Vidas
Использование более современных JS, hasClass может быть реализовано как:
Я искал решение, позволяющее работать $.bind и $.unbind без проблем в динамически добавленных элементах.
Поскольку on () делает трюк для присоединения событий, чтобы создать фальшивую отвязку на тех, к которым я пришел:
Используйте метод .on() jQuery http://api.jquery.com/on/ для присоединения обработчиков событий к элементу live.
Также с версии 1.9 .live() удаляется.
Вот почему динамически созданные элементы не реагируют на клики & nbsp;:
В качестве обходного пути вы должны прослушивать все клики и проверять исходный элемент & nbsp;:
Это называется «Event Delegation». Хорошие новости, это встроенная функция в jQuery: -)
Я предпочитаю использовать селектор, и я применяю его в документе.
Это привязывается к документу и будет применяться к элементам, которые будут отображаться после загрузки страницы.
вы можете использовать
, эти два метода эквивалентны, но имеют другой порядок параметров.
Вы можете присоединить событие к элементу при динамическом создании с помощью jQuery(html, attributes) .
Начиная с jQuery 1.8, любой метод экземпляра jQuery (метод jQuery.fn ) можно использовать как свойство объекта, переданного второму параметру:
Это делается путем делегирования событий. Событие будет привязываться к элементу-оболочке, но будет делегировано элементу селекторного класса. Вот как это работает.
Примечание:
Элемент-оболочка-оболочка может быть любым ex. документа, тела или вашей обертки. Упаковщик должен уже существовать.
Обратите внимание на класс «MAIN», в который помещается элемент, например
. В приведенном выше сценарии объект MAIN, который будет наблюдать jQuery, является «контейнером».
Тогда вы в основном будете иметь имена элементов в контейнере, такие как ul , li и select :
Более гибкое решение для создания элементов и связывания событий ( source )
Примечание. Это создаст экземпляр обработчика события для каждого элемента (может повлиять на производительность при использовании в петлях)
Я предпочитаю, чтобы прослушиватели событий были развернуты модульной функцией, а не сценарием прослушивателя событий уровня document . Итак, мне нравится ниже. Обратите внимание: вы не можете переадресовать элемент с одним и тем же прослушивателем событий, поэтому не беспокойтесь о прикреплении слушателя более одного раза — только один палец.
Привязать событие к родительскому объекту, который уже существует:
В документации jQuery.fn.on есть хорошее объяснение.
Обработчики событий привязаны только к выбранные в данный момент элементы; они должны существовать на странице, когда ваш код делает вызов .on() .
Таким образом, в следующем примере #dataTable tbody tr должен существовать до генерации кода.
Если на страницу вводится новый HTML-код, предпочтительнее использовать делегированные события для присоединения обработчика событий, как описано ниже.
Делегированные события имеют то преимущество, что они могут обрабатывать события от элементов потомков, которые будут добавлены в документ позже. Например, если таблица существует, но строки добавляются динамически с использованием кода, следующее будет обрабатывать ее:
В дополнение к их способности обрабатывать события на дочерних элементах, которые еще не созданы, другим преимуществом делегированных событий является их потенциал для гораздо более низких накладных расходов, когда необходимо контролировать многие элементы. В таблице данных с 1000 строками в tbody первый пример кода прикрепляет обработчик к 1000 элементам.
Подход с делегированными событиями (второй пример кода) прикрепляет обработчик события только к одному элементу , tbody , и событию нужно только выровнять один уровень (от щелчка tr до tbody ).
Примечание. Делегированные события не работают для SVG .
Источник
Почему $(this) не работает?
Я бы хотел, чтобы при нажатии был слайд тоггл, но думаю, что селектор не правильно поставлен.
Подскажите пожалуйста в чем проблема, почему $(this) не работает?
P.S.: jquery подключил
5 ответов 5
Вообще говоря, $(this) у вас работает. Не работает у вас .find(‘.dropb’) — потому что элементы .dropb не являются дочерними для .menu-item .
Надо искать от родителя:
посмотрите мой пример
только не стоит на ссылки вешать дополнительные подписки на click событие.
$(this) в данном случае — это элемент ссылки, внутри него нет .dprop .
Всё ещё ищете ответ? Посмотрите другие вопросы с метками jquery или задайте свой вопрос.
Похожие
Подписаться на ленту
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
дизайн сайта / логотип © 2021 Stack Exchange Inc; материалы пользователей предоставляются на условиях лицензии cc by-sa. rev 2021.10.18.40485
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Источник
JQuery на клик не работает после изменения DOM
Я настроил свой HTML в бритве, как показано ниже:
Кнопка onclick выглядит так:
Поэтому изначально эта кнопка «Добавить в список наблюдения» отсутствует в DOM. Он загружается в DOM после выполнения поиска на веб-сайте.
Как только это будет сделано, событие onclick работает очень хорошо. Когда публикация завершена, я скрываю кнопку и обновляю DOM, чтобы показать пользователю, что он добавил этого пользователя в список наблюдения.
Теперь снова выполняем поиск для другого пользователя, который не был добавлен в список наблюдения, и кнопка «Добавить в список наблюдения» с классом «btnSave Watchlist» снова загружается в DOM.
Но на этот раз он полностью не отвечает . Я проверил, инициируется ли действие в контроллере, но не . Кнопка кажется «замороженной» .
Есть идеи, что это может быть, ребята?
Постскриптум Все это делается без обновления страницы вообще. Я не хочу обновлять страницу для конечного пользователя .
Редактируйте здесь кнопку btnSaveWatchList с классом:
3 ответа
Есть идеи, что это может быть, ребята?
Да, разница между разметкой (в основном простая строка) и объектной моделью документа. Вы присоединяете обработчик событий к определенным DOM-узлам, но при загрузке новой разметки этот узел удаляется, и из предоставленной вами разметки создается новый.
И слушатель события также ушел со старого узла.
В настоящее время ваш код мне не совсем понятен, поэтому я не уверен на 100%, что это решит проблему, но вот мое решение:
Возможно, вы связываете элемент, который вы рендерите, с помощью jquery позже.
Есть 2 способа решить эту проблему. Самым простым (для меня) является использование привязки стиля родитель-потомок. Это означает, что вы привязываете привязку к родителю, и jQuery проверяет, щелкает ли дочерний элемент по факту. Это на самом деле работает с динамическим контентом (HTML, который был загружен через AJAX или что-то еще)
Пример:
Или есть другой путь; заставляя ваш вызов функции переустанавливать привязку каждый раз при рендеринге html (чуть менее эффективно)
Пример:
Пожалуйста, обратите внимание на мои комментарии здесь. Я скучаю по большому количеству информации, поэтому я поставил здесь несколько «вопросов».
Вы должны сначала позвонить setBinding() куда-нибудь (как на document.ready? ), иначе это не сработает.
Обратите внимание, что вы должны вызывать функцию setBinding() после того, как отрендерите нужную кнопку.
Где-то за пределами кода, который вы показываете в своем вопросе, вы визуализируете эту кнопку. Является ли это правдой append() или html() , я не знаю, но куда бы вы ни создавали эту кнопку, добавляйте ее после html() : element.html(myhtml).promise().done(setBinding);
Я предлагаю вам создать функцию с обязательным действием.
Если ваш документ готов, просто вызовите функцию bindButton. Затем, после каждого звонка, ваша кнопка снова будет связана, потому что вы очищаете содержимое div.
Источник
Почему эта функция щелчка jQuery не работает?
Приведенный выше код не работает. Когда я нажимаю #clicker, он не предупреждает и не скрывается. Я проверил консоль, ошибок нет. Я также проверил, загружается ли JQuery, и действительно ли это так. Так что не уверен, в чем проблема. Я также сделал функцию готовности документа с предупреждением, и это сработало, поэтому я не уверен, что я делаю не так. Пожалуйста помоги. Спасибо!
Вы должны добавить код javascript в $(document).ready(function() <>); блок.
Как указано в документации jQuery : «Страницей нельзя безопасно управлять, пока документ не будет« готов ». JQuery определяет это состояние готовности за вас. Код, включенный в него, $( document ).ready() будет запускаться только после того, как объектная модель документа (DOM) страницы будет готова для JavaScript код для выполнения «
Я нашел лучшее решение этой проблемы, используя ON с $ (document).
для начала идентификатора см. ниже:
наконец, через 1 неделю мне не нужно добавлять триггер onclick. Я надеюсь это поможет многим людям
Ваш код может работать без document.ready (), просто убедитесь, что ваш скрипт находится после #clicker. Ознакомьтесь с этой демонстрацией: http://jsbin.com/aPAsaZo/1/
Идея в готовом концепте. Если вы уверены, что ваш скрипт является последним на вашей странице или находится после затронутого элемента, он будет работать.
Примечание: вjsbindemo замените http на https там в коде, или используйте этот вариант Demo
Вам нужно обернуть свой Javascript-код с помощью $(document).ready(function()<>); Look this JSfiddle .
Источник