One place for hosting & domains

      элементов

      Создание перетаскиваемых элементов с помощью JavaScript без расширений и HTML


      Введение

      Перетаскивание — это распространенное пользовательское действие, встречающееся во многих графических пользовательских интерфейсах.

      Существуют готовые библиотеки JavaScript для добавления функции перетаскивания в ваше приложение. Однако в некоторых ситуациях библиотека может быть недоступна, или ее использование может быть связано с издержками или зависимостями, которые не нужны вашему проекту. В таких ситуациях найти альтернативное решение поможет знание API-интерфейсов, доступных в современных браузерах.

      Так, HTML Drag and Drop API использует модель событий DOM для получения информации о перетаскиваемом элементе и обновления этого элемента после перетаскивания. С обработчиками событий JavaScript вы можете превратить любой элемент в перетаскиваемый элемент или в цель перетаскивания.

      В этом обучающем модуле мы построим пример перетаскиваемого элемента, используя HTML Drag and Drop API с JavaScript без расширений для использования обработчиков событий.

      Предварительные требования

      Для данного обучающего руководства вам потребуется следующее:

      • Современный браузер с поддержкой Drag and Drop API (Chrome 4+, Firefox 3.5+, Safari 3.1+, Edge 18+).

      Шаг 1 — Создание проекта и начальная разметка

      Наш проект будет состоять из контейнера с двумя типами дочерних элементов:

      • Дочерние элементы, которые можно перетаскивать
      • Дочерние элементы, в которые могут быть перетащены элементы

      Откройте окно терминала и создайте новый каталог проекта:

      • mkdir drag-and-drop-example

      Затем перейдите в этот каталог:

      Создайте в этом каталоге файл index.html:

      Добавьте базовый код веб-страницы HTML:

      index.html

      <!DOCTYPE html>
      <html>
        <head>
          <title>My Drag-and-Drop Example</title>
          <link rel="stylesheet" href="https://www.digitalocean.com/community/tutorials/style.css" />
        </head>
        <body>
        </body>
      </html>
      

      Добавьте между тегами <body> перетаскиваемый элемент draggable и элемент dropzone (цель перетаскивания):

      index.html

      <div class="example-parent">
        <div class="example-origin">
          <div
            id="draggable-1"
            class="example-draggable"
          >
            draggable
          </div>
        </div>
      
        <div
          class="example-dropzone"
        >
          dropzone
        </div>
      </div>
      

      Сохраните и закройте файл. Затем создайте файл style.css:

      Добавьте стили элементов в файл index.html:

      style.css

      .example-parent {
        border: 2px solid #DFA612;
        color: black;
        display: flex;
        font-family: sans-serif;
        font-weight: bold;
      }
      
      .example-origin {
        flex-basis: 100%;
        flex-grow: 1;
        padding: 10px;
      }
      
      .example-draggable {
        background-color: #4AAE9B;
        font-weight: normal;
        margin-bottom: 10px;
        margin-top: 10px;
        padding: 10px;
      }
      
      .example-dropzone {
        background-color: #6DB65B;
        flex-basis: 100%;
        flex-grow: 1;
        padding: 10px;
      }
      

      При этом в приложение будет добавлено определенное форматирование. Теперь вы можете открыть файл index.html в браузере и увидеть элементы draggable <div> и dropzone <div>.

      Снимок экрана с разделами draggable и dropzone

      Затем мы явно сделаем первый <div> перетаскиваемым, добавив атрибут draggable:

      index.html

      <div class="example-parent">
        <div class="example-origin">
          <div
            id="draggable-1"
            class="example-draggable"
            draggable="true"
          >
            draggable
          </div>
        </div>
      
        <div
          class="example-dropzone"
        >
          dropzone
        </div>
      </div>
      

      Сохраните и закройте файл.

      В заключение снова откройте файл index.html в браузере. Если мы нажмем на элемент draggable <div> и перетащим его через экран, потребуется визуальная индикация перемещения.

      По умолчанию атрибут draggable имеет значение auto. Это означает, что поведение браузера по умолчанию определяет, является ли элемент перетаскиваемым. Обычно это значит, что выделенный текст, изображения и ссылки можно перетаскивать, не задавая draggable="true".

      Теперь у нас есть файл HTML с перетаскиваемым элементом. Мы перейдем к добавлению обработчиков onevent.

      Шаг 2 — Обработка событий Drag-and-Drop в JavaScript

      Сейчас, если мы отпустим мышь при перетаскивании перетаскиваемого элемента, ничего не произойдет. Чтобы при перетаскивании элементов DOM активировалось действие, нам необходимо использовать Drag and Drop API:

      • ondragstart: этот обработчик событий прикрепляется к нашему элементу draggable и срабатывает при возникновении события dragstart.
      • ondragover: этот обработчик событий прикрепляется к нашему элементу dropzone и срабатывает при возникновении события dragover.
      • ondrop: этот обработчик событий прикрепляется к нашему элементу dropzone и срабатывает при возникновении события drop.

      Примечание. Всего доступно восемь обработчиков событий: ondrag, ondragend, ondragenter, ondragexit, ondragleave, ondragover, ondragstart и ondrop. В нашем примере они требуются не все.

      Вначале разместим ссылку на новый файл script.js в нашем файле index.html:

      index.html

      <body>
        ...
        <script src="https://www.digitalocean.com/community/tutorials/script.js"></script>
      </body>
      

      Затем создадим новый файл script.js:

      Объект DataTransfer будет отслеживать информацию, связанную с текущим перетаскиванием. Чтобы обновить наш элемент после перетаскивания, нам нужен прямой доступ к объекту DataTransfer. Для этого мы можем выбрать свойство dataTransfer события DragEvent элемента DOM.

      Примечание. Объект DataTransfer технически может отслеживать информацию нескольких элементов, перетаскиваемых одновременно. В нашем примере мы ограничимся перетаскиванием одного элемента.

      Метод setData объекта dataTransfer можно использовать, чтобы задать информацию о состоянии перетаскивания текущего элемента. Для этого нужны два параметра:

      • строка, декларирующая формат второго параметра
      • фактически перемещаемые данные

      Наша цель — переместить элемент draggable в новый родительский элемент. Нам нужна возможность выбрать элемент draggable с уникальным идентификатором id. Мы можем задать id перетаскиваемого элемента с помощью метода setData, чтобы его можно было использовать позднее.

      Давайте снова откроем файл script.js и создадим новую функцию для использования setData:

      script.js

      function onDragStart(event) {
        event
          .dataTransfer
          .setData('text/plain', event.target.id);
      }
      

      Примечание. Сообщается, что в версиях Internet Explorer с 9 по 11 возникают проблемы при использовании 'text/plain'. Для этих версий браузера следует использовать формат 'text'.

      Чтобы обновить стили CSS перетаскиваемого элемента, мы можем снова получить доступ к его стилям, используя событие DOM, и установив желаемые стили для currentTarget.

      Дополним нашу функцию и изменим значение backgroundColor на yellow:

      script.js

      function onDragStart(event) {
        event
          .dataTransfer
          .setData('text/plain', event.target.id);
      
        event
          .currentTarget
          .style
          .backgroundColor="yellow";
      }
      

      Примечание. Любые изменяемые стили потребуется снова обновлять вручную после перетаскивания, если вы используете только стили на время перетаскивания. Если вы измените что-то в начале перетаскивания, перетащенный элемент сохранит новый стиль, если вы снова его не измените.

      Теперь у нас есть функция JavaScript для начала перетаскивания.

      Мы можем добавить ondragstart в элемент draggable в файле index.html:

      index.html

      <div class="example-parent">
        <div class="example-origin">
          <div
            id="draggable-1"
            class="example-draggable"
            draggable="true"
            ondragstart="onDragStart(event);"
          >
            draggable
          </div>
        </div>
      
        <div class="example-dropzone">
          dropzone
        </div>
      </div>
      

      Откройте файл index.html в браузере. Если вы теперь попытаетесь перетащить элемент, будут применены стили, декларированные в нашей функции:

      Анимированный файл gif, показывающий элемент, который перетаскивают, но не отпускают

      Однако если отпустить элемент, ничего не произойдет.

      Следующим в этой последовательности срабатывает обработчик событий ondragover.

      Поведение определенных элементов DOM по умолчанию, в том числе <div> в браузерах, обычно не принимает отпускание. Такое поведение перехватит поведение, которое мы пытаемся реализовать. Чтобы гарантированно получить желаемое поведение при отпускании, мы применим preventDefault.

      Давайте снова откроем файл script.js и создадим новую функцию для использования preventDefault: Добавьте в конец файла следующий код:

      script.js

      function onDragOver(event) {
        event.preventDefault();
      }
      

      Теперь мы можем добавить ondragover в элемент dropzone в файле index.html:

      index.html

      <div class="example-parent">
        <div class="example-origin">
          <div
            id="draggable-1"
            class="example-draggable"
            draggable="true"
            ondragstart="onDragStart(event);"
          >
            draggable
          </div>
        </div>
      
        <div
          class="example-dropzone"
          ondragover="onDragOver(event);"
        >
          dropzone
        </div>
      </div>
      

      На этом этапе мы еще не написали код для обработки завершения перетаскивания. Последним в этой последовательности срабатывает обработчик событий ondrop.

      Вернемся в файл script.js и создадим новую функцию.

      Мы можем сослаться на ранее сохраненные данные, используя метод setData объекта dataTransfer. Мы будем использовать метод getData объекта dataTransfer. Мы задали данные id, и поэтому результат выполнения будет выглядеть так:

      script.js

      function onDrop(event) {
        const id = event
          .dataTransfer
          .getData('text');
      }
      

      Выберем элемент draggable с полученным id:

      script.js

      function onDrop(event) {
        // ...
      
        const draggableElement = document.getElementById(id);
      }
      

      Выберем элемент dropzone:

      script.js

      function onDrop(event) {
        // ...
      
        const dropzone = event.target;
      }
      

      Добавим элемент draggable в dropzone:

      script.js

      function onDrop(event) {
        // ...
      
        dropzone.appendChild(draggableElement);
      }
      

      Сбросим объект dataTransfer:

      script.js

      function onDrop(event) {
        // ...
      
        event
          .dataTransfer
          .clearData();
      }
      

      Теперь мы можем добавить ondrop в элемент dropzone в файле index.html:

      index.html

      <div class="example-parent">
        <div class="example-origin">
          <div
            id="draggable-1"
            class="example-draggable"
            draggable="true"
            ondragstart="onDragStart(event);"
          >
            draggable
          </div>
        </div>
      
        <div
          class="example-dropzone"
          ondragover="onDragOver(event);"
          ondrop="onDrop(event);"
        >
          dropzone
        </div>
      </div>
      

      Сделав это, мы завершили реализацию функции перетаскивания. Откройте файл index.html в браузере и перетащите элемент draggable в dropzone.

      Анимированный файл gif, показывающий перетаскивание объекта в целевую зону

      В нашем примере мы рассмотрели сценарий с одним перетаскиваемым элементом и одной целевой зоной. Мы можем использовать несколько перетаскиваемых элементов, несколько целей, и настроить все это с помощью других обработчиков событий Drag and Drop API.

      Шаг 3 — Построение расширенного примера с несколькими перетаскиваемыми элементами

      Приведем пример возможного использования этого API: список задач с перетаскиваемыми задачами, которые вы можете перетаскивать из столбца «Сделать» в столбец «Сделано».

      Анимированный файл gif, показывающий перетаскивание нескольких задач в столбец «Сделано»

      Чтобы создать собственный список задач, добавьте дополнительные перетаскиваемые элементы с уникальными id в файл index.html:

      index.html

      <div class="example-parent">
        <h1>To-do list</h1>
        <div class="example-origin">
          To-do
          <div
            id="draggable-1"
            class="example-draggable"
            draggable="true"
            ondragstart="onDragStart(event);"
          >
            thing 1
          </div>
          <div
            id="draggable-2"
            class="example-draggable"
            draggable="true"
            ondragstart="onDragStart(event);"
          >
            thing 2
          </div>
          <div
            id="draggable-3"
            class="example-draggable"
            draggable="true"
            ondragstart="onDragStart(event);"
          >
            thing 3
          </div>
          <div
            id="draggable-4"
            class="example-draggable"
            draggable="true"
            ondragstart="onDragStart(event);"
          >
            thing 4
          </div>
        </div>
      
        <div
          class="example-dropzone"
          ondragover="onDragOver(event);"
          ondrop="onDrop(event);"
        >
          Done
        </div>
      </div>
      

      Откройте index.html в браузере и перетащите элементы из столбца «Сделать» в столбец «Сделано». Вы создали приложение списка задач и протестировали его работу.

      Заключение

      В этой статье мы создали приложение списка задач, чтобы изучить возможности функции перетаскивания, доступной в современных браузерах.

      Drag and Drop API предоставляет много разных возможностей настроить действия в дополнение к перетаскиванию. Например, вы можете обновлять стили CSS перетаскиваемых элементов. Также вместо перемещения вы можете копировать перетаскиваемый элемент так, чтобы при отпускании он реплицировался.

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

      Чтобы узнать больше обо всех элементах, которые вы можете перетаскивать с помощью Drag and Drop API, ознакомьтесь с соответствующей документацией MDN.



      Source link

      Использование .map() для итерации элементов массива в JavaScript


      Введение

      В JavaScript существует много разных способов и методик итерации массивов данных, от классического цикла for до метода forEach(). Метод .map() — один из самых популярных методов. Метод .map() создает массив, вызывая определенную функцию для каждого элемента родительского массива. Метод .map() не использует мутацию и создает новый массив, в отличие от мутационных методов, которые вносят изменения в вызывающий массив.

      Существует много возможностей использования этого метода при работе с массивами. В этом учебном модуле мы рассмотрим четыре полезных способа использования .map() в JavaScript: вызов функции для элементов массива, конвертацию строк в массивы, рендеринг списков в библиотеках JavaScript и переформатирование элементов массива.

      Предварительные требования

      Для этого учебного модуля не потребуется писать код, но если вы захотите попробовать приведенные примеры, вы можете использовать Node.js REPL или инструменты для разработчика в браузере.

      Шаг 1 — Вызов функции для каждого элемента массива

      Метод .map() принимает функцию обратного вызова как один из аргументов, и текущее значение обрабатываемого функцией элемента является важным параметром этой функции. Это обязательный параметр. С этим параметром вы можете модифицировать каждый элемент массива и создать новую функцию.

      Приведем пример:

      const sweetArray = [2, 3, 4, 5, 35]
      const sweeterArray = sweetArray.map(sweetItem => {
          return sweetItem * 2
      })
      
      console.log(sweeterArray)
      

      Вывод регистрируется в консоли:

      Output

      [ 4, 6, 8, 10, 70 ]

      Это можно упростить еще больше для очистки кода:

      // create a function to use
      const makeSweeter = sweetItem => sweetItem * 2;
      
      // we have an array
      const sweetArray = [2, 3, 4, 5, 35];
      
      // call the function we made. more readable
      const sweeterArray = sweetArray.map(makeSweeter);
      
      console.log(sweeterArray);
      

      Этот же вывод регистрируется в консоли:

      Output

      [ 4, 6, 8, 10, 70 ]

      Использование выражений вида sweetArray.map(makeSweeter) делает код более удобочитаемым.

      Шаг 2 — Конвертация строки в массив

      Метод .map() принадлежит к прототипу массива. На этом шаге мы используем его для конвертации строки в массив. Здесь мы не разрабатываем метод для работы со строками. Вместо этого мы используем специальный метод .call().

      В JavaScript все элементы являются объектами, и к этим объектам прикреплены методы и функции. Метод .call() позволяет использовать контекст одного объекта с другим объектом. Поэтому вы скопируете контекст .map() в массив на строке.

      Методу .call() можно передавать аргументы используемого контекста и параметры для аргументов первоначальной функции.

      Приведем пример:

      const name = "Sammy"
      const map = Array.prototype.map
      
      const newName = map.call(name, eachLetter => {
          return `${eachLetter}a`
      })
      
      console.log(newName)
      

      Вывод регистрируется в консоли:

      Output

      • [ "Sa", "aa", "ma", "ma", "ya" ]

      Здесь мы использовали контекст метода .map() на строке и им передается аргумент функции, который ожидается от метода .map().

      Такие функции как метод .split() строки, позволяют изменять только отдельные символы в строках, прежде чем возвращать их в массив.

      Шаг 3 — Рендеринг списков в библиотеках JavaScript

      Библиотеки JavaScript, такие как React, используют метод .map() для рендеринга элементов в списках. Однако для этого требуется синтаксис JSX, поскольку метод .map() заключен в синтаксис JSX.

      Приведем пример компонента React:

      import React from "react";
      import ReactDOM from "react-dom";
      
      const names = ["whale", "squid", "turtle", "coral", "starfish"];
      
      const NamesList = () => (
        <div>
          <ul>{names.map(name => <li key={name}> {name} </li>)}</ul>
        </div>
      );
      
      const rootElement = document.getElementById("root");
      ReactDOM.render(<NamesList />, rootElement);
      

      Это компонент React без состояния, выполняющий рендеринг div со списком. Рендеринг отдельных элементов списка выполняется посредством использования метода .map() для итерации по именам, изначально созданным массивом. Рендеринг этого компонента выполняется с использованием ReactDOM на элементе DOM с Id root.

      Шаг 4 — Переформатирование объектов массива

      Метод .map() можно использовать для итерации объектов массива и, аналогично случаю с традиционными массивами, изменяют содержание каждого отдельного объекта и возвращают новый массив. Эта модификация выполняется на основе того, что возвращает функция обратного вызова.

      Приведем пример:

      const myUsers = [
          { name: 'shark', likes: 'ocean' },
          { name: 'turtle', likes: 'pond' },
          { name: 'otter', likes: 'fish biscuits' }
      ]
      
      const usersByLikes = myUsers.map(item => {
          const container = {};
      
          container[item.name] = item.likes;
          container.age = item.name.length * 10;
      
          return container;
      })
      
      console.log(usersByLikes);
      

      Вывод регистрируется в консоли:

      Output

      [ {shark: "ocean", age: 50}, {turtle: "pond", age: 60}, {otter: "fish biscuits", age: 50} ]

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

      Заключение

      В этом учебном модуле мы рассмотрели четыре модели использования метода .map() в JavaScript. В сочетании с другими методами функционал метода .map() можно расширить. Дополнительную информацию можно найти в статье Использование методов массива в JavaScript: методы итерации.



      Source link

      Создание элементов React с помощью JSX


      Автор выбрал Creative Commons для получения пожертвования в рамках программы Write for DOnations.

      Введение

      В этом обучающем руководстве вы узнаете, как описать элементы с помощью JSX. JSX — это абстракция, которая позволяет использовать синтаксис HTML внутри вашего кода JavaScript и с помощью которой вы можете создавать компоненты React, которые выглядят как стандартная HTML-разметка. JSX — это язык шаблонов для элементов React, поэтому он служит основой для любой разметки, которую React будет отображать в вашем приложении.

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

      В рамках этого руководства вы должны будете захватывать события нажатия кнопки мыши по кнопкам непосредственно в разметке и искать случаи, когда синтаксис не соответствует стандартному HTML, например в случае с классами CSS. В конце этого обучающего руководства у вас будет рабочее приложение, которое использует самые разные функции JSX для отображения списка элементов, который имеет встроенный обработчик нажатий кнопки мыши. Это обычная практика для приложений React, которую вы часто будете использовать при изучении фреймворка. Также вы можете смешивать стандартные HTML-элементы с JavaScript, чтобы посмотреть, как React предоставляет возможность создавать небольшие куски кода, пригодные для повторного использования.

      Предварительные требования

      Шаг 1 — Добавление разметки в элемент React

      Как упоминалось ранее, React поддерживает специальный язык разметки JSX. Он представляет собой смесь синтаксиса HTML и JavaScript, которая выглядит примерно следующим образом:

      <div>
        {inventory.filter(item => item.available).map(item => (
          <Card>
              <div className="title"}>{item.name}</div>
              <div className="price">{item.price}</div>
          </Card>
          ))
        }
      </div>
      

      Вы узнаете ряд функций JavaScript, таких как .filter и .map, а также ряд стандартных HTML-тегов, таких как <div>. Но есть другие элементы, которые выглядят как HTML и JavaScript, такие как <Card> и className.

      Это JSX, специальный язык разметки, который делает компоненты React похожими на HTML, но обеспечивает возможности JavaScript.

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

      Создайте новый проект. В командной строке запустите следующий скрипт для установки нового проекта с помощью create-react-app:

      • npx create-react-app jsx-tutorial

      После завершения создания проекта перейдите в его директорию:

      В новой вкладке или окне терминала запустите проект, используя скрипт start Create React App​​​. Браузер будет выполнять автообновление при изменениях, поэтому вы должны оставить этот скрипт работающим все время при работе:

      Вы получите запущенный локальный сервер. Если проект не был открыт в браузере, вы можете перейти на страницу http://localhost:3000/. Если вы запустили приложение на удаленном сервере, приложение можно открыть по адресу http://your_IP_address:3000.

      Ваш браузер будет загружать приложение React, добавленное в Create React App.

      Шаблон проекта React

      Вы должны будете создать абсолютно новый набор компонентов, поэтому вам нужно начать с удаления определенного шаблонного кода, чтобы получить пустой проект. Откройте App.js в текстовом редакторе. Это корневой компонент, который встраивается в страницу. Все компоненты будут запускаться отсюда.

      В новом окне терминала перейдите в папку проекта и откройте src/App.js с помощью следующей команды:

      Вы увидите следующий файл:

      jsx-tutorial/src/App.js

      import React from 'react';
      import logo from './logo.svg';
      import './App.css';
      
      function App() {
        return (
          <div className="App">
            <header className="App-header">
              <img src={logo} className="App-logo" alt="logo" />
              <p>
                Edit <code>src/App.js</code> and save to reload.
              </p>
              <a
                className="App-link"
                href="https://reactjs.org"
                target="_blank"
                rel="noopener noreferrer"
              >
                Learn React
              </a>
            </header>
          </div>
        );
      }
      
      export default App;
      

      Теперь удалите строку import logo from './logo.svg и все содержимое после оператора return в функции. Измените ее, чтобы функция возвращала null. Окончательный код будет выглядеть следующим образом:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        return null;
      }
      
      export default App;
      

      Сохраните изменения и закройте текстовый редактор.

      В заключение удалите логотип. В окне терминала введите следующую команду:

      Вы не будете использовать этот файл SVG в вашем приложении. Кроме того, вам нужно удалить неиспользуемые файлы, которые не пригодятся вам в работе. Это позволит более оптимально организовать ваш код в долгосрочной перспективе.

      Теперь, когда эти части вашего проекта удалены, вы можете перейти к изучению аспектов JSX. Этот язык разметки компилируется React и в результате становится HTML-кодом, который вы видите на странице. Если не слишком углубляться в детали, React принимает JSX и создает модель того, как ваша страница будет выглядеть, затем создает необходимые элементы и добавляет их на страницу.

      Это означает, что вы можете написать что-то, что выглядит как HTML, и ожидать, что созданный HTML будет выглядеть аналогичным образом. Однако существует несколько моментов, которые необходимо прояснить.

      Во-первых, если вы посмотрите на вкладку или окно, где запущен ваш сервер, то увидите следующее:

      Output

      ... ./src/App.js Line 1:8: 'React' is defined but never used no-unused-vars ...

      Это инструмент статического анализа, который сообщает, что вы не используете импортированный код React. При добавлении строки import React from 'react'​​​​​ в ваш код, вы импортируете код JavaScript, который конвертирует JSX в код React. Если JSX отсутствует, то нет и необходимости в импорте.

      Давайте изменим это, добавив немного JSX. Начните с замены null на Hello, World:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        return <h1>Hello, World</h1>;
      }
      
      export default App;
      

      Сохраните файл. Если вы посмотрите в терминал, где запущен сервер, то увидите, что предупреждение исчезло. Если вы перейдете в браузер, то увидите сообщение в виде элемента h1.

      экран браузера с надписью "Hello, World"

      Далее под тегом <h1> добавьте тег параграфа, который содержит строку I am writing JSX. Код будет выглядеть следующим образом:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        return(
          <h1>Hello, World</h1>
          <p>I am writing JSX</p>
        )
      }
      
      export default App;
      

      Поскольку код JSX занимает несколько строк, вам нужно будет обернуть выражение в скобки.

      Сохраните файл. После этого вы увидите ошибку в терминале, где запущен ваш сервер:

      Output

      ./src/App.js Line 7:5: Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? 5 | return( 6 | <h1>Hello, World</h1> > 7 | <p>I am writing JSX</p> | ^ 8 | ) 9 | } 10 |

      Когда вы возвращаете JSX из функции или оператора, необходимо вернуть один элемент. Этот элемент может иметь вложенные дочерние элементы, но на верхнем уровне должен быть один элемент. В этом случае вы возвращаете два элемента.

      Чтобы устранить эту проблему, потребуется внести небольшие изменения в код. Оберните код в пустой тег. Пустой тег — это элемент HTML без каких-либо слов. Он выглядит следующим образом: <></>.

      Откройте ./src/App.js в редакторе и добавьте пустой тег:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        return(
          <>
            <h1>Hello, World</h1>
            <p>I am writing JSX</p>
          </>
        )
      }
      
      export default App;
      

      Пустой тег создает один элемент, но когда код компилируется, он не добавляется в итоговую разметку. Это позволит сохранить чистый код, но при этом предоставив React один элемент.

      Примечание. Вы также могли обернуть код в div вместо пустого тега, если код возвращает один элемент. В этом примере пустой тег имеет преимущество, так как он не добавляет дополнительную разметку в получаемый вывод.

      Сохраните код и закройте файл. Ваш браузер обновит и отобразит обновленную страницу с элементом в виде параграфа. Кроме того, когда код конвертируется, пустые теги отбрасываются:

      Браузер, демонстрирующий разметку и инструменты разработчика, показывающие разметку без пустых тегов

      Вы добавили базовый код JSX для вашего компонента и узнали, что нужно, чтобы включить JSX в отдельный компонент. На следующем шаге мы добавим несколько стилей в ваш компонент.

      Шаг 2 — Добавление стилей в элемент с помощью атрибутов

      На этом шаге вы начнете использование стилей для элементов в вашем компоненте, чтобы узнать, как HTML-атрибуты работают с JSX. В React есть много вариантов использования стилей. Некоторые из них подразумевают использование CSS в Javascript, а другие — предпроцессоров. В этом обучающем руководстве вы будете работать с импортируемыми CSS и классами CSS.

      Теперь, когда у вас есть ваш код, пришло время добавить несколько стилей. Откройте файл App.css в предпочитаемом текстовом редакторе:

      Поскольку вы начинаете с нового JSX, текущий CSS относится к элементам, которые больше не существуют. Поскольку вам не требуется CSS, вы можете удалить ненужный код.

      После удаления кода вы получите пустой файл.

      Далее вам нужно добавить несколько стилей для выравнивания текста по центру. В src/App.css добавьте следующий код:

      jsx-tutorial/src/App.css

      .container {
          display: flex;
          flex-direction: column;
          align-items: center;
      }
      

      В этом блоке кода вы создали селектор класса CSS с именем .container и использовали его для выравнивания содержимого по центру с помощью display: flex.

      Сохраните файл и закройте его. Браузер обновит страницу, но изменений вы не увидите. Прежде чем вы сможете увидеть изменения, вам нужно добавить класс CSS в ваш компонент React. Откройте код компонента JavaScript:

      Код CSS уже импортирован с помощью строки import '. /App.css. Это означает, что webpack будет загружать код для получения окончательной таблицы стилей, но для применения CSS в ваших элементах вам нужно добавить классы.

      Во-первых, в текстовом редакторе замените пустые теги <> на <div>.

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        return(
          <div>
            <h1>Hello, World</h1>
            <p>I am writing JSX</p>
          </div>
        )
      }
      
      export default App;
      

      В этом коде вы заменили пустые теги <>​​​ на теги div. Пустые теги полезны для группировки кода без добавления дополнительных тегов, но здесь вам нужно использовать div, поскольку пустые теги не принимают HTML-атрибутов.

      Далее вам нужно добавить имя класса. Именно здесь JSX начинает отклоняться от HTML. Если вы хотите добавить класс в обычный элемент HTML, вы должны сделать это следующим способом:

      <div class="container">
      

      Но поскольку JSX — это JavaScript, он имеет ряд ограничений. Одно из ограничений состоит в наличии в JavaScript зарезервированных ключевых слов. Это означает, что вы не можете использовать определенные слова в любом коде JavaScript. Например, вы не можете создать переменную с именем null, поскольку это слово зарезервировано.

      Еще одно зарезервированное слово — это class. React обходит это ограничение, внося небольшие изменения в ключевые слова. Вместо добавления атрибута class вы будете использовать атрибут className. Как правило, если атрибут не работает ожидаемым образом, попробуйте добавить версию в «верблюжьем» стиле. Еще один атрибут, который несколько отличается, — это атрибут for, который вы будете использовать для меток. Есть несколько других случаев, но, к счастью, список довольно короткий.

      Примечание. В React атрибуты часто называют свойствами. Свойства — это элементы данных, которые вы можете передавать в другие пользовательские компоненты. Они выглядят как атрибуты, но не соответствуют ни одному из элементов HTML-разметки. В этом обучающем руководстве мы будем называть их атрибутами, поскольку они чаще всего используются как стандартные HTML-атрибуты. Это позволит отличать их от свойств, которые ведут себя отличным от HTML-атрибутов образом. Этот момент будет отражен в будущем в рамках этой серии обучающих материалов.

      Теперь, когда вы знаете, как используется атрибут class в React, вы можете обновить ваш код для добавления стилей. В текстовом редакторе добавьте className="container​​​" в открывающий тег div:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        return(
          <div className="container">
            <h1>Hello, World</h1>
            <p>I am writing JSX</p>
          </div>
        )
      }
      
      export default App;
      

      Сохраните файл. После этого страница будет перезагружена, а содержимое будет выровнено по центру.

      Выровненные по центру элементы html в браузере.

      Атрибут className является уникальным для React. Вы можете добавить большинство атрибутов HTML в JSX без изменений. В качестве примера вернитесь в текстовый редактор и добавьте id greeting​​ в элемент <h1>. Он будет выглядеть как стандартный HTML:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        return(
          <div className="container">
            <h1 id="greeting">Hello, World</h1>
            <p>I am writing JSX</p>
          </div>
        )
      }
      
      export default App;
      

      Сохраните страницу и обновите окно браузера. Страница не изменится.

      Пока что JSX выглядит как стандартная разметка, но преимущество JSX состоит в том, что хотя он и выглядит как HTML, но имеет функционал JavaScript. Это означает, что вы можете назначать переменные и ссылаться на них в ваших атрибутах. Для использования атрибута оберните его в фигурные скобки — {} — вместо кавычек.

      В текстовом редакторе добавьте следующие выделенные строки, чтобы сослаться на атрибут:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        const greeting = "greeting";
        return(
          <div className="container">
           <h1 id={greeting}>Hello, World</h1>
            <p>I am writing JSX</p>
          </div>
        )
      }
      
      export default App;
      

      В этом коде вы создали переменную над оператором return с названием greeting и значением "greeting", а затем указали переменную в атрибуте id вашего тега <h1>.

      Сохраните и закройте файл. Страница будет выглядеть так же, но будет иметь тег id.

      Страница с тегом id, выделенным в инструментах для разработчиков

      До текущего момента вы работали с несколькими элементами отдельно, но вы можете также использовать JSX для добавления множества элементов HTML и внедрять их для создания сложных страниц.

      Чтобы продемонстрировать это, вы создадите страницу со списком эмодзи. Эти эмодзи будут обернуты в элемент <button>. При нажатии на эмодзи вы получите его краткое имя CLDR.

      Для начала вам нужно добавить несколько дополнительных элементов на страницу. Откройте файл src/App.js​​​ в предпочитаемом текстовом редакторе. Держите файл открытым в течение всего шага.

      Вначале добавьте список эмодзи, вставив следующие выделенные строки:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        const greeting = "greeting";
        return(
          <div className="container">
            <h1 id={greeting}>Hello, World</h1>
            <p>I am writing JSX</p>
            <ul>
              <li>
                  <button>
                    <span role="img" aria-label="grinning face" id="grinning face">😀</span>
                  </button>
              </li>
              <li>
                <button>
                    <span role="img" aria-label="party popper" id="party popper">🎉</span>
                </button>
              </li>
              <li>
                <button>
                    <span role="img" aria-label="woman dancing" id="woman dancing">💃</span>
                </button>
              </li>
            </ul>
          </div>
        )
      }
      
      export default App;
      

      Здесь вы создали тег <ul> для хранения списка эмодзи. Каждый эмодзи находится внутри отдельного элемента <li> и окружен элементом <button>. На следующем шаге вы должны будете добавить событие для этой кнопки.

      Вы также окружили эмодзи тегом <span>, который имеет несколько атрибутов. Каждый тег span имеет атрибут role, для которого указано значение img. Это будет служить сигналом для программного обеспечения о том, что элемент выступает в качестве изображения. Кроме того, каждый тег <span> имеет атрибуты aria-label и id с именем эмодзи. Атрибут aria-label будет сообщать посетителям, использующим экранный диктор, что отображается на экране. Вы будете использовать атрибут id при создании событий на следующем шаге.

      Когда вы будете писать код таким образом, вам придется использовать семантические элементы, которые помогут сделать страницу доступной и удобной для парсинга для экранного диктора.

      Сохраните и закройте файл. После обновления страницы в браузере вы увидите следующее:

      браузер со списком эмодзи

      Теперь добавим несколько стилей. Откройте CSS-код в вашем текстовом редакторе:

      Добавьте следующий выделенный код для удаления фона и границы по умолчанию для кнопок, а также увеличения размера шрифта:

      jsx-tutorial/src/App.css

      .container {
          display: flex;
          flex-direction: column;
          align-items: center;
      }
      
      button {
          font-size: 2em;
          border: 0;
          padding: 0;
          background: none;
          cursor: pointer;
      }
      
      ul {
          display: flex;
          padding: 0;
      }
      
      li {
          margin: 0 20px;
          list-style: none;
          padding: 0;
      }
      

      В этом коде вы использовали font-size, border и прочие параметры для изменения внешнего вида ваших кнопок и шрифта. Вы также удалили стили списка и добавили display: flex в элемент <ul>, чтобы сделать список горизонтальным.

      Сохраните и закройте файл CSS. После обновления страницы в браузере вы увидите следующее:

      список с удаленными стилями по умолчанию

      Вы поработали с нескольким элементами JSX, которые выглядят как стандартный HTML. Вы добавили классы, идентификаторы и теги, а также использовали данные в качестве строк и переменных. Но React также использует атрибуты для определения того, как ваши элементы должны реагировать на пользовательские события. На следующем шаге мы начнем делать страницу интерактивной, добавляя события для кнопки.

      Шаг 3 — Добавление событий в элементы

      На этом шаге вы должны будете добавить события для элементов, используя особые атрибуты и захватывая события нажатия кнопки мыши на элементе кнопки. Вы узнаете, как получить информацию из этого события, чтобы вывести дополнительные действия, или использовать другую информацию внутри файла.

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

      Для начала добавьте обработчик события onclick. Это позволяет вам добавить код JavaScript прямо в ваш элемент, вместо того чтобы подключать обработчика событий:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      function App() {
        const greeting = "greeting";
        return(
          <div className="container">
            <h1 id={greeting}>Hello, World</h1>
            <p>I am writing JSX</p>
            <ul>
              <li>
                <button
                  onClick={event => alert(event.target.id)}
                >
                  <span role="img" aria-label="grinning face" id="grinning face">😀</span>
                </button>
              </li>
              <li>
                <button
                  onClick={event => alert(event.target.id)}
                >
                    <span role="img" aria-label="party popper" id="party popper">🎉</span>
                </button>
              </li>
              <li>
                  <button
                    onClick={event => alert(event.target.id)}
                  >
                    <span role="img" aria-label="woman dancing" id="woman dancing">💃</span>
                </button>
              </li>
            </ul>
          </div>
        )
      }
      
      export default App;
      

      Поскольку это JSX, вам нужно использовать onclick в «верблюжьем» стиле, что означает, что вы должны добавить его как onClick. Этот атрибут onClick использует анонимную функцию для получения информации об элементе, на который нажимает пользователь.

      Вы добавили анонимную стрелочную функцию, которая получит событие от нажатой кнопки, а событие будет иметь цель, которая представляет собой элемент <span>. Информация, которая вам нужна, содержится в атрибуте id, который вы можете получить с помощью event.target.id​​​. Вы можете запустить сигнал с помощью функции alert().

      Сохраните файл. В браузере нажмите одно из эмодзи, после чего вы получите сигнал с именем.

      Сигнал для party popper

      Вы можете уменьшить количество дублирующего кода, объявив функцию один раз и передавая ее в каждое действие onClick. Поскольку функция не зависит ни от чего, кроме вводимых данных и вывода, вы можете объявить ее за пределами основной функции компонента. Другими словами, функции не требуется доступа к области видимости компонента. Преимущество такого отделения состоит в том, что функция компонента несколько короче, и вы можете перенести функцию в отдельный файл позже, если захотите.

      В текстовом редакторе создайте функцию displayEmojiName, которая получает событие и вызывает функцию alert() с идентификатором. Затем передайте функцию каждому атрибуту onClick:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      const displayEmojiName = event => alert(event.target.id);
      
      function App() {
        const greeting = "greeting";
        return(
          <div className="container">
            <h1 id={greeting}>Hello, World</h1>
            <p>I am writing JSX</p>
            <ul>
              <li>
                <button
                  onClick={displayEmojiName}
                >
                  <span role="img" aria-label="grinning face" id="grinning face">😀</span>
                </button>
              </li>
              <li>
                <button
                  onClick={displayEmojiName}
                >
                    <span role="img" aria-label="party popper" id="party popper">🎉</span>
                </button>
              </li>
              <li>
                  <button
                    onClick={displayEmojiName}
                  >
                    <span role="img" aria-label="woman dancing" id="woman dancing">💃</span>
                </button>
              </li>
            </ul>
          </div>
        )
      }
      
      export default App;
      

      Сохраните файл. В браузере нажмите на эмодзи, после чего вы увидите тот же сигнал.

      На этом шаге вы добавили событие для каждого элемента. Вы также увидели, как JSX использует немного отличающиеся имена для событий элементов, а также начали писать многократно используемый код, принимая функцию и используя ее для нескольких элементов. На следующем шаге вы будете писать функцию для многократного использования, которая возвращает элементы JSX, вместо того, чтобы писать каждый элемент вручную. Это позволит дополнительно уменьшить количество дублирующего кода.

      Шаг 4 — Сопоставление данных для создания элементов

      На этом шаге мы перейдем к дальнейшему знакомству с использованием JSX в качестве простой разметки. Вы научитесь совмещать его с JavaScript для создания динамической разметки, которая позволяет сократить код и повысить удобочитаемость. Вы выполните рефакторинг кода в массив, по которому вы пройдетесь в цикле для создания HTML-элементов.

      JSX не ограничивается использованием синтаксиса в стиле HTML. Он позволяет также использовать JavaScript непосредственно в вашей разметке. Вы уже попробовали сделать это, передавая функции в атрибуты. Вы также использовали переменные для повторного использования данных. Теперь пришло время создать JSX прямо из данных, используя стандартный код JavaScript.

      В текстовом редакторе вам потребуется создать массив данных эмодзи в файле src/App.js. Откройте файл снова, если вы закрыли его:

      Добавьте массив, который будет содержать объекты, которые содержат эмодзи и имя эмодзи. Обратите внимание, что эмодзи должны быть окружены кавычками. Создайте этот массив над функцией App:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      const displayEmojiName = event => alert(event.target.id);
      const emojis = [
        {
          emoji: "😀",
          name: "grinning face"
        },
        {
          emoji: "🎉",
          name: "party popper"
        },
        {
          emoji: "💃",
          name: "woman dancing"
        }
      ];
      
      function App() {
      ...
      }
      
      export default App;
      

      Теперь у вас есть данные, по которым вы можете пробегаться в цикле. Чтобы использовать JavaScript внутри JSX, вам нужно поместить его в круглые скобки: {}. Это аналогично тому, как вы добавляли функции для атрибутов.

      Для создания компонентов React вам нужно будет преобразовать данные в элементы JSX. Чтобы сделать это, вам нужно будет выполнить сопоставление данных и вернуть элемент JSX. Существует несколько проблем, которые вам нужно учитывать при написании кода.

      Во-первых, группа элементов должна быть окружена контейнером <div>. Во-вторых, каждый элемент нуждается в специальном свойстве key. key должен представлять собой уникальный набор данных, которые React сможет использовать для отслеживания элементов, что позволит ему узнать, когда нужно обновить компонент. Ключ будет отделен от скомпилированного HTML, поскольку он предназначен только для внутренних целей. Когда вы работаете с циклами, вам нужно будет добавить простую строку в качестве ключа.

      Здесь представлен упрощенный пример, который осуществляет сопоставление списка имен в <div>:

      ...
      const names = [
          "Atul Gawande",
          "Stan Sakai",
          "Barry Lopez"
      ];
      
      return(
          <div>
              {names.map(name => <div key={name}>{name}</div>)}
          </div>
      )
      ...
      

      Получаемый в результате HTML будет выглядеть следующим образом:

      ...
      <div>
          <div>Atul Gawande</div>
          <div>Stan Sakai</div>
          <div>Barry Lopez</div>
      </div>
      ...
      

      Конвертация списка эмодзи будет выглядеть аналогичным образом. <ul> будет служить контейнером. Вы должны будете выполнить сопоставление данных и вернуть <li> с ключом короткого имени эмодзи. Вы будете использовать жестко заданные данные в тегах <button> и <span>​​ на информацию из цикла.

      В текстовом редакторе добавьте следующее:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      const displayEmojiName = event => alert(event.target.id);
      const emojis = [
        {
          emoji: '😀',
          name: "test grinning face"
        },
        {
          emoji: '🎉',
          name: "party popper"
        },
        {
          emoji: '💃',
          name: "woman dancing"
        }
      ];
      
      function App() {
        const greeting = "greeting";
        return(
          <div className="container">
            <h1 id={greeting}>Hello, World</h1>
            <p>I am writing JSX</p>
            <ul>
              {
                emojis.map(emoji => (
                  <li key={emoji.name}>
                    <button
                      onClick={displayEmojiName}
                    >
                      <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
                    </button>
                  </li>
                ))
              }
            </ul>
          </div>
        )
      }
      
      export default App;
      

      В коде вы выполнили сопоставление для массива эмодзи в теге <ul> и вернули <li>. В каждом элементе <li> вы использовали имя эмодзи в качестве свойства key. Кнопка будет иметь ту же функцию, что и обычно. В элементе <span> замените aria-label​​​ и id на name. Внутри тега <span>​​ должен быть эмодзи.

      Сохраните файл. После обновления окна браузера вы увидите данные. Обратите внимание, что ключ отсутствует в сгенерированном HTML.

      Браузер с инструментами разработчика, демонстрирующий обновленный HTML без свойств ключей

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

      Шаг 5 — Условное представление элементов с сокращенным вычислением

      На этом шаге мы будем использовать сокращенное вычисление для демонстрации определенных элементов HTML при определенных условиях. Это позволит вам создавать компоненты, которые смогут скрывать или показывать HTML на основе дополнительной информации, обеспечивающей гибкость для ваших компонентов при разных ситуациях.

      Существуют ситуации, когда компонент должен в определенных ситуациях отображать информацию, а в других — нет. Например, вы можете показать пользователю сообщение с сигналом при соблюдении одних условий, либо вы можете вывести информацию об учетной записи для администратора, которая не должна быть доступна обычному пользователю.

      Чтобы сделать это, вам нужно будет использовать сокращенное вычисление. Это означает, что вы будете использовать условные операторы, и если первая часть условия будет выполняться, оператор будет возвращать информацию во второй части.

      Ниже представлен пример. Если вы хотите показать кнопку только для пользователя, выполнившего вход, необходимо окружить элемент круглыми скобками и добавить перед ним условие.

      {isLoggedIn && <button>Log Out</button>}
      

      В этом примере вы используете оператор &&, который возвращает последнее значение, если все условия являются истинными. В ином случае он возвращает false, что служит для React сигналом о том, что возвращать дополнительную разметку не нужно. Если isLoggedIn​​​ имеет значение true, React будет отображать кнопку. Если isLoggedIn имеет значение false, кнопка не будет отображаться.

      Чтобы сделать это, добавьте следующие выделенные строки:

      jsx-tutorial/src/App.js

      import React from 'react';
      import './App.css';
      
      ...
      
      function App() {
        const greeting = "greeting";
        const displayAction = false;
        return(
          <div className="container">
            <h1 id={greeting}>Hello, World</h1>
            {displayAction && <p>I am writing JSX</p>}
            <ul>
      ...
            </ul>
          </div>
        )
      }
      
      export default App;
      

      В текстовом редакторе вы создали переменную с именем displayAction и значением false. Затем вы окружили тег <p> фигурными скобками. Перед фигурными скобками вы добавили displayAction && для создания условного оператора.

      Сохраните файл, после чего вы увидите, как элемент исчез в браузере. Что более важно, он не появляется в сгенерированном HTML. Это не то же самое, что сокрытие элемента в CSS. Он не существует вообще в итоговой разметке.

      Браузер с инструментами для разработчиков, демонстрирующий отсутствие элемента

      Теперь значение displayAction жестко задано, но вы можете хранить это значение в виде состояния или передавать его в качестве свойства из родительского компонента.

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

      Заключение

      К данному моменту мы создали пользовательское приложение с помощью JSX. Вы узнали, как добавить в компонент элементы в стиле HTML, добавить стили для этих элементов, передавать атрибуты для создания семантической и доступной разметки, а также добавить события в компоненты. Затем вы научились совмещать JavaScript с JSX, чтобы сократить количество дублирующего кода и показывать или скрывать элементы в зависимости от условий.

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

      Если вы хотите узнать больше о React, ознакомьтесь с нашей страницей, посвященной React.



      Source link