KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Марейн Хавербеке - Выразительный JavaScript

Марейн Хавербеке - Выразительный JavaScript

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Марейн Хавербеке, "Выразительный jаvascript" бесплатно, без регистрации.
Перейти на страницу:

      fail(reader.error);

    });

    reader.readAsText(file);

  });

}

Возможно читать только часть файла, вызывая slice и передавая результат (т. н. объект blob) объекту reader.

Хранение данных на стороне клиента

Простые HTML-странички с добавкой JavaScript могут выступать отличной основой для мини-приложений – небольших вспомогательных программ, автоматизирующих ежедневные дела. Присоединив к полям формы обработчики событий вы можете делать всё – от конвертации фаренгейтов в цельсии до генерации паролей из основного пароля и имени веб-сайта.

Когда такому приложению нужно сохранять информацию между сессиями, переменные JavaScript использовать не получится – их значения выбрасываются каждый раз при закрытии страницы. Можно было бы настроить сервер, подсоединить его к интернету и тогда приложение хранило бы ваши данные там. Это мы разберём в главе 20. Но это добавляет вам работы и сложности. Иногда достаточно хранить данные в своём браузере. Но как?

Можно хранить строковые данные так, что они переживут перезагрузку страниц — для этого надо положить их в объект localStorage. Он разрешает хранить строковые данные под именами (которые тоже являются строками), как в этом примере:

localStorage.setItem("username", "marijn");

console.log(localStorage.getItem("username"));

// → marijn

localStorage.removeItem("username");

Переменная в localStorage хранится, пока её не перезапишут, удаляется при помощи removeItem или очисткой локального хранилища пользователем.

У сайтов с разных доменов – разные отделения в этом хранилище. То есть, данные, сохранённые с вебсайта в localStorage, могут быть прочтены или перезаписаны только скриптами с этого же сайта.

Также браузеры ограничивают объём хранимых данных, обычно в несколько мегабайт. Это ограничение, вкупе с тем фактом, что забивание жёстких дисков у людей не приносит прибыли, предотвращает отъедание места на диске.

Следующий код реализует простую программу для ведения заметок. Она хранит заметки в виде объекта, ассоциируя заголовки с содержимым. Он кодируется в JSON и хранится в localStorage. Пользователь может выбрать записку через поле <select> и поменять её текст в <textarea>. Добавляется запись по нажатию на кнопку.

Заметки: <select id="list"></select>

<button onclick="addNote()">новая</button><br>

<textarea id="currentnote" style="width: 100%; height: 10em">

</textarea>


<script>

  var list = document.querySelector("#list");

  function addToList(name) {

    var option = document.createElement("option");

    option.textContent = name;

    list.appendChild(option);

  }


  // Берём список из локального хранилища

  var notes = JSON.parse(localStorage.getItem("notes")) ||

              {"что купить": ""};

  for (var name in notes)

    if (notes.hasOwnProperty(name))

      addToList(name);


  function saveToStorage() {

    localStorage.setItem("notes", JSON.stringify(notes));

  }


  var current = document.querySelector("#currentnote");

  current.value = notes[list.value];


  list.addEventListener("change", function() {

    current.value = notes[list.value];

  });

  current.addEventListener("change", function() {

    notes[list.value] = current.value;

    saveToStorage();

  });


  function addNote() {

    var name = prompt("Имя записи", "");

    if (!name) return;

    if (!notes.hasOwnProperty(name)) {

      notes[name] = "";

      addToList(name);

      saveToStorage();

    }

    list.value = name;

    current.value = notes[name];

  }

</script>

Скрипт инициализирует переменную notes значением из localStorage, а если его там нет – простым объектом с одной записью «что купить». Попытка прочесть отсутствующее поле из localStorage вернёт null. Передав null в JSON.parse, мы получим null обратно. Поэтому для значения по умолчанию можно использовать оператор ||.

