Таха Шаштари
Крутая особенность в Средний Это меню подсветки, которое всплывает, когда вы выбираете какой-нибудь текст. Это меню содержит кнопки, которые позволяют выполнять определенные действия на выбранном тексте, как выделение, и делиться.
Если вам нравится эта функция, и вы хотите, чтобы это было на вашем сайте, я собираюсь показать вам, как создать многоразовый компонент, который позволяет этому поведению на тексте, который он содержит.
Вы можете попробовать живую демонстрацию на кодепене:
Посмотреть кодепен здесь .
Создание нового проекта с Vue CLI 3
С Vue CLI 3 Мгновенный прототип мы можем быстро запустить приложение Vue только с одним * .vue.vue.vue файл.
Обратите внимание, что это используется только для создания прототипов, а не для производства.
Во-первых, убедитесь, что у вас установлено это глобально:
NPM установить -G @ vue/cli-service-global
В этом приложении нам нужно только два файла: App.vue.vue. и Highlightable.Vue Отказ
Highlightable.Vue Наш многоразовый элемент меню подсветки. И App.vue.vue. является главной страницей компонента.
Создайте оба файла в любом каталоге, который вы хотите; Тогда запустите Vue служить на App.vue Отказ
vue serve App.vue
Реализация App.Vue.vue.
В App.vue , мы добавим два абзаца. Тот, который можно выделено, и тот, который не может.
Мы также импортируем и используем Highlightable.vue.vue. прежде чем даже создавать его. (Это полезно, чтобы увидеть, как мы собираемся использовать его.)
Вот как это должно смотреть в конце:
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eveniet at debitis deserunt, optio rem eaque obcaecati non possimus nisi assumenda architecto exercitationem dolore quo praesentium, deleniti reiciendis sed ab nihil!
This paragraph can't be highlighted. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore ipsam repellat, fugiat aut ex incidunt ut quisquam quasi consequatur ducimus quo in, cum soluta eos dolores tempore unde voluptate modi. <;/p>
Как вы можете видеть выше, мы обрабатываем два события от Выделенный Отказ Эти два события являются действиями кнопок в меню выделения. Это просто примеры. Вы можете изменить их на все, что вы хотите.
Реализация Highlightable.Vue.
Раздел шаблона состоит из двух частей: элемент меню с кнопками и
Давайте начнем с этого кода в Шаблон :
The insterted text should be displayed here
Обратите внимание, что мы используем Showmenu , который мы еще не создали, чтобы определить, следует ли мы отображать меню.
Теперь давайте перейдем к стайлийской части.
Добавьте следующие CSS в
Нет ничего сложного здесь. .Менью для меню выделения. Меню: после Для маленького треугольника (стрелка) в нижнем центре меню.
Одна важная вещь, чтобы отметить вот что .Менью имеет Абсолют позиция. Нам нужно это расположить его выше выбранного текста.
Наконец, давайте перейдем к
Давайте начнем с данные .
export default { data () { return { x: 0, y: 0, showMenu: false, selectedText: '' } }}xиyдля позиционирования меню.ShowmenuЧтобы показать/скрыть меню.Выбранный текстбудет содержать фактическое содержание выбранного текста.
Теперь давайте перейдем к вычисляется Отказ
computed: { highlightableEl () { return this.$slots.default[0].elm }}У нас есть только одночисленное свойство, которое возвращает элемент, используемый в секции слота Выделенный Отказ В нашем примере это было бы < ; P> Tag Be Tween /выделено>.
Тогда давайте добавим монтируется и BeForeestestroy Функции крюка.
mounted () { window.addEventListener('mouseup', this.onMouseup)},beforeDestroy () { window.removeEventListener('mouseup', this.onMouseup)}Мы используем их, чтобы слушать мышцы Событие, которое мы обращаемся в onmouseup метод.
Теперь давайте создадим onmouseup метод.
methods: { onMouseup () { const selection = window.getSelection() const selectionRange = selection.getRangeAt(0) // startNode is the element that the selection starts in const startNode = selectionRange.startContainer.parentNode // endNode is the element that the selection ends in const endNode = selectionRange.endContainer.parentNode // if the selected text is not part of the highlightableEl (i.e. ) // OR // if startNode !== endNode (i.e. the user selected multiple paragraphs) // Then // Don't show the menu (this selection is invalid) if (!startNode.isSameNode(this.highlightableEl) || !startNode.isSameNode(endNode)) { this.showMenu = false return } // Get the x, y, and width of the selection const { x, y, width } = selectionRange.getBoundingClientRect() // If width === 0 (i.e. no selection) // Then, hide the menu if (!width) { this.showMenu = false return } // Finally, if the selection is valid, // set the position of the menu element, // set selectedText to content of the selection // then, show the menu this.x = x + (width / 2) this.y = y + window.scrollY - 10 this.selectedText = selection.toString() this.showMenu = true }}
Теперь давайте обновим шаблон Highlightable.Vue отражать новые изменения.
The insterted text should be displayed here
Изменения:
- Применил позиции в элемент меню.
- Добавлено
@ mousedown.prevent = ""в элемент меню, чтобы предотвратить закрытие меню при нажатии внутри него. - Добавлено
@ Mousedown.prevent = "HandleAction (« Доля »)»На кнопке Share для обработки нажатого действия. То же самое для выделения действия.
Обратите внимание, что мы используем Mousedown событие вместо Нажмите Чтобы помешать тексту от невыбранного – что приведет к закрытию меню.
Последнее, что мы должны сделать, это добавить Грузоподъемность метод.
handleAction (action) { this.$emit(action, this.selectedText)}Этот метод выделяет Действие Событие и передает выбранный текст вместе с ним. (Мы использовали это событие в app.vue , помнить?)
С этим мы закончили! Теперь у вас есть многоразовый компонент, который вы можете использовать, чтобы показать меню выделения для выбранного текста, так же, как носитель делает.
Спасибо за прочтение! Кстати, я пишу книгу о том, как создать полное одностраничное приложение с нуля, используя Vue. Узнайте страницу посадки книги, если вы заинтересованы в том, чтобы узнать больше о том, что будет покрывать книгу:
Оригинал: “https://www.freecodecamp.org/news/how-to-create-a-medium-like-highlight-menu-in-vue-dc515f2dddef/”