Как сделать кнопку javascript
Как сделать кнопку javascript
Как активировать или отключить кнопку с помощью чистого JavaScript и jQuery
В этой статье мы обсудим способы включения и отключения кнопки. Сначала мы рассмотрим, как это делается с помощью простого JavaScript, а затем разберемся, как данный процесс выглядит в случае использования jQuery.
JavaScript – один из самых популярных языков программирования, применяемых в веб-разработке. Он используется на большинстве сайтов, и все современные браузеры поддерживают его по умолчанию. В этом руководстве мы рассмотрим полезные приемы, которые помогут вам освоить разработку на JavaScript.
К примеру, при создании сайта на основе JavaScript очень часто требуется включать или отключать кнопки в зависимости от каких-то событий. Как правило, подобная необходимость возникает при разработке форм и анкет: кнопка отправки данных должна оставаться неактивной, пока пользователь не заполнит все обязательные поля. После того, как необходимая информация будет введена, кнопка должна стать активной, чтобы пользователь мог нажать на нее и отправить данные на сервер.
В HTML для кнопок предусмотрено собственное состояние, и таким образом, вы можете активировать или отключать кнопки по желанию. К примеру, во время загрузки формы на странице можно деактивировать кнопку, а затем включить ее с помощью JavaScript.
Сейчас на конкретных примерах мы рассмотрим, как можно включать и отключать кнопки с помощью JavaScript.
Включение и отключение кнопки на чистом JavaScript
В этом разделе мы разберем пример кода на чистом JavaScript, который активирует и отключает кнопку. Посмотрите на приведенный ниже фрагмент кода:
Вот так и выглядит активация и отключение кнопки на чистом JavaScript. В следующем разделе мы рассмотрим, как включать и отключать кнопки при работе с библиотекой jQuery.
Активация и отключение кнопок на jQuery
Теперь разберемся, как реализовать включение и деактивацию кнопок при помощи библиотеки jQuery. Для этого обратимся к примеру кода из предыдущего раздела. Далее показано как выглядит код при использовании jQuery:
Метод attr используется в jQuery для установления и получения значений определенных атрибутов элемента. Если передать методу один аргумент, он вернет значение атрибута объекта. При использовании двух аргументов метод установит новое значение атрибута. В нашем случае метод используется для задания значения disabled атрибуту кнопки. Весь остальной код остается без изменений.
Заключение
В этом руководстве на двух конкретных примерах мы рассмотрели различные способы активации и отключения кнопки – с помощью чистого JavaScript, и с использованием библиотеки jQuery.
Пожалуйста, опубликуйте ваши мнения по текущей теме материала. Мы очень благодарим вас за ваши комментарии, подписки, дизлайки, отклики, лайки!
Пожалуйста, оставляйте свои комментарии по текущей теме статьи. Мы крайне благодарны вам за ваши комментарии, лайки, дизлайки, отклики, подписки!
Наталья Кайда автор-переводчик статьи « How to Enable or Disable a Button With JavaScript: jQuery vs. Vanilla »
Нажатие на кнопку в JavaScript (событие и функции)
Привет всем любителя программирования. Это довольно простой урок по такому событию в JavaScript, как нажатие на кнопку. не смотря на то, что это базовые вещи в JS, реализовать нажатие на кнопку можно разными способами. Давайте предположим, что у нас на странице есть некая кнопка.
Она пока никак не реагирует потому, что мы не повесили на нее никакого события. И давайте рассмотрим первый вариант.
Функция по нажатию кнопки в JavaScript
Событие по клику на кнопку мы создали, но можно сделать то же самое, только напишем функцию, с именем.
А к кнопке добавим эту функцию:
Вывод на страницу по клику на кнопку в JS
Соответственно по нажатию на кнопку в JavaScript можно делать не только всплывающий alert, но и все, что угодно, передавать данные на сервер, изменять элементы на странице, удалять, копировать и много чего еще. Давайте рассмотрим еще один пример. напишем небольшую функцию, которая будет срабатывать по клику и выводить на страницу случайное число. Для этого под кнопкой добавим элемент DIV с классом sum, в котором будем выводить результат работы JavaScript функции.
function randomSum(min, max)
Для кнопки добавим эту функцию по нажатию:
По нажатию на кнопку под ней будет выведено четырехзначное число от 1000 до 9999 в случайном порядке. Это мы указали в специальных параметрах min и max.
Нажатие правой кнопкой мыши в JS
Событие клика правой кнопкой мыши в JavaScript отличается от левой и по умолчанию вызывает стандартное контекстное меню браузера. Но мы его можем изменить. Во-первых убрать, а во-вторых задать свое действие.
Запрещаем вывод контекстного меню при клике правой кнопкой мыши:
Это простейший вызов функции по клику в JavaScript и усваивается без особых трудностей. В дальнейшем рекомендую изучать более сложные функции, которые делают различные операции. Например считают сумму, как в калькуляторе расчета стоимости. Надеюсь этот урок оказался для вас полезным. Если остались вопросы, вы всегда можете задать их в комментариях.
Читайте также:
Как всегда интересно и доступно. Намедни, писал калькулятор расчёта цены металлической решётки на JS и пытался вызвать срабатывание двух фуекций одновременно по нажатию кнопки. Запускались два массива радиокнопок с разными именами и дальше использовались для расчётов. Не получилось и даже пишут, что это не возможно.
Интересует ваше мнение вызова нескольких функций по нажатию только одной кнопки.
Проблем с запуском 2-х функций в JS возникать не должно. Просто эти функции нужно написать отдельно. Возможно у вас какой-то конфликт в коде.
Имеется в виду есть 2 групы или более радио кнопок с возможностью выбора только одной кнопки в каждой группе по параметру value. Хотелось бы написать один код, в котором поставив чекбоксы в радио кнопках использовать их значениня value в этом коде дальше по нажатию кнопки РАССЧИТАТЬ. Каждая группа кнопок перебирается в цикле и определяется значение value одной и второй группы. На самом деле, записав оба цикла последовательно в коде не удаётся далье воспользоваться полученными значениями велью. Если радио кнопки не зависимые, тогда всё в порядке, а если с одним именем не получается.
Не совсем понял. Можно попробовать использовать this и написать один цикл.
Спасибо. Буду пробовать.
Всплывает модальное окно подписки и зависает. Дальше не реагирует.
Доброго времени суток! а как быть в случае когда надо на одной странице несколько раз выполнить одинаковый код обновление div-а с помощью Ajax?
Пример: есть страница строки/столбцы. В одном из столбцов (для каждой строки) есть номер и ттн. По нажатию на кнопку происходит отправка данных. php возвращает некий ответ. Этот ответ отображается в div под кнопкой отправки. Но такая конструкция срабатывает только один раз для первого элемента
$.ajax( <
type: «POST»,
url: url,
data: form.serialize(),
success: function(html) <
$(»).html(html);>>);
return false;
>);
Вам скорее всего нужен формат Json. Об этот я писал здесь.
Данные отправляются через эту конструкцию нормально. php тоже отрабатывает возвращая нужную строку. После в строке success результат от php присваивается некому div-у на странице. Но если это код повторить несколько раз на одной странице то все, которые ниже уже не работают (я так понимаю, что это из за уникальности id-шников)
Соответственно id должны быть разными.
Кнопка «Наверх» на чистом JavaScript
Сложность
Описание
Создаем кнопку на нативном JavaScript, без jQuery. Создаем улучшенную кнопку, действующую как вверх, так и вниз.
HTML часть
Вначале разметка.
Добавляем в HTML тег a, задаем ему класс и заглавие(title). Содержимое тега будет спецсимвол ↑ он как раз и будет отображаться в виде стрелки. Важно заметить, что здесь у тега a нет атрибута href, т.к. он нам здесь не нужен.
CSS часть
Пишем стили.
В будущем вы сможете изменить внешний вид кнопки, сейчас сделаем «базовую» модель. Записываем в CSS представленный код, он стандартный, отмечу только класс back_to_top-show, мы будем его добавлять/убирать у нашей кнопке средствами javascript. В начале(после загрузки страницы) у кнопки стоит класс back_to_top и соответственно display:none; т.е. кнопка не отображается, когда мы добавим кнопке класс back_to_top-show то display станет block и кнопка появится на экране.
JavaScript часть
Теперь JavaScript.
Мы создадим два обработчика:
Вначале отслеживаем прокрутку документа.
Мы задаем два условия(if) и в зависимости от срабатывания одного из них, мы нашей кнопке добавляем/удаляем класс back_to_top-show, а следовательно делаем ее «видимой»/»невидимой». Когда мы прокручиваем документ на «один экран», кнопка появляется, и наоборот.
Теперь отслеживаем клик по кнопке.
Логично предположить, что мы можем совершить клик по кнопке только тогда, когда обработчик scrollотработал и показал ее нам. Задача здесь в добавлении анимации(плавный скролл наверх). Я решил эту задачу с помощью метода setTimeout и рекурсии(т.е. функция вызывает сама себя). За каждый такой вызов функции, мы будем прокручивать страницу вверх, в коде значение -80 это и есть параметр прокрутки документа за один «шаг»(вызов функции). Чтобы понять как это действует, нужно понимать как действует рекурсия и метод setTimeout, еще можно попробовать изменить значение -80 и второй параметр в setTimeout т.е в данном случае он равен нулю, в зависимости от этих параметров мы можем делать прокрутку быстрее/медленнее.
Готово!
Теперь соберем все воедино, переведем наш код в «строгий режим» путем добавления ‘use strict’; и обернем его в анонимную функцию, это нужно чтобы наши переменные не попали в глобальную область видимости( т.е. чтобы не было конфликта с другими нашими скриптами).
javascript как создать кнопку
Начало
Библиотека ui.buttons позволяет создавать кнопки не только разметкой, но и с помощью JavaScript API.
Подключение на странице
Привет, кнопка!
Метод getContainer возвращает ссылку на DOM-элемент кнопки. Используйте его для гибкого построения интерфейсов.
Размеры
Допустимые значения BX.UI.Button.Size :
Цвета
Допустимые значения BX.UI.Button.Color: :
Состояния
Кнопка может иметь состояние. Например, быть активной или заблокированной. Опция state и перечисление BX.UI.Button.State управляют этой возможностью.
Допустимые значения BX.UI.Button.State :
Тег кнопки
Допустимые значения BX.UI.Button.Tag :
Иконка
Допустимые значения BX.UI.Button.Icon :
HTML-атрибуты
Опция props позволяет установить произвольные HTML-атрибуты кнопки. Например, href для кнопки-ссылки или data-атрибут.
Также можно установить свой CSS класс-модификатор.
Обработка событий
Круглая кнопка
Заглавные буквы
По умолчанию текст кнопки приводится к верхнему регистру. Опция noCaps=true позволяет отменить это поведение.
Dropdown-кнопка
Опция dropdown=true добавляет иконку в виде стрелки справа от названия кнопки. Такой внешний вид предполагает показ меню после нажатия.
Двойная кнопка
Допустимые значения BX.UI.SplitButton.State :
Параметры можно указывать как для целой кнопки, так и для отдельных ее частей. В опциях mainButton и menuButton задаются идивидуальные настройки основной и дополнительной кнопки.
Стандартные кнопки
Для типовых кнопок «Сохранить», «Применить», «Отмена» и др. существуют вспомогательные классы. Эти классы предустанавливают цвет и текст кнопки.
Вспомогательные классы обычной кнопки (наследники BX.UI.Button ):
Вспомогательные классы двойной кнопки (наследники BX.UI.SplitButton ):
Любое предустановленное значение можно переопределить.
Пользовательские комментарии
Мы будем рады, если разработчики добавят свои комментарии по практическому использованию методов системы.
Для этого нужно всего лишь авторизоваться на сайте
Но помните, что Пользовательские комментарии, несмотря на модерацию, не являются официальной документацией. Ответственность за их использование несет сам пользователь.
Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.
Рассмотрим пример, как нужно обрабатывать нажатия кнопки в форме с помощью JavaScript.
Создадим простейшую форму.
На данный момент кнопка ничего не делает. Получим доступ к кнопке.
Далее следует создать код, который будет выполняться при нажатии кнопки.
Осталось подключить созданную функцию к переменной
При нажатии на кнопку появляется сообщение.
Идём дальше. Мы хотим получить текст, введённый пользователем в текстовом поле. Когда пользователь вводит текст, то у элемента input type=»text» в свойстве value появляется значение, которое и содержит текст пользователя. Таким образом, нам нужно сначала получить доступ к элементу страницы по идентификатору, а затем его свойство.
Теперь выводится сообщение, в котором содержится имя кота. Не помешает небольшая проверка, что текст был введён.
Третий шаг — выводить имена котов на самой странице. Мы уже приготовили список ul, к которому тоже можно получить доступ и добавлять дочерние элементы. Для получения доступа используем знакомый метод getElementById(). Для динамического создания нового элемента используется метод document.createElement(). После создания мы можем настроить элемент, например, прописав текст. Для текста элемента списка будем использовать переменную, которая содержит имя кота. Создав новый элемент, его необходимо добавить к родительскому элементу через appendChild().
Новые способы
В последнее время стали использовать другой код. Например, используют const вместо var, вместо onclick — addEventListener.
Также вместо getElementById() можно использовать querySelector(). А в addEventListener использовать другой формат вызова функции.
Атрибут onclick
Также можно использовать готовый атрибут у кнопки onclick.
Я почитал комментарии к моему последнему посту и.
Так как я всегда прислушиваюсь к своим читателям(НЕТ)
Я решил вставлять код
В сторону плоские шутки,перейдём к теме поста.
Опять-же пишем стандартную структуру html файла.
Собственное контекстное меню с использованием JavaScript
Что есть контекстное меню?
Если верить Википедии, контекстное меню — меню, появляющееся при взаимодействии пользователя с графическим интерфейсом (при нажатии правой кнопки мыши). Контекстное меню содержит ограниченный набор возможных действий, который обычно связаны с выбранным объектом.
На вашем компьютере клик правой кнопкой мыши на рабочем столе вызовет контекстное меню операционной системы. Отсюда вы, вероятно, можете создать новую папку, получить какую-то информацию и сделать что-нибудь еще. Контекстное меню в браузере позволяет, например, получить информацию о странице, посмотреть ее исходники, сохранить изображение, открыть ссылку в новой вкладке, поработать с буфером обмена и всякое такое. Причем набор доступных действий зависит от того, куда именно вы кликнули, то есть от контекста. Это стандартное поведение, закладываемое разработчиками браузера [И расширений к нему].
Веб-приложения постепенно начинают заменять стандартные контекстные меню своими собственными. Отличными примерами являются все те же Gmail и Dropbox. Вопрос лишь в том, как сделать свое контекстное меню? В браузере при клике правой кнопкой мыши срабатывает событие contextmenu. Нам придется отменить поведение по умолчанию и сделать так, чтобы вместо стандартного меню выводилось наше собственное. Это не так уж сложно, но разбираться будем пошагово, так что выйдет довольно объемно. Для начала создадим базовую структуру приложения, чтоб разрабатываемый пример не был совсем уж оторван от реальности.
Список задач
Представим, что мы создаем приложение, позволяющее вести список задач. Я понимаю, вы уже наверняка неимоверно устали от всех этих списков задач, но пусть будет. Страница приложения содержит список незавершенных задач. Для каждой задачи доступен типичный набор действий CRUD: получить информацию о задаче, добавить новую, редактировать, удалить.
Пример результата есть на CodePen. Можете заглянуть туда сразу, если лень читать или хотите убедиться, что действительно заинтересованы в дальнейшем чтении. Ну а пока приступим к пошаговой разработке задуманного. Я буду использовать некоторые современные фишки CSS и создам простейший список задач на data-атрибутах. Также воспользуюсь сбросом стилей от Эрика Мейера и сброшу свойство box-sizing для всех элементов в border-box:
Я не буду использовать префиксы в CSS, но в демо на CodePen включен автопрефиксер.
Создание базовой структуры
Откроем наш HTML-документ, накидаем шапку, контентную часть с некоторым списком задач и подвал. Я также подтяну Font Awesome и шрифт Roboto, чтобы сделать оформление немного лучше. Каждая задача должна содержать атрибут data-id, который в реальности брался бы из БД. Также каждая задача будет содержать список действий. Вот важные части разметки:
Если вы используете CodePen, можете в настройках включить автопрефиксер и подключение CSS-сброса. В противном случае придется делать все руками, если еще не автоматизировали этот процесс. Не забывайте, что наша цель — создание контекстного меню, так что обработка действий не будет реализована. А теперь давайте добавим еще немного CSS:
Полный набор стилей (да и всего остального) представлен на CodePen. А здесь будут самые важные части кода, разметки и оформления. Но давайте уже наконец приблизимся к нашему контекстному меню.
Набросаем наше контекстное меню — разметка
Приводим наше меню в порядок — CSS
Уже была упомянута необходимость абсолютного позиционирования разрабатываемого меню. Кроме того, установим свойство z-index в 10. Не забывайте, что в вашем приложении может потребоваться другое значение. Это не все возможные стили, в демке наведены прочие красивости, но они уже зависят от ваших потребностей и не являются обязательными. Прежде чем переходить к JS, сделаем меню невидимым по умолчанию и добавим дополнительный класс для его отображения.
Разворачиваем наше контекстное меню — JavaScript
Начнем с того, что посмотрим, как зарегистрировать событие contextmenu. Откроем самовыполняющуюся функцию и отловим событие на всем документе. Также будем логировать событие в консоль, чтобы получить какую-то информацию:
Если заглянуть в консоль, можно увидеть, что уникальное событие срабатывает при каждом нажатии на элемент из списка задач. Теперь помимо отмены поведения по умолчанию реализуем отображение контекстного меню, добавляя к нему вспомогательный класс.
Но для начала давайте добавим к меню ID, чтобы его проще было получать посредством JS. Также добавим переменную состояния меню menuState и и переменную с активным классом. Получились три переменных:
Едем дальше. Пересмотрим функцию contextMenuListener и добавим toggleMenuOn, отображающую меню:
На данный момент правой кнопкой мыши уже можно вызвать наше контекстное меню. Но нельзя сказать, что оно работает правильно. Во-первых, оно находится совсем не там, где хотелось бы. Для устранения проблемы понадобится немного математики. Во-вторых, закрыть это меню пока невозможно. С учетом того, как работают обычные контекстные меню, хотелось бы, чтоб наша его реализация закрывалась при клике не меню и при нажатии Escape. Помимо этого при правом клике вне нашего меню оно должно закрыться, а вместо него требуется открытие меню по умолчанию. Давайте попробуем все это решить.
Рефакторинг нашего кода
Вернемся и отредактируем contextListener:
Имея вспомогательную функцию, делающую за нас часть грязной работы, и отлавливая событие contextmenu на всем документе, мы можем теперь закрывать меню при клике вне его. Для этого добавим функцию toggleMenuOff и отредактируем contextListener:
Теперь нажмите правой кнопкой по элементу списка. А после — где-нибудь в другом месте документа. Вуаля! Наше меню закрылось и открылось стандартное. Затем сделаем нечто похожее самое для события click, чтобы не от одной правой кнопки оно закрывалось:
Этот кусок кода несколько отличается от предыдущего, потому что Firefox. После того, как правая кнопка мыши отжата, в Firefox срабатывает событие click, так что здесь нам приходится дополнительно убеждаться, что произошел действительно клик левой кнопкой. Теперь меню не моргает при правом клике. Давайте добавим похожий обработчик и на нажатие клавиши ESC:
Мы получили меню, которое открывается и закрывается как задумано, взаимодействующее с пользователем естественным образом. Давайте наконец отпозиционируем меню и попробуем обрабатывать события внутри него.
Позиционирование нашего контекстного меню
С учетом текущих HTML и CSS, наше меню отображается в нижней части экрана. Но нам-то хотелось бы, чтоб оно появлялось там, где произошел клик. Давайте исправим сие досадное упущение. Во-первых, добавим еще одну вспомогательную функцию, получающую точные координаты клика. Назовем ее getPosition и попробуем заставить обрабатывать разные причуды браузеров:
Наш первый шаг в позиционировании меню — подготовка трех переменных. Добавим их в соответствующий блок кода:
Создадим функцию positionMenu, принимающую единственный аргумент — событие. Пока что пусть она выводит координаты меню в консоль:
Отредактируем contextListener, чтобы начать процесс позиционирования:
Снова повтыкайте в контекстное меню и загляните в консоль. Убедитесь, что позиция действительно доступна и логируется. Мы можем использовать встроенные стили для задания свойств top и left посредством JS. Вот и новая версия positionMenu:
Как вы помните, по умолчанию наше меню скрыто, так что нельзя просто взять и посчитать его размеры. В нашем случае меню статическое, но при реальном применении его содержимое может меняться в зависимости от контекста, так что рассчитывать ширину и высоту лучше в момент открытия. Получим нужные величины внутри функции positionMenu:
Введем еще две переменных, но на этот раз для размеров окна:
Посчитаем их значения похожим образом:
В конечном счете давайте предположим, что хотим показывать меню не ближе, чем в 4 пикселях от края окна. Можно сравнить значения, как я говорил выше, и скорректировать позицию как-то так:
Сейчас наше меню ведет себя совсем хорошо. Осталось что-то сделать с ресайзом окна. Я уже говорил, как поступает Dropbox, но вместо этого мы будем закрывать контекстное меню. [Такое поведение куда ближе к стандартному] Добавим в функцию init следующую строку:
И напишем саму функцию:
Цепляем события к пунктам контекстного меню
Если ваше приложение сложнее данного примера, и у вас планируется динамическое содержимое контекстного меню, придется подробнее вникнуть в происходящее далее, чтобы самому додумать недостающие детали. В нашем приложении все проще, и есть всего одно меню с постоянным набором действий. Таким образом, можно быстро проверить, какой именно элемент был выбран, и обработать этот выбор. В нашем примере просто сохраним выбранный элемент в переменную и запишем в консоль его data-id и выбранное действие. Для этого отредактируем разметку меню:
Далее давайте закэшируем все нужные объекты:
Появилась переменная taskItemInContext, которой присваивается значение при правом клике по элементу списка. Она нам потребуется для логирования ID элементов. Также появились новые имена классов. Теперь пройдемся по функциональности.
Функция инициализации остается такой же. Первое изменение затрагивает contextListener, ведь мы хотим сохранять в taskItemInContext элемент, на который кликнул пользователь, а функция clickInsideElement как раз его и возвращает:
Мы сбрасываем ее в null, если правый клик произошел не по элементу списка. Ну и возьмемся за clickListener. Как я упоминал ранее, для простоты мы просто будем выводить информацию в консоль. Сейчас при отлавливании события click производится несколько проверок и меню закрывается. Внесем коррективы и начнем обрабатывать клик внутри контекстного меню, выполняя некоторое действие и лишь после этого закрывая меню:
Вы могли заметить, что вызывается функция menuItemListener. Ее мы определим чуть позже. Функции keyupListener, resizeListener и positionMenu оставляем без изменений. Функции toggleMenuOn и toggleMenuOff отредактируем незначительно, изменив имена переменных для лучшей читаемости кода:
Наконец реализуем menuItemListener:
На этом разработка функциональности заканчивается.
Некоторые замечания
Большой вопрос
Я выделил эту проблему в отдельный пункт, потому что это действительно важно после всего, что мы проделали. Задайтесь вопросом: действительно ли вам нужно собственное контекстное меню? Такие штуки — это круто, но прежде чем их использовать, вы должны убедиться, что это действительно полезно в вашем случае. Обычно пользователи ожидают привычного поведения приложения. Например, после правого клика по фотографии они ожидают получения возможности сохранить ее, скопировать ссылку и т. д. Отсутствие нужных пунктов в кастомном меню может их огорчить.
Совместимость с браузерами
Заключение и демо
Если вы тщательно все обдумали и уверены, что такая функциональность нужна вашему приложению, вы можете использовать разработанное меню. Конечно, оно может потребовать каких-либо изменений, но данное руководство подробно описывает процесс разработки, так что реализовывать свои поправки должно быть не так сложно.
Кодовая база этого руководства залита на GitHub и будет поддерживаться и, возможно, обновляться в течение долгого времени. А полное рабочее демо можно потыкать на CodePen.
От переводчика
Перевод местами достаточно вольный, но не в ущерб смыслу или содержанию. Все, что не относится напрямую к оригиналу, вынесено в примечания.
С предложениями, пожеланиями и замечаниями, как обычно, в ЛС.
Выразительный JavaScript: Обработка событий
Содержание
Вы властны над своим разумом, но не над внешними событиями. Когда вы поймёте это, вы обретёте силу.
Марк Аврелий, «Медитации».
Некоторые программы работают с вводом пользователя, мышью и клавиатурой. Время возникновения такого ввода и последовательность данных нельзя предсказать заранее. Это требует иного подхода к контролю над порядком выполнения программы, чем уже привычный нам.
Обработчики событий
Представьте интерфейс, в котором единственным способом узнать, нажали ли на кнопку клавиатуры, было бы считывание текущего состояния кнопки. Чтобы реагировать на нажатия, вам пришлось бы постоянно считывать состояния кнопок, чтобы вы могли поймать это состояние, пока кнопка не отжалась. Было бы опасно проводить другие подсчёты, отнимающие процессорное время, так как можно было бы пропустить момент нажатия.
Таким образом ввод обрабатывался на примитивных устройствах. Шагом вперёд было бы, если железо или операционка замечали бы нажатие кнопки и передавали бы его в очередь. Затем программа периодически могла бы проверять очередь на новые события и реагировать на то, что находится в очереди.
Разумеется, она должна помнить о проверке, и делать это достаточно часто, потому что наличие длительного промежутка времени между нажатием кнопки и тем, когда программа замечает и реагирует на это, ведёт к восприятию этой программы как медленно работающей. Такой подход называется опросом. Большинство программистов по возможности избегают его. Такой подход используется достаточно редко.
Вариант получше – некая промежуточная система, которая позволяет коду реагировать на события в момент их возникновения. Браузеры позволяют это делать путём регистрации функций как обработчиков заданных событий.
Функция addEventListener регистрирует свой второй аргумент как функцию, которая вызывается, когда описанное в первом аргументе событие случается.
События и узлы DOM
Каждый обработчик событий браузера зарегистрирован в контексте. Когда вы вызываете addEventListener, вы вызываете её как метод целого окна, потому что в браузере глобальная область видимости – это объект window. У каждого элемента DOM есть свой метод addEventListener, позволяющий слушать события от этого элемента.
Пример назначает обработчик на DOM-узел кнопки. Нажатия на кнопку запускают обработчик, а нажатия на другие части документа – не запускают.
Присвоение узлу атрибута onclick работает похоже. Но у узла есть только один атрибут onclick, значит таким способом вы можете зарегистрировать только один обработчик. Метод addEventListener позволяет добавлять любое количество обработчиков, так что вы не замените случайно уже назначенный ранее обработчик.
Метод removeEventListener, вызванный с такими же аргументами, как addEventListener, удаляет обработчик.
Чтобы это провернуть, мы даём функции имя (в данном случае, once), чтобы её можно было передать и в addEventListener, и в removeEventListener.
Объекты событий
В примерах мы проигнорировали тот факт, что функциям-обработчикам передаётся аргумент – объект события. В нём хранится дополнительная информация о событии. К примеру, если надо узнать, какая кнопка мыши была нажата, мы можем обратиться к свойству which этого объекта.
Хранящаяся в объекте информация – разная для каждого типа событий. Мы обсудим эти типы позже. Свойство объекта type всегда содержит строку, описывающую событие (например, «click» или «mousedown»).
Распространение (propagation)
События, зарегистрированные на узлах, имеющих дочерние узлы, получат и некоторые события, случившиеся с их детьми. Если кликнуть на кнопку внутри параграфа, обработчики событий параграфа получат событие click.
Если и у параграфа и у кнопки есть обработчики, то первым запустится более конкретный – то есть, обработчик кнопки. Событие как бы распространяется наружу, от узла, где оно случилось, до его родительского и далее до корня документа. После отработки всех обработчиков всех промежуточных узлов, очередь среагировать на событие доходит и до самого окна.
В любой момент обработчик может вызвать метод stopPropagation объекта события, чтобы «высшие» узлы не получили его. Это может быть полезным, когда у вас есть кнопка внутри другого кликабельного элемента, и вы не хотите, чтобы клики по кнопке активировали поведение внешнего элемента.
Следующий пример регистрирует обработчики «mousedown» как на кнопке, так и на окружающем параграфе. При щелчке правой кнопкой обработчик кнопки вызывает stopPropagation, который предотвращает запуск обработчика параграфа. При клике другой кнопкой запускаются оба обработчика.
У большинства объектов событий есть свойство target, ссылающееся на узел, который запустил обработку. Его можно использовать для проверки того, что вы не обрабатываете что-то, пришедшее с ненужного вам узла.
Также возможно использовать свойство target, чтобы распространить обработку конкретного типа события. К примеру, если у вас есть узел, содержащий длинный список кнопок, было бы удобнее зарегистрировать один обработчик событий для узла, и в нём выяснять, нажали ли на кнопку – вместо того, чтобы регистрировать обработчики каждой кнопки по отдельности.
Действия по умолчанию
У многих событий есть действия по умолчанию. При клике на ссылку вы перейдёте по ней. При нажатии на стрелку вниз браузер прокрутит страницу вниз. По правому клику мыши вы увидите контекстное меню. И так далее.
Для большинства типов событий обработчики событий вызываются до того, как сработает действие по умолчанию. Если обработчик не хочет, чтобы это действие происходило (часто потому, что он уже обработал его), он может вызвать метод preventDefault объекта события.
Это можно использовать для создания своих горячих клавиш или контекстного меню. Также это можно использовать для слома привычного пользователю интерфейса. К примеру, вот ссылка, по которой нельзя пройти.
Не делайте так – если у вас нет очень серьёзной причины! Пользователям вашей страницы будет очень неудобно, когда они столкнутся с неожиданными результатами своих действий. В зависимости от браузера, некоторые события перехватить нельзя. В Chrome нельзя обрабатывать горячие клавиши закрытия текущей закладки (Ctrl-W or Command-W).
События от кнопок клавиатуры
При нажатии кнопки на клавиатуре браузер запускает событие «keydown». Когда она отпускается, происходит событие «keyup».
Несмотря на название, «keydown» происходит не только тогда, когда на кнопку нажимают. Если нажать и удерживать кнопку, событие будет происходить каждый раз по приходу повторного сигнала от клавиши (key repeat). Если вам, к примеру, надо увеличивать ускорение игрового персонажа, когда нажата кнопка со стрелкой, и уменьшать его, когда она отпущена – надо быть осторожным, чтобы не увеличивать ускорение каждый раз при повторе сигнала от кнопки, иначе скорость возрастёт очень сильно.
В примере упомянуто свойство keyCode объекта события. Так вы можете узнать, какая именно кнопка нажата или отпущена. К сожалению, не всегда очевидно, как преобразовать числовые коды в нужную кнопку.
Для цифр и букв код будет кодом символа Unicode, связанного с прописным символом, изображённым на кнопке. Метод строки charCodeAt даёт нам этот код.
У других кнопок коды менее предсказуемы. Лучший способ их выяснить – экспериментальный. Зарегистрировать обработчик, который записывает коды клавиш, и нажать нужную кнопку.
Кнопки-модификаторы типа Shift, Ctrl, Alt, и Meta (Command на Mac) создают события, как и нормальные кнопки. Но при разборе комбинаций клавиш можно выяснить, были ли нажаты модификаторы, через свойства shiftKey, ctrlKey, altKey, и metaKey событий клавиатуры и мыши.
События «keydown» и «keyup» дают информацию о физическом нажатии кнопок. А если вам нужно узнать, какой текст вводит пользователь? Создавать его из нажатий кнопок – неудобно. Для этого существует событие «keypress», происходящее сразу после «keydown» (и повторяющееся вместе с «keydown», если клавишу продолжают удерживать), но только для тех кнопок, которые выдают символы. Свойство объекта события charCode содержит код, который можно интерпретировать как код Unicode. Мы можем использовать функцию String.fromCharCode для превращения кода в строку из одного символа.
Источником события нажатия клавиши узел становится в зависимости от того, где находился фокус ввода во время нажатия. Обычные узлы не могут получить фокус ввода (если только вы не задали им атрибут tabindex), а такие, как ссылки, кнопки и поля форм – могут. Мы вернёся к полям ввода в главе 18. Когда ни у чего нет фокуса, в качестве целевого узла событий работает «document.body».
Щелчки мышью
Нажатие кнопки мыши тоже запускает несколько событий. События «mousedown» и «mouseup» похожи на «keydown» и «keyup», и запускаются, когда кнопка нажата и когда отпущена. События происходят у тех узлов DOM, над которыми находился курсор мыши.
После события «mouseup» на узле, на который пришлись и нажатие, и отпускание кнопки, запускается событие “click”. Например, если я нажал кнопку над одним параграфом, потом передвинул мышь на другой параграф и отпустил кнопку, событие “click” случится у элемента, который содержал в себе оба эти параграфа.
Если два щелчка происходят достаточно быстро друг за другом, запускается событие «dblclick» (double-click), сразу после второго запуска “click”.
Для получения точных координат места, где произошло событие мыши, обратитесь к свойствам pageX и pageY – они содержат координаты в пикселях относительно верхнего левого угла документа.
В примере создана примитивная программа для рисования. Каждый раз по клику на документе он добавляет точку под вашим курсором. В главе 19 будет представлена менее примитивная программа для рисования.
Свойства clientX и clientY похожи на pageX и pageY, но дают координаты относительно части документа, которая видна сейчас (если документ был прокручен). Это удобно при сравнении координат мыши с координатами, которые возвращает getBoundingClientRect – его возврат тоже связан с относительными координатами видимой части документа.
Движение мыши
Каждый раз при сдвиге курсора мыши запускается событие «mousemove». Его можно использовать для отслеживания позиции мыши. Обычно это нужно при создании некоей функциональности, связанной с перетаскиванием объектов мышью.
К примеру, следующая программа отображает полоску и устанавливает обработку событий так, что движение влево и вправо уменьшает или увеличивает её ширину.
Обратите внимание – обработчик «mousemove» зарегистрирован у всего окна. Даже если мышь уходит за пределы полоски, нам надо обновлять её размер и прекращать это, когда кнопку отпускают.
Когда курсор попадает на узел и уходит с него, происходят события «mouseover» или «mouseout». Их можно использовать, кроме прочего, для создания эффектов проведения мыши, показывая или меняя стиль чего-либо, когда курсор находится над этим элементом.
К сожалению, создание такого эффекта не ограничивается запуском его при событии «mouseover» и завершением при событии «mouseout». При движении мыши от узла к его дочерним узлам на родительском узле происходит событие «mouseout», хотя мышь, вообще говоря, его и не покидала. Что ещё хуже, эти события распространяются как и все другие, поэтому вы всё равно получаете «mouseout» при уходе курсора с одного их дочерних узлов того узла, где вы зарегистрировали обработчик.
Для обхода проблемы можно использовать свойство relatedTarget объекта событий. Он сообщает, на каком узле была до этого мышь при возникновении события «mouseover», и на какой элемент она переходит при событии «mouseout». Нам надо менять эффект, только когда relatedTarget находится вне нашего целевого узла. Только в этом случае событие на самом деле представляет собой переход на наш узел (или уход с узла).
Функция isInside перебирает всех предков узла, пока не доходит до верха документа (и тогда узел равен null), или же не находит заданного ей родителя.
Должен добавить, что такой эффект достижим гораздо проще через псевдоселектор CSS под названием :hover, как показано ниже. Но когда при наведении вам надо делать что-то более сложное, чем изменение стиля узла, придётся использовать трюк с событиями «mouseover» и «mouseout».
События прокрутки
Когда элемент прокручивается, запускается событие «scroll». Это используется во многих случаях, например чтобы узнать, на что сейчас пользователь смотрит (чтобы останавливать анимацию, не попавшую на экран, или отправлять секретные шпионские донесения в ваш злодейский штаб), или визуально демонстрировать прогресс (подсвечивая часть содержания или показывая номер страницы).
В примере в правом верхнем углу документа создаётся индикатор процесса, который заполняется по мере прокрутки элемента вниз.
Позиция элемента fixed означает почти то же, что absolute, но ещё и предотвращает прокручивание элемента вместе с остальным документом. Смысл в том, чтобы оставить наш индикатор в углу. Внутри него находится другой элемент, который изменяет размер, отражая текущий прогресс. Мы используем проценты вместо px для задания ширины, чтобы размер элемента изменялся относительно размера всего индикатора.
Глобальная переменная innerHeight даёт высоту окна, которую надо вычесть из полной высоты прокручиваемого элемента – при достижении конца элемента прокрутка заканчивается. (Также в дополнение к innerHeight есть переменная innerWidth). Поделив текущую позицию прокрутки pageYOffset на максимальную позицию прокрутки, и умножив на 100, мы получили процент для индикатора.
Вызов preventDefault не предотвращает прокрутку. Обработчик события вызывается уже после того, как прокрутка случилась.
События, связанные с фокусом
При получении элементом фокуса браузер запускает событие “focus”. Когда он теряет фокус, запускается событие “blur”.
В отличие от предыдущих событий, эти два не распространяются. Обработчик родительского узла не уведомляется о получении или утрате фокуса дочерним элементом.
Следующий пример демонстрирует текст подсказки для того текстового поля, у которого в данный момент фокус.
Объект window получает события focus и blur, когда пользователь выделяет или убирает фокус с закладки браузера или окна браузера, в котором показан документ.
Событие загрузки
Иногда вам надо отменить запланированную функцию. Это можно сделать, сохранив значение, возвращаемое setTimeout, и затем вызвав с ним clearTimeout.
Функция cancelAnimationFrame работает так же, как clearTimeout – вызов её со значением, возвращённым requestAnimationFrame, отменит этот кадр (если он уже не был вызван).
Похожий набор функций, setInterval и clearInterval используется для установки таймеров, которые будут повторяться каждые X миллисекунд.
Устранение помех (debouncing)
У некоторых событий есть возможность выполняться быстро и много раз подряд (например, «mousemove» и «scroll»). При обработке таких событий надо быть осторожным и не делать ничего «тяжёлого», или ваш обработчик займёт столько времени на выполнение, что взаимодействие с документом будет медленным и прерывистым.
Если в таком обработчике надо сделать что-то нетривиальное, можно использовать setTimeout, чтобы гарантировать, что вы делаете это не слишком часто. Это обычно называют «устранением помех» в событии. К этому существует несколько слегка различающихся подходов.
В первом примере надо сделать что-то, когда пользователь печатает, но не надо делать это сразу после запуска каждого события нажатия на клавиши. Когда они быстро печатают, нам надо подождать, когда возникнет пауза. Вместо немедленного выполнения действия в обработчике, мы устанавливаем таймаут. Также мы очищаем предыдущий таймаут, если он был, так что если события близко одно от другого (ближе, чем задержка таймера), предыдущее событие будет отменено.
Если задать undefined для clearTimeout, или вызвать его с таймаутом, который уже произошёл, то ничего не произойдёт. Таким образом, не надо осторожничать при его вызове, и мы просто поступаем так для каждого события.
Можно использовать немного другой подход, если нам надо разделить ответы минимальными промежутками времени, но при этом запускать их в то время, когда происходят события, а не после. К примеру, надо реагировать на события «mousemove», показывая текущие координаты мыши, но только каждые 250 миллисекунд.
Обработчики событий позволяют обнаруживать и реагировать на события, над которыми мы не властны. Для их регистрации используется метод addEventListener.
У событий есть определяющий их тип («keydown», «focus», и так далее). Большинство событий вызываются конкретными узлами DOM, и затем распространяются на их предков, позволяя связанными с ними обработчикам обрабатывать их.
При вызове обработчика ему передаётся объект события с дополнительной информацией о событии. У объекта также есть методы, позволяющие остановить дальнейшее распространение (stopPropagation) и предотвратить обработку события браузером по умолчанию (preventDefault).
Нажатия на клавиши запускают события «keydown», «keypress» и «keyup». Нажатия на кнопки мыши запускают события «mousedown», «mouseup» и «click». Движения мыши запускают события «mousemove», и возможно «mouseenter» и «mouseout».
Прокрутку можно обнаружить через событие “scroll”, а изменения фокуса через события «focus» и «blur». Когда заканчивается загрузка документа, у объекта window запускается событие “load”.
В одно и то же время может работать один участок программы. Поэтому обработчики событий и другие запланированные скрипты будут ждать окончания работы текущих.
Упражнения
Цензура клавиатуры
В промежутке с 1928 по 2013 год турецкие законы запрещали использование букв Q, W и X в официальных документах. Это являлось частью общей инициативы подавления курдской культуры – эти буквы используются в языке курдов, но не у турков.
В качестве упражнения на тему странного использования технологий, я прошу вас запрограммировать поле для ввода текста так, чтобы эти буквы нельзя было туда вписать. Насчет копирования и вставки и других подобных возможных обходов правила не беспокойтесь.
След мыши
В ранние дни JavaScript, когда было время кричащих домашних страниц с обилием анимированных картинок, люди использовали язык очень вдохновляющими способами. Одним из них был «след мыши» — серия картинок, которые следовали за курсором при его движении по странице.
Я хочу, что бы вы в упражнении сделали такой след. Используйте
с абсолютным позиционированием, фиксированным размером и цветом фона. Создайте кучку элементов и при движении мыши показывайте их следом за курсором.
К этому можно подойти многими способами. Можно сделать очень простое или очень сложное решение, как угодно. Простое – хранить фиксированное количество элементов и проходить по ним в цикле, двигая каждый следующий на текущее место курсора, каждый раз когда случается событие «mousemove».
Закладки
Интерфейс закладок встречается часто. Он позволяет вам выбирать панель интерфейса, выбирая одну из нескольких торчащих закладок над элементом.
В упражнении вам нужно сделать простой интерфейс закладок. Напишите функцию asTabs, которая принимает узел DOM, и создаёт закладочный интерфейс, показывая дочерние элементы этого узла. Ей нужно вставлять список элементов вверху узла, по одному на каждый дочерний элемент, содержащих текст, полученный из атрибута data-tabname. Все, кроме одного из дочерних элементов, должны быть спрятаны (при помощи значения none свойства стиля display), а текущий видимый узел можно выбирать нажатием кнопки.
Когда оно заработает, расширьте функционал, чтобы у текущей активной кнопки был свой стиль.
Простой универсальный переключатель на JavaScript
При разработке сайтов нередко возникает необходимость в каком-либо переключении их состояния, обычно для этого используются псевдоссылки: скрыть или показать подсказку, поле ввода, другую часть страницы.
Можно каждый раз писать JavaScript-код и стили к нему, но со временем это приводит к разрастанию кода, с чем в определенный момент мы и столкнулись.
Однако проблему можно решить гораздо элегантнее. Рассматриваемое ниже решение отличается простотой и не требует последующего участия JavaScript-программиста, так как верстальщик сможет самостоятельно вносить нужные изменения в стили.
Принцип работы
Решение предложил наш разработчик Павел Довбуш aka dpp: в HTML-коде на переключающий элемент прописывается класс jst (JavaScript toggle), а на родительский элемент, внутри которого происходят изменения — jsw (JavaScript wrapper).
Предлагаемый скрипт отслеживает щелчок на элементы с классом jst и переключает определённый класс на оборачивающем элементе с классом jsw. По умолчанию это класс jse (JavaScript enable), но для него может быть указано иное имя в атрибуте rel. Другие классы на элементе при этом не затрагиваются.
Далее приведён код, который намеренно упрощён для демонстрации идеи, но его нетрудно дополнить или перевести на используемый фреймворк для поддержки браузера Internet Explorer версии 8 и ниже.
Обработчик события щелчка «навешивается» сразу на узел document, используя «всплытие событий» (англ. event bubbling). Этот приём позволяет отслеживать щелчки в любом месте документа, не требует его полной загрузки (document уже существует при выполнении скриптов) и начинает работу сразу после того, как выполнен JavaScript, содержащий данный код. При этом увеличивается скорость инициализации страницы за счёт избавления от серии медленных DOM-запросов для «навешивания» обработчиков событий, которая была бы неизбежна при традиционном подходе.
Атрибут rel в приведённом коде указан непосредственно через точку, однако такой вариант работает только со ссылками. Чтобы извлечь атрибут любого элемента, следует использовать метод getAttribute(). С точки зрения семантики корректней будет использовать атрибуты data-* из HTML5, рассмотрение которых выходит за пределы данной статьи.
Для стандартных вариантов переключения разумно определить и стандартные стили. В Badoo для этого используются классы вида jsh, jsb, jseh, jseb:
Класс js добавляется скриптом сразу же при выполнении, обеспечивая разделение стилевого оформления в зависимости от того, включён или выключен JavaScript:
Классы jsi и jsb включают при работающем JavaScript отображение строчного и блочного элементов соответственно, jsh — наоборот, скрывает. Классы jsei, jseb и jseh работают так же как и js-аналоги при наличии класса jse.
С помощью этих классов можно гибко управлять поведением страницы, обеспечивая при этом «изящную деградацию» (англ. graceful degradation) в случае выключенного JavaScript в браузере.
Примеры использования
На сайте Badoo необязательно указывать настоящее имя и фамилию в блоке основной информации о себе. По этой причине дизайнер решил скрыть эти поля под псевдоссылкой:
После нажатия на текст поля появляются, а сама псевдоссылка исчезает (ширина формы на изображении уменьшена).
Этого можно добиться, например, с помощью следующего HTML-кода:
Класс change на псевдоссылке задаёт оформление, jsi показывает её при включённом JavaScript, а jseh скрывает после переключения. С помощью класса jsh скрываются поля при включённом JavaScript, а jseb делает их видимыми после переключения.
Таким образом обеспечивается работа скрывающей псевдоссылки. Тем не менее при выключенной работе скриптов в браузере необязательные поля будут показаны, благодаря чему вся форма останется доступной.
Как можно заметить из примера, переключатель необязательно использовать только для работы «туда-обратно». Его можно использовать и в случае односторонних действий, таких как показ необязательных полей.
Расширенное использование
Однако не всегда достаточно простого переключения, иногда необходимо переключаться между тремя и более состояниями, или что-то менять в заполняемой форме в зависимости от выбора пользователя из предложенных вариантов (с помощью радиокнопок).
Функцию несложно доработать и для такого использования. Для этого определяется класс jss, по нажатию на элемент с которым, на родительском элементе с классом jsw будет перезаписываться класс значением из атрибута rel или value. Этот вариант уже стоит использовать аккуратно, так как любой другой класс на элементе, кроме jsw, будет затёрт.
Пример использования
Пользователи Badoo могут делать друг другу подарки, а для помощи в его выборе имеется несколько пересекающихся наборов. Например, вишенка присутствует во всех наборах, а футбольный мяч — только в дружеском и полном.
Несколько упрощённо, HTML-код выглядит так:
Каждый подарок представлен элементом
с картинкой подарка внутри, а дополнительные классы у элемента определяют принадлежность к той или иной группе.
При наличии нашей функции для управления переключением этих наборов нужны только следующие стили:
Примером использования функции с радиокнопками может послужить форма бронирования авиабилетов (к сожалению, у нас не нашлось столь же наглядного примера). В зависимости от бронирования билетов в одну сторону или туда-обратно показывается или отсутствует поле обратной даты.
С указанным кодом скрытие поля обратной даты можно обеспечить лишь одной строчкой в CSS:
Заключение
Вместо того, чтобы каждый раз изобретать велосипед, можно обобщить класс возникающих задач и найти универсальное решение, удовлетворяющее им в 80% случаев.
Рассмотренная в данной статье функция позволяет решить множество типовых задач по переключению каких-либо элементов на странице силами одного лишь верстальщика, не перегружая при этом JavaScript-код и не отвлекая ресурсы JavaScript-программистов. Объём CSS-кода в результате тоже уменьшается.
Тем не менее есть случаи, когда использование этой функции невозможно: например, автоматический фокус на показывающемся поле (хотя атрибут autofocus в новых браузерах решает эту проблему) или динамическая загрузка частей страницы посредством AJAX-запросов.
Также при большом количестве переключаемых пунктов, например, при огромном количестве разнообразных вкладок, CSS-код может оказаться неоправданно раздут — настолько, что будет иметь смысл рассматривать другие решения.
Достоинствами данной функции являются простота и универсальность. Она может работать во всех браузерах, где работает JavaScript, имеет все возможности для «изящной деградации» в случае неработающих скриптов и не требует никаких лишних элементов и «хаков», в отличие от метода с использованием скрытого и CSS3-селектора :checked.
Update: По просьбам трудящихся несколько примеров выложено здесь.
Лев Солнцев Aingis, веб-разработчик Badoo
Как сделать кнопку ссылкой
Оформлять ссылку как стандартную кнопку нежелательно: ссылка по определению указывает на ресурс, а нажатие кнопки обычно инициирует действие. Но если задача возникла, имеет смысл хотя бы решать её правильно.
Правильно
Синтаксически корректное («валидное») и кроссбраузерное решение — заключить кнопку в простейшую форму. В атрибут action формы следует поместить URL-адрес, на который должна вести «кнопка-ссылка». Для работы формы в устаревших браузерах (IE8 и ниже) следует добавить кнопке атрибут type=»submit» :
Если требуется открывать ссылку в новом окне или фрейме, можно, как и у обычных ссылок, использовать атрибут target элемента FORM :
Строка запроса
Если адрес, на который должна указывать ссылка, содержит строку запроса, следует для каждого GET-параметра добавить в форму скрытое поле с соответствующими атрибутами name и value :
Chromium/Blink и WebKit
В браузерах на основе движков Chromium / Blink (Chrome, Opera 15+, Яндекс.Браузер, Vivaldi) и WebKit (Safari) есть ошибка (баг) (1, 2): вопросительный знак, отделяющий строку запроса от основной части адреса, добавляется к адресу даже при отсутствии полей в форме. Поэтому, например, форма:
Кент Тамура ( Kent Tamura) из команды разработчиков Chromium говорит, что это соответствует текущим спецификациям HTML и URL.
Обойти это можно с помощью автоматического серверного перенаправления (редиректа) с адреса, оканчивающегося вопросительным знаком, на такой же адрес без воспросительного знака.
Ограничения по сравнению с реальной ссылкой
Неправильно
Кнопка внутри ссылки
Нередко элемент BUTTON просто помещают внутрь ссылки:
Это работает во всех современных браузерах, но согласно HTML5 это синтаксически некорректно («невалидно»): ссылка не должна содержать интерактивные элементы. Кроме того, такая ссылка не работает в Internet Explorer (IE) ниже 9-й версии.
Кнопка с JS-обработчиком щелчка
Порой используется кнопка с JavaScript-обработчиком события щелчка:
Но такая кнопка не работает при выключенном JavaScript, её невозможно открыть в новой вкладке или новом окне, и возможны проблемы с индексацией поисковиками, не исполняющими JavaScript-код.
Программа для масштабирования игр без размытия
Нестандартные расширения CSS
Описанные ниже возможности нестандартные, и использовать их не рекомендуется.
Firefox и Chromium
A.example <
-moz-appearance: button; /* Firefox */
-webkit-appearance: button; /* Chromium */
>
Internet Explorer, Edge и спецификация
В браузерах Microsoft — Internet Explorer (IE) и Edge — возможность недоступна. В спецификации CSS Basic User Interface Module Level 4 значение button свойства appearance не предусмотрено.
Есть и у этого способа подводные камни. Вот такие вот штуки ( http://s020.radikal.ru/i720/1311/34/bfe7beda17fe.jpg ) при использовании кнопок предыдущей и следующей страницы. Мешается ужасно. Как обойти непонятно.
Никита, если вы о подтверждении, запрашиваемом браузером при попытке обновить страницу (или вернуться на неё по браузерной истории), загруженную в результате отправки формы, то это имеет место только в отношении форм, отправляемых методом POST (когда данные отправляются отдельным HTTP-пакетом).
Спасибо большое за информацию. У меня есть один «дурацкий» вопрос :-). Почему при размещении 2 и более кнопок на одной странице (с разными url адресами) все они работают в одном направлении?
Наташа, скорее всего, в вашем HTML-коде есть ошибки (например, у первой из двух форм отсутствует закрывающий тег ). На всякий случай обратите внимание, что каждую кнопку-ссылку следует заключать в собственную форму, при этом формы не должны быть вложенными друг в друга.
В общем случае при любых странных проблемах полезно проверять код HTML-страницы валидатором.
Спасибо, мне следовало быть более внимательной. И за Валидатор отдельное спасибо )))
Весь интернет перерыл пока искал! спасибо мне очень помогло! и ошибок никаких нет в браузерах.
Не работает на движок OpenCart 2.0.2
Но в общем случае использование JavaScript для реализации ссылки на предыдущую страницу нежелательно, т. к. :
При необходимости URL-адрес предыдущей страницы имеет смысл вставлять в ссылку явным образом на серверной стороне, а лучше — воздержаться от дублирования встроенной функциональности браузера.
Логично. Спасибо за быстрый ответ. Буду искать другой путь
Спасибо, что просветили! Я тоже сначала сделал не правильно.
ИМХО правильный способ кнопку все таки ссылкой не делать, а просто визуализировать ссылку в виде кнопки:
С цветами и стилями только сами поиграйтесь, а то тут какой то ужас стоит 🙂
anstrem, такая кнопка будет отличаться внешне от системных кнопок, имеющих оформление, родное (native) для операционной системы.
и не мучиться с настройкой редиректа
Галина, такая кнопка не будет работать при выключенном JavaScript.
Кстати, ссылка на главную страницу не должна указывать на файл.
Спасибо за подробное описание!
Но у меня не получилось.
Вот код (это популярная в сети кнопка)
Guess Who?
Was born Agnes Gonxha Bojaxhiu.
Что не делаю, все равно код невалидный.
Андрей, скорее всего, JS-логика, привязанная к такой кнопке, зависит от конкретной, заранее определённой HTML-структуры, и с этим ничего не поделать. Для полной уверенности можно попробовать заменить обрамляющую ссылку на форму с тем же атрибутом data-path-hover — если не заработает (скорее всего), то ветер с моря дул не судьба.
Самое логичное решение
Скажите пожалуйста, а можно ли в этой форме кнопки поменять цвет кнопки и шрифта?
Добрый день.
Я только-только начал изучать html.
Сейчас пытаюсь сделать элементы выпадающего списка ссылками на якоря.Это возможно сделать, используя только html?
Спасибо.
Просто было любопытно. Понял Вас, приму к сведению.
Спасибо за ответ.
Всем привет,информация точна и подробная,спасибо автору,но у меня возник вопрос,если у меня сайт разделён фреймами,то как задать условия появления страницы,ссылка которой в кнопке,в определённом фрейме?(у меня на сайте есть верхний фрейм,боковой(там где находится кнопка) и центральный фрейм(в котором и должен появиться файл,который указан ссылкой) )
можно не указывать, она по умолчанию submit, достаточно просто
Дмитрий, именно поэтому в тексте и написано «в современных браузерах и IE8+ атрибут необязателен».
У меня сейчас небольшая запара как раз на тему как известно это не поддерживается в браузерах до ie8, можно конечно использовать input, но мне нужно именно button (кнопка с favicon), похоже придётся отказаться от поддержки старых браузеров на своём сайте.
Марат у меня вот такая кнопка но ссылка на неё не работает что делать
.button <
background-color:#0000ff;
border: none;
color: white;
padding:20px;
width: 200px;
Паша, см. секцию «Правильно» в заметке.
Такой вопрос, при наведении курсора на кнопку, внешность курсора не заменяется на всем принятый указательный палец поднятый вверх (когда наводишь на любую ссылку), есть ли способ как-то сделать это, многие даже не поймут что это ссылка наводя на кнопку)
Я не силен в программировании, но кнопку для интернет-магазина на PrestaShop все таки смог перепрограммировать.
Вот то, что было изначально:
Нужно было сделать так, чтобы при нажатии на кнопку активировался переход по адресу URL.
Сначала сделал так:
Этот вариант сработал, но мне не хотелось использовать javascript в кнопке. В итоге, благодаря Badrainbow, сделал так:
Это работает. Еще раз спасибо Badrainbow.
не хотелось использовать javascript в кнопке
Сергей, в обработчике onclick в любом случае указывается именно JavaScript-код. Отключите JavaScript — и ваша кнопка работать перестанет.
Использование псевдопротокола javascript: в этом атрибуте вообще ошибочно, он предназначен только для вызова JS-кода через атрибут href ссылок, и от его отсутствия в атрибуте onclick JS-код не перестанет быть JS-кодом.
Напротив, при использовании формы-обёртки кнопка-ссылка будет работать даже при отключённом JS.
Marat Tanalin (автор) 2018-03-04 писал:
Сергей, в обработчике onclick в любом случае указывается именно JavaScript-код. Отключите JavaScript — и ваша кнопка работать перестанет.
==========================================================================
Хочу выразить благодарность Marat Tanalin за разъяснения. Если честно, я был уверен, что обработчик onclick не использует сам по себе JavaScript.
Теперь сделал кнопку на чистом html вот таким образом:
Паттерн с пунктирными ссылками не раскрыт потому, что это кнопка, а не ссылка. Ничего не мешает оформить кнопки как пунктирные ссылки. Благо паттерн Татьянычем раскрыт ещё до появления
Здравствуйте, воспользовался вашим советом для перехода по ссылке при нажатии на кнопку. Но проблема в том что мне надо сделать так? что ссылка открывалась в новом окне, а старое окно оставалось. У меня сейчас при нажатии на кнопку «Заказать» происходит в том же окне переход на указываемую ссылку. Без JS Можно ли это реализовать при таком коде:
или надо всё это заменить на вот такой код:
помогите пожалуйсто, мне нужно что бы кнопки были расположены горизонтально, а не вертикально. Как это сделать? Вот код:
а можете написать то как это будет выглядеть, а то у меня не получается
Но если это навигационное меню, то лучше использовать обычные ссылки — их, в отличие от форм, пользователь может, например, открыть в новой вкладке или окне.
Хорошая статья. Спасибо большое автору.
Подскажите, пожалуйста, что нужно дописать в этой кнопке, чтобы при переходе ссылка открывалась в новом окне?
Я понимаю, что это делается через target=»_blank», но где и как его прописать правильно, не пойму?
Помогите, пожалуйста!
Ничего не поняла, куда этот target вставлять? Можете написать подробнее?
Сори, увидела в самой записи. Спасибо за помощь!
Добрый день.
подскажите, пожалуйста, а как сделать так, чтобы по кнопке открывался попап? Причем это всплывающее окно в виде шорткода.
Иван, можно открыть новое окно с помощью атрибута target=»_blank» или генерировать псевдоокно средствами JavaScript. Генерация псевдоокна и использование шорткодов (видимо, вы подразумеваете функциональность движка WordPress) выходит за рамки данной заметки.
Перепечатка любых материалов сайта в любом объёме запрещена
Модальные окна на javascript. 30 строк кода
В этой статье мы разберемся как создавать модальные окна с помощью javascript.
Весь код для копирования в конце статьи.
Вот что получилось в итоге ( это скрин, не кликать :)):
План работы скрипта:
Пишем JavaScript
В начале, повесим на document событие DOMContentLoaded. Это событие сработает когда страница будет загружена.
Затем запишем массив кнопок в переменную используя метод querySelector. Здесь же определим еще 2 переменные: элемент подложки и массив кнопок-крестиков.
Заметьте, modalButtons и CloseButtons мы получаем через querySelectorAll, который возвращает массив, мы сделали это потому что нужно обрабатывать клики по всем кнопка, а вот overlay мы получаем через querySelector, он возвращает один элемент.
В переменной item у нас будет храниться текущий элемент цикла. Повесим обработчик на него:
event или e — объект текущего события. В этом объекте хранятся различные методы и данные. При вызове любого события указание аргумента у функции будет ссылаться на этот объект. Зачем нам нужен этот объект? Об этом чуть ниже.
Что нам нужно сделать теперь?
Для начала нужно предусмотреть то, что кнопка, которая вызывает наше модальное окно, может быть ссылкой, кнопкой в форме или другим элементом, который стандартно выполняет какие-то интерактивные действия. Нам нужно отменить эти действия для нормальной работы нашего кода.
Для этого в объекте события есть метод, который предотвращает стандартное действие элемента.
С предотвращением вопрос решили.
У каждой кнопки есть атрибут data-modal, в нем хранится значение, которое находится у модального окна в таком же атрибуте. Наши действия:
Для того чтобы найти модальное окно, мы пишем определенный селектор, а там где нужно вставить значение, делаем разрыв строки и вставляем значение переменной, соединяя строки используя оператор сложения, в случае со строками, он выполняет их соединение ( конкатенацию).
Давайте добавим нашему окну и подложке класс active.
Напишем стили для классов .active:
Весь javascript код который получился:
Кнопки должны открывать то модальное окно, к которому привязаны. Проверяем:
Осталось написать закрытие окон по клику на крестик. С перебором элементов и созданием события вы уже знакомы.
При клике на крестик нам нужно у этого же элемента найти родителя или деда с классом .modal и удалить у него класс .active.
Готовой функции для перебора родителей элемента нет. Есть метод который позволяет получить родителя, но это ненадежно, так как разметка может поменяться и наш код сломается.
Для таких задач я не буду писать велосипед, а воспользуюсь готовой микро-библиотекой closest. Код библиотеки:
Его нужно подключить в отдельном файле или в этом же файле до нашего кода.
Библиотека создает функцию closest. Используя её мы можем искать элемент, который находится выше по дереву и класс которого совпадает с тем который мы ищем.
В нашем случае мы должны найти родителя с классом .modal и не важно является ли он прямым предком или между них есть еще какие-то элементы.
От нашего крестика мы идем вверх и проверяем родителя на класс .modal, не подошел — берем родителя его родителя и опять проверяем, так до самого конца, до window, пока не найдем интересующий нас элемент. В библиотеке jquery такая функция есть изначально, пишется она так же.
При клике на крестик, код выполнился и мы увидели в консоли родителя или деда нашего крестика, элемент с классом.modal. Теперь мы можем убрать у него активный класс, сразу же уберем его и у подложки.
Теперь вы можете создавать много много модальных окон не изменяя свой js код.
Для многих операция jquery является громоздкой библиотекой. Вы можете использовать вместо этого микро-библиотеки. Сборник библиотек — http://microjs.com/.
Еще один полезный сайт который уже в названии говорит что jquery вам может быть и не нужен. http://youmightnotneedjquery.com/
Спасибо за прочтение статьи! Если материал был полезен для тебя — поставь лайк или напиши об этом в комментариях, это займет 1 минуту, это важно для меня. Спасибо!
Если у тебя есть замечания, пожелания, предложения — можешь так же написать их в комментариях. Я рад новым мнениям и критике.
Дополнение
По просьбе читателя добавляю код для закрытия модального окна по кнопке ESC и при клике на темный фон.
Закрытие окна при клике на ESC:
Здесь мы создали событие нажатия на поднятия клавиш. В документе будут проверяться любые клавиши, нажатые пользователем. В функции мы указываем параметр, который отвечает за событие нажатия.
У событий связанных с клавишами, есть свойство keycode, которое хранит код нажатой клавиши. У ESC этот код — 27.
Нам остается проверять при каждом нажатии код клавиши с кодом ESC и если есть совпадение — удаляем класс у активного окна и фона.
Скрытие при нажатии
Ну тут вы уже сами должны уметь. Не читайте дальше и попробуйте сами подумать и написать этот код. Я сделать пару отступов, чтобы вы не подглядывали.
Ладно, подглядывай уже 🙂
Создаем событие клика на overlay, эта переменная создана в самом начале. Потом в функции удаляем у активного модального окна активный класс и делаем тоже самое у фона, на который кликнули, за это отвечает переменная this, если переводить — этот.
То есть при клике на фон, мы говорим: «Удали активный класс у окна и у фона, на который кликнули»
Как сделать кнопку javascript
Чтобы вы дальше не запутались, потому, что я сам запутался! смайлы
onclick в теге
onclick = функция
addEventListener + click
Onclick вариант №1
Повесить Onclick прямо на тег!
Onclick прямо в теге!
Onclick вариант №2
Onclick вариант №3
Синтаксис : Onclick в HTML
Пример: Onclick в HTML
Синтаксис : Onclick в JavaScript
Пример: Onclick в JavaScript
Чтобы это понять, нам понадобится кнопка. button
Соберем все вместе:
Это второй способ реализации Onclick в JavaScript
Это второй способ реализации Onclick в JavaScript
Синтаксис : В JavaScript, используя метод addEventListener()
Пример:Onclick В JavaScript, используя метод addEventListener()
Нам опять понадобится кнопка
Далее нам понадобится функция:
Соберем весь код вместе:
Это третий способ реализации Onclick в JavaScript
Это третий способ реализации Onclick в JavaScript
Поисковые запросы на тему Onclick в javascript event
На одну кнопку onclick две функции!?
Если говорить об onclick два события в теге, то внутри onclick прописываем стандартные действия как в js
Две функции onclick на одну кнопку js
Две функции onclick на одну кнопку js
Две функции onclick на одну кнопку js
Как передать данные в другой тег по id при onclick
Далее нам понадобится скрипт, который по нажатию, отправит какие-то данные в этот див:
Вызов функции по клику js
Первый способ Вызов функции по клику js
В функции прописываем что-то.
Вызов функции в теге. по клику
Результат вызова функции из тега
Вызов функции в теге. по клику
Второй способ Вызов функции по клику js
Вызов функции в скрипте. по клику
Вызов функции в скрипте. по клику
3). Третий способ Вызов функции по клику js
onclick + функция + несколько действий!?
На onclick можно навесить столько функций или действий, сколько одновременно вы хотите, чтобы произошло.
Давайте разберем очередной пример использования onclick
Изменение текста(innerHTML + getElementById) при onclick :
Вывод alert при onclick :
Соберем весь код несколько событий при одном onclick js
Изменить цвет текста onclick!?
javascript onclick без клика
но первое, что я подумал. вспомнил старый пошлый анекдот! дети, если вам нет 16, то закрываем страницу на этом месте!
Теперь продолжим со взрослыми.
Встречается парочка на хате, а у парня был попугай! Девушка:
— я не могу заниматься этим, когда он смотрит.
Парень накинул тряпку на клетку.
Начали заниматься любовью!
— Давай я сверху, ты снизу!
— Давай ты сверху, я снизу!
— А теперь давай ты сверху, и я сверху!
— Пусть мне оторвут голову! Но это я должен увидеть!
Источники информации:
- http://serblog.ru/nazhatie-na-knopku-v-javascript-sobytie-i-funkcii/
- http://erweb.ru/web-development/back-to-top-button-vanilla-js
- http://computermaker.info/javascript-kak-sozdat-knopku.html
- http://habr.com/ru/post/258167/
- http://habr.com/ru/post/244041/
- http://habr.com/ru/company/badoo/blog/143714/
- http://tanalin.com/blog/posts/link-button/
- http://dev-postnov.ru/modal-on-javascript/
- http://dwweb.ru/page/js/events/001_onclick_v_javascript.html