Когда данные в note меняются (добавляется новая запись или меняется текущая), для обновления хранимого поля вызывается функция saveToStorage. Если б мы рассчитывали, что у нас будут храниться тысячи записей, это было бы слишком накладно, и нам пришлось бы придумать более сложную процедуру для хранения – например, своё поле для каждой записи.

Когда пользователь добавляет запись, код должен обновить текстовое поле, хотя у поля и есть обработчик “change”. Это нужно потому, что событие “change” происходит, только когда пользователь меняет значение поля, а не когда это делает скрипт.

Есть ещё один похожий на localStorage объект под названием sessionStorage. Разница между ними в том, что содержимое sessionStorage забывается по окончанию сессии, что для большинства браузеров означает момент закрытия.

Итог

HTML предоставляет множество различных типов полей формы – текстовые, галочки, множественного выбора, выбора файла.

Из JavaScript можно получать значение и манипулировать этими полями. По изменению они запускают событие “change”, по вводу с клавиатуры – “input”, и ещё много разных клавиатурных событий. Они помогают нам отловить момент, когда пользователь взаимодействует с полем ввода. Свойства вроде value (для текстовых полей и select) или checked (для галочек и радиокнопок) используются для чтения и записи содержимого полей.

При передаче формы происходит событие “submit”. Обработчик JavaScript затем может вызвать preventDefault этого события, чтобы остановить передачу данных. Элементы формы не обязаны быть заключены в теги <form>.

Когда пользователь выбрал файл с жёсткого диска через поле выбора файла, интерфейс FileReader позволит нам добраться до содержимого файла из программы JavaScript.

Объекты localStorage и sessionStorage можно использовать для хранения информации таким способом, который переживёт перезагрузку страницы. Первый сохраняет данные навсегда (ну или пока пользователь специально не сотрёт их), а второй – до закрытия браузера.

Упражнения

Верстак JavaScript

Сделайте интерфейс, позволяющий писать и исполнять кусочки кода JavaScript.

Сделайте кнопку рядом с <textarea>, по нажатию которой конструктор Function из главы 10 будет обёртывать введённый текст в функцию и вызывать его. Преобразуйте значение, возвращаемое функцией, или любую её ошибку, в строку, и выведите её после текстового поля.

<textarea id="code">return "hi";</textarea>

<button id="button">Поехали</button>

<pre id="output"></pre>


<script>

  // Ваш код.

</script>

Автодополнение

Дополните текстовое поле так, что при вводе текста под ним появлялся бы список вариантов. У вас есть массив возможных вариантов, и показывать нужно те из них, которые начинаются с вводимого текста. Когда пользователь щёлкает по предложенному варианту, он меняет содержимое поля на него.

<input type="text" id="field">

<div id="suggestions" style="cursor: pointer"></div>


<script>

  // Строит массив из имён глобальных перменных,

  // типа  'alert', 'document', и 'scrollTo'

  var terms = [];

  for (var name in window)

    terms.push(name);


  // Ваш код.

</script>

Игра «Жизнь» Конвея

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

— каждая живая клетка, количество соседей которой меньше двух или больше трёх, погибает — каждая живая клетка, у которой от двух до трёх соседей, живёт до следующего хода — каждая мёртвая клетка, у которой есть ровно три соседа, оживает

Соседи клетки – это все соседние с ней клетки по горизонтали, вертикали и диагонали, всего 8 штук.

Обратите внимание, что правила применяются ко всей решётке одновременно, а не к каждой из клеток по очереди. То есть, подсчёт количества соседей происходит в один момент перед следующим шагом, и изменения, происходящие на соседних клетках, не влияют на новое состояние клетки.

Реализуйте игру, используя любые подходящие структуры. Используйте Math.random для создания случайных начальных популяций. Выводите поле как решётку из галочек с кнопкой «перейти на следующий шаг». Когда пользователь включает или выключает галочки, эти изменения нужно учитывать при подсчёте следующего поколения.

<div id="grid"></div>

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*