Выразительный JavaScript - Марейн Хавербеке
Шрифт:
Интервал:
Закладка:
Много типов полей ввода используют тег <input>. Его атрибут type используется для выбора стиля поля. Вот несколько распространённых типов:
text текстовое поле на одну строку
password то же, что текст, но прячет ввод
checkbox переключатель вкл./выкл.
radio часть поля с возможностью выбора из нескольких вариантов
file позволяет пользователю выбрать файл на его компьютере
Поля форм не обязательно должны появляться внутри тега <form>. Их можно разместить в любом месте страницы. Информацию из таких полей нельзя передавать на сервер (это возможно только для всей формы целиком), но когда мы делаем поля, которые обрабатывает JavaScript, нам обычно и не нужно передавать информацию из полей через submit.
<p><input type="text" value="abc"> (text)</p>
<p><input type="password" value="abc"> (password)</p>
<p><input type="checkbox" checked> (checkbox)</p>
<p><input type="radio" value="A" name="choice">
<input type="radio" value="B" name="choice" checked>
<input type="radio" value="C" name="choice"> (radio)</p>
<p><input type="file" checked> (file)</p>
Интерфейс JavaScript для таких элементов разнится в зависимости от типа. Мы рассмотрим каждый из них чуть позже.
У текстовых полей на несколько строк есть свой тег <textarea>. У тега должен быть закрывающий тег </textarea>, и он использует текст внутри этих тегов вместо использования атрибута value.
<textarea>
один
два
три
</textarea>
А тег <select> используется для создания поля, которое позволяет пользователю выбрать один из заданных вариантов.
<select>
<option>Блины</option>
<option>Запеканка</option>
<option>Мороженка </option>
</select>
Когда значение поля изменяется, запускается событие “change”.
Фокус
В отличие от большинства элементов документа HTML, поля форм могут получать фокус ввода клавиатуры. При щелчке или выборе их другим способом они становятся активными, т.е. главными приёмниками клавиатурного ввода.
Если в документе есть текстовое поле, то набираемый текст появится в нём, только если поле имеет фокус ввода. Другие поля по-разному реагируют на клавиатуру. К примеру, <select> пытается перейти на вариант, содержащий текст, который вводит пользователь, а также отвечает на нажатия стрелок, передвигая выбор варианта вверх и вниз.
Управлять фокусом из JavaScript можно методами focus и blur. Первый перемещает фокус на элемент DOM, из которого он вызван, а второй убирает фокус. Значение document.activeElement соответствует текущему элементу, получившему фокус.
<input type="text">
<script>
document.querySelector("input").focus();
console.log(document.activeElement.tagName);
// → INPUT
document.querySelector("input").blur();
console.log(document.activeElement.tagName);
// → BODY
</script>
На некоторых страницах нужно, чтобы пользователь сразу начинал работу с какого-то из полей формы. При помощи JavaScript можно передать этому полю фокус при загрузке документа, но в HTML также есть атрибут autofocus, который приводит к тому же результату, но сообщает браузеру о наших намерениях. В этом случае браузер может отменить это поведение в подходящих случаях, например когда пользователь перевёл фокус куда-то ещё.
<input type="text" autofocus>
Браузеры по традиции позволяют пользователю перемещать фокус клавишей Tab. Мы можем влиять на порядок перемещения через атрибут tabindex. В примере документ будет переносить фокус с текстового поля на кнопку OK, вместо того, чтобы сначала пройти через ссылку help.
<input type="text" tabindex=1> <a href=".">(help)</a>
<button onclick="console.log('ok')" tabindex=2>OK</button>
По умолчанию, большинство типов элементов HTML не получают фокус. Но добавив tabindex к элементу, вы сделаете возможным получение им фокуса.
Отключённые поля
Все поля можно отключить атрибутом disabled, который существует и в виде свойства элемента объекта DOM.
<button>У меня всё хорошо</button>
<button disabled>Я в отключке</button>
Отключённые поля не принимают фокус и не изменяются, и в отличие от активных, обычно выглядят серыми и выцветшими.
Когда программа находится в процессе обработки нажатия на кнопку или другой элемент, которое может потребовать общение с сервером и занять длительное время, неплохо отключать элемент до завершения действия. В этом случае, когда пользователь потеряет терпение и нажмёт на элемент ещё раз, действие не будет повторено лишний раз.
Форма в целом
Когда поле, содержится в элементе <form>, у его элемента DOM будет свойство form, которое будет ссылаться на форму. Элемент <form>, в свою очередь, имеет свойство elements, содержащее массивоподобную коллекцию полей.
Атрибут name поля задаёт, как будет определено значение этого поля при передаче на сервер. Его также можно использовать как имя свойства при доступе к свойству формы elements, который работает и как объект, похожий на массив (с доступом по номерам), так и map (с доступом по имени).
<form action="example/submit.html">
Имя: <input type="text" name="name"><br>
Пароль: <input type="password" name="password"><br>
<button type="submit">Войти</button>
</form>
<script>
var form = document.querySelector("form");
console.log(form.elements[1].type);
// → password
console.log(form.elements.password.type);
// → password
console.log(form.elements.name.form == form);
// → true
</script>
Кнопка с атрибутом type равным submit при нажатии отправляет форму. Нажатие клавиши Enter внутри поля формы имеет тот же эффект.
Отправка формы обычно означает, что браузер переходит на страницу, обозначенную в атрибуте формы action, используя либо запрос GET, либо POST. Но перед этим запускается свойство “submit”. Его можно обработать в JavaScript, и обработчик может предотвратить поведение по умолчанию, вызвав на объекте event preventDefault.
<form action="example/submit.html">
Значение: <input type="text" name="value">
<button type="submit">Сохранить </button>
</form>
<script>
var form = document.querySelector("form");
form.addEventListener("submit", function(event) {
console.log("Saving value", form.elements.value.value);
event.preventDefault();
});
</script>
Перехват событий “submit” полезен в нескольких случаях. Мы можем написать код, проверяющий допустимость введённых значений и сразу же показать ошибку вместо передачи данных формы. Или мы можем отключить отправку формы по умолчанию и дать программе возможность самой обработать ввод, например используя XMLHttpRequest для отправки данных на сервер без перезагрузки страницы.
Текстовые поля
Поля с тегами <input> и типами text и password, а также теги , имеют общий интерфейс. У их элементов DOM есть свойство value, в котором содержится их текущее содержимое в виде строки текста. Присваивание этому свойству значения меняет содержимое поля.
Свойства текстовых полей selectionStart и selectionEnd содержат данные о положении курсора и выделения текста. Когда ничего не выделено, их значение одинаковое, и равно положению курсора. Например, 0 обозначает начало текста, 10 обозначает, что курсор находится на 10-м символе. Когда выделена часть поля, свойства имеют разные значения, а именно начало и конец выделенного текста. В эти поля также можно записывать значение.
К примеру, представьте, что вы пишете статью про Khasekhemwy, но затрудняетесь писать его имя правильно. Следующий код назначает тегу <textarea> обработчик событий, который при нажатии F2 вставляет строку “ Khasekhemwy”.
<textarea></textarea>
<script>
var textarea = document.querySelector("textarea");
textarea.addEventListener("keydown", function(event) {
// The key code for F2 happens to be 113
if (event.keyCode == 113) {
replaceSelection(textarea, "Khasekhemwy");
event.preventDefault();
}
});
function replaceSelection(field, word) {
var from = field.selectionStart, to = field.selectionEnd;
field.value = field.value.slice(0, from) + word
field.value.slice(to);
// Put the cursor after the word
field.selectionStart = field.selectionEnd =
from + word.length;
};
</script>
Функция replaceSelection заменяет текущий выделенный текст заданным словом, и перемещает курсор на позицию после этого слова, чтобы можно было продолжать печатать.