Сокрытие дополнительной информации за взаимодействием со значком, кнопкой или текстом – хороший способ сделать ваш интерфейс чистым и аккуратно. Это то, где играют подсказки и всплывающие меню.
Эта статья представит вас к подходу, который я выполнил, чтобы реализовать компонент контроллера подсказки в реакции. Хотя я называю это всплывающим подсказок, это может быть все, что вы хотите отобразить, когда элемент внутри дома взаимодействует через клик или зависание.
Всплывающее меню пример из среды.
Я буду охватывать только основы здесь. Однако, если вы заинтересованы в виде подробных функций, проверьте хранилище GitHub для полного проекта.
DBILGILI/REACT-TOOTTIP-CONTROLLER
Это богатый функциональный компонент реагирования для управления подсказками/всплывающимися меню
Это богатый функциональный компонент React для контроля подсказков. Не только для подсказков, но вы можете использовать его для различных потребностей в взаимодействии.
Он легко интегрируется в вашу разметку, не нарушая его.
Посетите ПРИМЕРЫ Page обнаружить функциональные возможности.
Особенности
- Поддерживает
Нажмите,надувать,удержаниеиВзаимодействие по зависаниюобнаружение. - Каждая подсказка может быть анимирована индивидуально.
- Установите, закрывается ли всплывающая подсказка при нажатии на него.
- Закройте всплывающую подсказку вручную, присваивая переменную.
- Получить состояние всплывающей подсказки (открыто или нет).
- Установите тайм-аут, чтобы автоматически закрыть всплывающую подсказку.
- Установите всплывающую подсказку относительно запущенного элемента.
- Автоматически отцентрируйте всплывающую подсказку вдоль оси X для элементов динамически размера.
Установка
NPM Установить React-Tooltip-контроллер
После установки модуля импортируйте следующие компоненты:
import {ToolTipController, Select} from 'react-tooltip-controller'Основное использование
Давайте начнем с участия некоторых основных требований к компоненту контроллера подсказков.
- Он должен легко интегрироваться в существующую разметку JSX
Возможность интеграции компонента в ваш существующий JSX без внедрения дополнительных элементов HTML, таких как или В этом смысле важно, чтобы он не влияет на вывод jsx и стайлинг, следовательно,.
- Он должен появиться в верхней части всех других элементов
Очевидно, что подсказка не должна появляться под любыми другими элементами внутри дома. Использование Z-индекса может не помочь вам в некоторых случаях, поскольку его использование не так просто, как кажется. Поэтому всплывающая подсказка должна появиться в самом нижней части Чтобы гарантировать свою иерархию в верхней части дерева Дома.
- Это должно быть интерактивным, когда это необходимо
Пассивная всплывающая подсказка, показывающая только текст или изображение, обычно не требует никакого взаимодействия. Может быть, даже следует, как ожидается, чтобы закрыть при нажатии. Но пример, показанный выше, например, требует всплывающей подсказки, чтобы оставаться активным при нажатии на использование кнопок/ссылок внутри него.
Рассмотрим следующие блоки кода и предположим, что мы хотим создать взаимодействие на одном из
// vim: syntax=JSX
render() {
return (
- List element-1
- List element-2
- List element-3
)
}
Оборачивая этот специфический Элемент вместе с компонентом для подсказки, который мы хотим контролировать, это подход, который мы будем следовать.
// vim: syntax=JSX
render() {
return (
- List element-1
- List element-3
)
}
Это даст нам гибкость иметь полный контроль над выбранным элементом, так и для подсказки компонента или размещения JSX, которую мы включаем в компонент.
Мы можем добавить слушателей событий, управление стилью, информацию о положении Fetch и т. Д. Когда у вас есть один или несколько компонентов, завернутых другим компонентом, эта модель дизайна обычно называется Составные компоненты.
Компоненты
Мы создадим два компонента: <Контроллер> и Отказ
<Контроллер> будет держать часть кода, который мы хотим поговорить друг с другом; Подсказка и выбранный элемент. Компонент, с другой стороны, будет обрабатывать только выбранный элемент DOM, который будет управлять всплеском.
Апис
С <Контроллер> Компонент будет обернуть двоих детей, мы будем использовать следующие активы React API для решения этих детей.
Реагировать. Дети
Реагировать. Детям является одним из API на реакцию, используемые для обработки детей-реквизитов компонента, что означает, что все, что обернутую компонентом, можно получить в качестве опоры внутри компонента. Способ вызова карты на реакцию. Дети с этим .proops.Childrand помогает нам повторять его и создать новый массив из модифицированных детей.
Rect.CloneELement.
Этот API создает клон ввода и возвращает новый реактивный элемент. Объединение этого с реакцией. Дети дают нам возможность манипулировать дочерние компоненты <Контроллер> Компонент, который мы собираемся реализовать.
Reactom.CreatePortal
Поскольку мы стремимся установить компонент подпрыгнуть в самом нижней части тела, нам нужно как-то предотвратить реагирование от добавления его до ближайшего родительского узла по умолчанию. Портал – это нативное решение, предоставляемое реагированием. Мы можем указать, где и какой элемент для монтирования в доме.
Начните с основы
Прежде чем мы начнем реализовывать детальные функциональные возможности, давайте быстро посмотрим на основную структуру <Контроллер> компонент.
// vim: syntax=JSX
import React from 'react'
import ReactDOM from 'react-dom'
class Controller extends React.Component{
render(){
const { children } = this.props
const inputChildren = React.Children.map(children, child => {
if(child.type.displayName === "Select"){
return React.cloneElement(child)
}
else{
return ReactDOM.createPortal(React.cloneElement(child), document.body)
}
})
return inputChildren
}
}
export default Controller
Обратите внимание на использование реагирования. Дети с функцией карты, чтобы повторить все дети и вернуть клону каждого ребенка с React.CloneElement.
Кроме того, использование RACT.CREATEPORTAL является простым, он берет клонированный ребенок и делает его документом. Те, что возвращает элемент в доме.
Обратите внимание, что для того, чтобы различать детей <Контроллер> Я использовал свойство DisplayName, который будет определен как статическое свойство в компонент позже.
Функциональные возможности
Следующим шагом добавляет следующие функции.
- Добавьте слушатель событий на Выбранный элемент Для того, чтобы контролировать всплывающую подсказку
- Установите всплывающую подсказку относительно Выбранный элемент
- Обнаружение Нажмите За пределами компонента всплеск, чтобы закрыть его
- Предотвратить всплывающую подсказку от пузырьковных событий, чтобы он не закрыл при нажатии на него
1. Откройте всплывающую подсказку
Подключение компонента всплывающего подсказки к элементу.
** Начните с создания состояния <Контроллер>
// vim: syntax=JSX
state = {
isOpen: false,
style: {
position: "absolute",
top: 0,
left: 0,
}
}
ISOpen предназначен для монтажа и размонтирования компонента подсказки/JSX Markup и стиль предназначен для позиционирования подсказки относительно Выбранный элемент . Подсказка абсолютно расположена относительно тела по умолчанию. Итак, получив информацию о положении и размере Выбранный элемент, Мы можем разместить подсказку относительно него.
Теперь создайте функции, управляющие состоянием подсказки
// vim: syntax=JSX
open = () => {
this.setState({isOpen: true})
}
close = () => {
this.setState({isOpen: false})
}
Далее, это использует состояния ISOpen и Style, чтобы показать/скрыть и позиционировать компонент для подсказки соответственно. Кроме того, требуется пройти функцию Open () для Компонент в качестве опоры, чтобы при нажатии выбранного элемента мы можем показать всплывающую подсказку.
// vim: syntax=JSX
render(){
const { children } = this.props
const { isOpen, style } = this.state
const inputChildren = React.Children.map(children, child => {
if(child.type.displayName === "Select"){
return React.cloneElement(child, {open: this.open})
}
else{
return (
isOpen && ReactDOM.createPortal(
{React.cloneElement(child)}, document.body
)
)
}
})
return inputChildren
}
Второй аргумент для реагирования .CLONEELEMENT – это новые реквизиты, которые мы передаем на компонент.
Давайте посмотрим на Компонент и посмотреть, как мы обрабатываем клонированный ребенок и реквизит.
// vim: syntax=JSX
import React from 'react'
class Select extends React.Component{
static displayName = "Select"
render(){
const { children, open } = this.props
return React.cloneElement(children, {onClick: open})
}
}
export default Select
Обратите внимание на статическое определение отображения отображения, которое мы ранее использовали в <Контроллер> Отказ
Хотя мы могли бы просто сделать Вернуть детей в методе рендера Компонент, использование API Cloneelement API дает нам возможность создавать новый клон детей опоры с обработчиком событий OnClick.
И мы присваиваем Open Spring этот обработчик событий OnClick для вызова функции Open () в <Контроллер> Компонент, который в результате показывает всплывающую подсказку в верхнем левом углу экрана.
Теперь пришло время получить информацию о положении и размере клонированного дочернего элемента внутри Компонент и передайте эти данные обратно в <Контроллер> Для использования в стиле состояния для позиционирования подсказки.
2. Установите всплывающую подсказку
Позиционирование подсказки относительно элемента.
Получение положения элемента внутри Компонент требует использования атрибута REF. INVEDJS имеет свой способ создания Refs. После того, как вы определите REF, используя REVING.CREATEREF () и прикрепите его к элементу, вы можете обратиться к нему по всему компоненту.
// vim: syntax=JSX
constructor(){
super()
this.selectedElement = React.createRef()
}
render(){
const { children, open } = this.props
return React.cloneElement(children, {ref: this.selectedElement, onClick: open})
}
Вызов метода GetBoundingClientRect () на выделенном элементе REF, возвращает информацию о положении, так и в размере элемента. Мы пройдем эту информацию от Компонент к <Контроллер> Компонент, развертывая функцию в качестве опоры на Отказ
// vim: syntax=JSX
getPos = (left, top, height) => {
this.setState(prevState => ({style: {...prevState.style, left, top: top + height}}))
}
// return React.cloneElement(child, {open: this.open, getPos: this.getPos})
Как только функция GetPos () доступна для Компонент в качестве опоры, вызывая его внутри ThecomponentDidmount Life-Club Club Clust, обновляет переменную состояния стиля <Компонент> и позиционирует всплывающую подсказку относительно левой нижней части выбранного элемента.
// vim: syntax=JSX
state = {
isOpen: false,
style: {
position: "absolute",
top: 0,
left: 0,
}
}
3. Закройте всплывающую подсказку
Переключение всплеск.
До сих пор мы контролировали всплывающую подсказку через Выбранный элемент и позиционируется относительно этого элемента. Теперь следующая вещь реализует механизм для закрытия всплывающей подсказки при нажатии на его нажатие.
Это довольно просто прослушать, чтобы прослушивать события на окне Object Object и переключите переменную состояния ISOPEN. Однако этот подход требует, чтобы некоторые маленькие хитрости заставляли его работать правильно.
Рассмотрим следующий фрагмент из <Контроллер> компонент.
// vim: syntax=JSX
componentDidUpdate(){
if(this.state.isOpen){
window.addEventListener('click', this.close)
}
else{
window.removeEventListener('click', this.close)
}
}
Когда компонент обновляется, мы либо добавляем, либо удаляем слушатель события для окна объекта в соответствии с состоянием всплеск подсказки. Однако эта попытка приводит к открытию всплывающей подсказки и закрытия практически одновременно.
Я придумал два разных решения этой проблемы:
- Вместо того, чтобы прослушать событие ToClick как о предупреждении (), так и близких функциях (), прослушивание Tomousedown и TouseUp для Close () и Open (), соответственно, предотвращает вызов CLACK (), который вызывается, поскольку она слушает событие Mousedown, которое произошло до этой подсказки открыл.
Однако этот подход не удается, если вы попытаетесь закрыть всплывающую подсказку, нажав на Выбранный элемент.
- Этот второй подход немного более продвинутый с точки зрения рассуждения позади него. Использование метода Settimeout с 0 миллисекундными задержкой или без каких-либо определенных временных задач очередей новая задача, которая должна выполняться следующей петлей события. Хотя использование 0 миллисекундов обычно описывает задачу, которая должна быть выполнена немедленно, это не так, чтобы с одним резьбом синхронной природой JavaScript. Когда сертификат используется, он просто создает асинхронный обратный вызов. Вы можете обратиться к конкретному MDN веб-документы Для подробного объяснения по теме.
Внесенный ниже фрагмент гарантирует, что слушатель событий будет добавлен или удален после задач взаимодействия с Выбранный элемент выполнены.
// vim: syntax=JSX
componentDidUpdate(){
setTimeout(() => {
if(this.state.isOpen){
window.addEventListener('click', this.close)
}
else{
window.removeEventListener('click', this.close)
}
}, 0)
}
Хотя нажав на Выбранный элемент Вызывает функцию Open (), слушатель событий на объекте TheWindow вызывает функцию Close () после и закрывает всплывающую подсказку.
4. Предотвратить пузырька события
Предотвращение пузырька событий на подсказке.
Как упоминалось ранее, в некоторых конкретных случаях вам может потребоваться предотвратить закрытие подсказки при нажатии на него. Причина, нажав на всплеск, вызывает функцию CLACE (), является результатом Мероприятие Burning Отказ
Когда событие, такое как OnClick, происходит на элементе, он также призывает к родителю и все остальным предкам. В нашем случае, поскольку подсказка является ребенком тела и тела, имеет прикрепленное событие Click, нажав на всплеск, вызывает функцию, прикрепленную к концу, чтобы щелкнуть событие на теле в конце концов.
Чтобы предотвратить это явление, нам нужно явно указать на обработчике щелчков дочернего элемента, что события не должны пузырить дальше до предков.
Метод Event.StopPagagation () – это то, что нам нужно использовать на обработчике событий OnClick, чтобы остановить распространение событий OnClick в DOM.
// vim: syntax=JSX
return (
isOpen && ReactDOM.createPortal(
e.stopPropagation()} style={style}>{React.cloneElement(child)}, document.body
)
)
Вывод
После прочтения этой статьи вы должны ознакомиться с упомянутыми API-API и иметь общую идею о том, как использовать и объединить их для структурирования составных компонентов для более конкретных задач. Наличие разных компонентов, разговаривающих друг с другом внутри, может сделать ваш код более структурированным и целенаправленным.
Plug: Logrocket, DVR для веб-приложений
https://logrocket.com/signup/
Logrocket Это инструмент для ведения журнала Frontend, который позволяет вам повторить проблемы, как если бы они произошли в вашем браузере. Вместо того, чтобы угадать, почему случаются ошибки, или просят пользователей на скриншоты и журнал свалки, Lognocket позволяет воспроизвести сеанс, чтобы быстро понять, что пошло не так. Он отлично работает с любым приложением, независимо от основ и имеет плагины для регистрации дополнительного контекста из Redux, Vuex и @ Ngrx/Store.
В дополнение к регистрации действий и состояния Redux, Lognocket Records Console Logs, ошибки JavaScript, Stacktraces, Networks/Ответы с заголовками + тел, метаданные браузера и пользовательские журналы. Он также привлекает инструменты DOM для записи HTML и CSS на странице, воссоздая Pixel-Perfect видео даже самых сложных приложений для одной страницы.
Попробуйте бесплатно.
Пост Управляющие подсказки и всплывающие меню с использованием составных компонентов в React появился первым на Logocket blog Отказ
Оригинал: “https://dev.to/bnevilleoneill/controlling-tooltips-pop-up-menus-using-compound-components-in-react-539o”