кому не лень, поделитесь опытом по javascript
Решил я вот в одной из своих программ избавиться от jquery
Его там реально 4 строчки и нет смысла его тянуть.
Но что то я туплю.
У меня был некий обработчик события change у формы
Работает как нужно — события изменения любого элемента этой формы запускают этот код и что важно — this всегда ссылается на форму. Что позволяет следующей строкой получить в переменную все значения всех элементов формы, неважно какой именно был изменен.
Начинаю разбираться с событиями в javascript.
Опираюсь на это learn.javascript.ru/introduction-browser-events
и там описывается три способа создать реакцию на событие.
Пишу вот такое
Так как же правильно обработать событие change чтобы в идеале event.target указывавал на форму в которой произошло измеенние, а не на сам элемент или хотя бы, а как грамотные люди определяют в какой форме на странице произошло изменение?
Его там реально 4 строчки и нет смысла его тянуть.
Но что то я туплю.
У меня был некий обработчик события change у формы
$(document).on('change', this.config.filterWrapper, function () {
const filterData = $(this).serializeArray();
}где this.config.filterWrapper это идентификатор формы.Работает как нужно — события изменения любого элемента этой формы запускают этот код и что важно — this всегда ссылается на форму. Что позволяет следующей строкой получить в переменную все значения всех элементов формы, неважно какой именно был изменен.
Начинаю разбираться с событиями в javascript.
Опираюсь на это learn.javascript.ru/introduction-browser-events
и там описывается три способа создать реакцию на событие.
Есть три способа назначения обработчиков событий:Ну работать с инлайновым js и вписывать его в html не солидно, путаюсь понять работу addEventListener.
Атрибут HTML: onclick="...".
DOM-свойство: elem.onclick = function.
Специальные методы: elem.addEventListener(event, handler[, phase]) для добавления, removeEventListener для удаления.
Пишу вот такое
document.addEventListener('change', function (event) {
console.log(event.target);
})смущает тот факт, что отслеживаются все события change возникающие в документе (подозреваю что jquery работает под капотом так же просто это скрыто от нас). Но проблема на лицо — как отслеживать события только внутри определенной формы? На странице может быть их много. Приходит в голову мысль, что раз у нас есть объект event то через него можно проверять кто инициатор, кто target и уже по условию проверять наш ли это пациент. Но ожидаемо, что targеt это не есть форма, это dom элемент, на котором произошло событие — input, select и так далее. А значит мне по прежнему ничего не известно о том, из какой конкретно формы этот элемент. Да можно пытаться у каждого элемента проверять кто его предок, проверять у предка id и смотреть не наша ли это форма, но это плохо и плюс формы на всегда содержит только тег form и сразу inputы, там может быть сложная разметка div, span что угодно.Так как же правильно обработать событие change чтобы в идеале event.target указывавал на форму в которой произошло измеенние, а не на сам элемент или хотя бы, а как грамотные люди определяют в какой форме на странице произошло изменение?
Комментарии: 16
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
А что нет никакого метода для получения данных из формы?
давал мне массив объектов в виде name — value
а javascript не подскажите, имеет метод получения сразу всех заполненных полей формы?
Я вот для себя открыл, что оказывается существует некая коллекция форм
learn.javascript.ru/form-elements
которая содержит в себе все формы, все элементы всех форм и так далее
Могу делать цикл, сам создавать сам объекты и наполнить ими какой-то массив. Но тогда нужно еще и проверять какой элемент выбран (например если есть input type radio), ну тоесть я то нагорожу 30 строчек кода). Но может я просто не нашел удобного метода в языке js для работы с данными с формы?
FormData в помощь.
Может даже лучше тут.
Очень удобным для меня открытием оказались коллекции данных js — form
learn.javascript.ru/form-elements
сделал пока некий метод на них, но не уверен что смог учесть все нюансы. В форме могут содержаться элементы разных типов. Так например у инпутов нужно получать value, у textarea получать innerHtml, checkbox нужно проверять на наличие атрибута checked и так далее и это чтобы получить то, что мне давала даже не одна строка, а одно слово в jquery — serializeArray()
Заменить serializeArray одной строкой не получится. Вот люди предлагают свой вариант замены.
спасибо за подсказки.
А у меня другое. Я наверное запутал всех, акцентируя внимание на слове — форма.
Это некий фильтр и в момент изменения любого его поля нужно собрать все текущие данные в виде массива объектов. Теоретически это может быть и вовсе не форма, а какие-то дивы. Ведь форма никогда и не отправляется по сути. Отслеживается событие change, все данные (выбранные чекбоксы например) собираются и далее уже пошла логика работы с этими данными. Форма здесь скорее дань традициям.
Если тебе нужно отслеживать изменения внутри какой-то конкретной формы, то просто проверяешь ее наличие среди родителей через closest.
Данные из формы удобнее всего собирать через FormData, как уже выше сказали. Иногда может потребоваться дополнительная обработка всяких чекбоксов, потому что по умолчанию неотмеченные чекбоксы вообще не собираются, например.
К слову, FormData — итерируемый объект, поэтому ты можешь легко по нему пройтись через цикл и поменять то, что тебе нужно:
fetch лично мне не зашел, слишком много телодвижений требуется для обычных ajax-запросов. Чтобы принять json на сервере, нужно лезть в php://input и оттуда его доставать, что может быть не всегда удобно по разным причинам. Тут либо написать свой простенький асинхронный метод-обертку для запросов, который будет построен на старом XMLHttpRequest, либо посылать данные в multipart/form-data, тогда проблем не будет.
Помимо этого, fetch до сих пор не умеет отслеживать прогресс загрузки, поэтому если нужна такая фича, можно смело от него отказываться.
но для меня проблемой стало то, что таргет как ему и положено всегда указывает на инициатора события, тоесть на input например, если мы изменили текст в нем. Но как определить, что этот инпут именно из той формы, за которой мы хотим следить?
К примеру форма имеет атрибут id = «filter», но на странице есть еще 20 форм, формы заказа обратного звонка, калькулятора какого-то, еще что то.
если наш листенер повешен на весь объект документ, то он будет следить за всеми элементами всех форм и единственный способ решить задачу, который я вижу, это всем input задавать определенный класс и проверять на его наличие.
Пока сделал так
по крайней мере под мою задачу так оказалось удобнее. теперь событие возникает только если изменена конкретная форма и что важно для меня — target тоже всегда сама форма, а нее ее отдельный инпут.
Насчет FormData нужно будет присмотреться. Я использовал ее несколько раз, но когда нужно было подготовить данные для отправки ajax-ом (хотя это можно сделать и вручную если заранее знаешь какие в форме input и их названия), я чаще пользовался formData чтобы передать через ajax файл. Но наверное вы и Сергей правы — собирать данные из формы эта штука должна уметь.
Он поднимается вверх по DOM и ищет указанного родителя.
У тебя может быть хоть 150 одинаковых форм, но измененный инпут принадлежит только одной из них.
Поэтому ты делаешь, например, вот так
и узнаешь, что измененный инпут принадлежит форме с классом formClass.
Более того, ты можешь сразу сохранить эту форму в переменную и в дальнейшем работать с ней, если есть такая необходимость.
Верно, он будет следить за всеми элементами всех форм, в этом и есть его плюс, который называется делегирование.
Например, если у тебя на странице появятся еще 2 формы с таким же классом, то они автоматически подхватятся и в них тоже будут отслеживаться изменения.
И нет, не нужно задавать всем инпутам определенный класс.
Твоя задача
решается вот так
Это будет точно так же срабатывать, если изменения происходят только в рамках конкретной формы.
Твоя форма может быть присвоена переменной, как я уже показал выше, чтобы ты мог с ней работать и собирать из нее данные через FormData, например.
К слову, getElementById('formtest') уже практически не используется в новом коде, поэтому рекомендую заменять его на querySelector('#formtest').
matches
classList
closest
Просто это очень похоже на методы jquery а вот у ванильного js я нигде не находил их описания.
максимум
learn.javascript.ru/dom-navigation
но там эти методы не перечислены.
Практически всю нужную тебе инфу можно смотреть в рамках этого сайта. Просто пишешь прямо там в поиске нужный метод или фразу, а потом смотришь результаты.
Я когда начинаю что то разрабатывать совсем с нуля, иду от простого к сложного, сначала делаю наброски, пишу так как легче мне и проверяю саму идею. Если уже заработало и идея жизнеспособна, начинаю как-то код улучшать. Поэтому наброски как правило (если код использует js ) делаю на jquery.
А на днях посмотрел, ну реально же всего 4 места где используется jquery (а тут еще месяцок назад на этом сайте под одним постом была долгая дискуссия, мол что js сейчас сам по себе идеален для работы c DOM) и стало интересно смогу или нет избавиться от него, просто для прокачки навыков скорее всего.