Какое событие следует отменить, чтобы остановить доступное для редактирования сочетание клавиш?

Я пытаюсь построить вокруг contenteditable, сначала отключив поведение стиля текста с помощью сочетаний клавиш, таких как ctrl+b или ctrl+i.

Я использую event.preventDefault(), когда эти сочетания клавиш обнаруживаются в событиях keyup и keydown, однако иногда редко, я замечаю, что contenteditable по-прежнему игнорирует event.preventDefault(), а сочетание клавиш соблюдается.

Есть ли способ полностью отключить эти сочетания клавиш, кроме отмены keyup и keydown?


Мой детектор ярлыков был неисправен, и в некоторых случаях он пропускал событие. Кажется, что отмена события на keydown фактически отменяет и ярлык.

Я создал jsfiddle для всех, кто хочет попробовать: https://jsfiddle.net/mohj19bs/28/

Я закрою эту тему завтра, на случай, если кто-то еще может поделиться чем-то интересным, так как contenteditable не перестает меня удивлять.

Почему вы используете и keyup, и keydown? Кстати, keyup не сработает, потому что, подумайте об этом. Когда вы нажимаете Ctrl+T или Ctrl+S, прежде чем вы уберете палец с клавиатуры, желаемое действие уже выполняется. Я бы, наверное, просто использовал keyup. Не могли бы вы включить код?

code 19.03.2022 21:03

@code Я отменил мероприятие keyup, потому что только отмена keydown не всегда помогала, так что я подумал. Но вы правы, вы можете нажать Ctrl+B, и пока обе клавиши полностью нажаты, по умолчанию эффект сработает — это означает, что отмена keydown должна помочь, но иногда Contenteditable стилизует текст редко! Позже я создам хороший jsfiddle.

tosi 19.03.2022 21:13

Также следите за событием keypress. Он по-прежнему выскакивает на определенные браузеры, и некоторый код все еще действует на него.

terrymorse 19.03.2022 21:46

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

code 19.03.2022 22:04

Не могли бы вы показать какой-нибудь код, чтобы мы могли выяснить, когда возникает проблема, и отладить ее оттуда?

code 19.03.2022 22:12

хорошо, я сейчас создаю небольшой редактор в jsfiddle. @код

tosi 19.03.2022 22:20

Я только что понял, что моя функция обнаружения ярлыков была неисправна :( Когда вы нажимаете эти клавиши и держите их нажатыми в том же порядке Ctrl+Any+I, моя функция не может идентифицировать это как сочетание клавиш для курсива и, таким образом, пропускает событие Мне очень жаль всех - отмена ярлыков на «keydown», кажется, на самом деле очень хорошо справляется со своей задачей.

tosi 19.03.2022 22:45

Это была ошибка оператора (меня), и код был в порядке.

tosi 20.03.2022 12:45
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
8
43
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вот еще одна стратегия, которая может сработать для вас. Вместо того, чтобы пытаться предотвратить вставку элементов b и i, просто сразу удалите их на keyup или на paste.

К рассмотренным случаям относятся:

  • [CTRL] + [b] и [CTRL] + [i]
  • вставленный HTML-код, содержащий атрибут встроенного стиля

И он работает рекурсивно, чтобы заботиться о вложенных элементах.

let forbiddenTags = ["B", "I", "STRONG"]
let clean = function(e){

  // Loop through all child nodes
  e.target.childNodes.forEach(function(item){
  
    // recursion if there are childnodes
    if (item.childNodes){
      clean({target:item})
    }
    
    // Remove forbidden tags
    if (item.tagName && forbiddenTags.indexOf(item.tagName) > -1){
      item.insertAdjacentHTML("afterEnd", item.innerHTML)
      item.remove()
      return
    }
    
    // Reset inline style
    if (item.style){
      item.style.fontWeight = "normal"
      item.style.fontStyle = "normal"
    }
  })
}

document.querySelector("#test").addEventListener("keyup", clean)
document.querySelector("#test").addEventListener("paste", clean)
div{
  border: 1px solid grey;
  padding: 0.5em;
}
table{
  border-collapse: collapse;
}
td{
  border: 1px solid grey;
}
<div id = "test" contentEditable=true>Enter text here</div>
<br>
Paste me in!:
<div id = "pasteit">
  <b>bold</b> <i>italic</i> <strong>strong</strong> <span style = "font-weight:bold;">inline</span>
  <table>
    <tr>
      <td style = "font-style:italic;">Italic</td>
      <td style = "font-weight:bold;">Bold</td>
    </tr>
  </table>
</div>

Это работает, но, по-моему, это ужасный UX. Я думаю, что пользователь попытается выделить его жирным шрифтом, это работает, говорит «ура», идет «куда в мире делся мой жирный текст»? Попробовав 3 или 4 раза, пользователь сообщает об ошибке, в которой говорится, что «всякий раз, когда я выделяю что-то жирным шрифтом, оно выделяется». Счастливый разработчик, безумный потребитель.

code 19.03.2022 22:01

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

Louys Patrice Bessette 19.03.2022 22:05

это правда, но до того, как я научился программировать, на некоторых веб-сайтах, которые я использовал, были редактируемые элементы div, где, когда я вставлял HTML вместо предотвращения вставки, он сразу же удалял его. Там все еще есть доли секунды показа HTML. Хотя я не был разработчиком, я был очень раздражен и подумал, что тот, кто создал веб-сайт, сделал плохую работу; также было ясно, что мне не разрешалось вставлять HTML, но я все еще ненавидел то, как это работает. Я не скажу, что этот ответ сам по себе плохой, но UX действительно действует мне на нервы. Было бы намного лучше сделать так, чтобы жирный текст никогда не появлялся.

code 19.03.2022 22:11

@code: С самого начала ... Почему не разрешить выделение жирным шрифтом и курсивом - это настоящий вопрос. ;)

Louys Patrice Bessette 19.03.2022 22:15

Это несколько работает, но с этим решением вы все еще подвергаетесь черной магии contenteditable - это означает, что полужирный шрифт обрабатывается по-разному (т.е. путем его переноса в b или strong или с использованием встроенного) в зависимости от разных браузеров/кейсов.

tosi 19.03.2022 22:20

Я отредактировал, чтобы заботиться об этих случаях.

Louys Patrice Bessette 19.03.2022 23:15

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

Louys Patrice Bessette 19.03.2022 23:32

Лойс, ваше решение работает, но оно просто слепо убивает указанные стили текста. Сценарии использования такого решения чрезвычайно малы, поскольку каждый контент, доступный для редактирования, должен обрабатываться и храниться в каком-либо формате данных. Правильное решение состоит в том, чтобы запретить contenteditable когда-либо применять стиль текста, чтобы нам не приходилось иметь дело с непоследовательным адом разметки при обработке его содержимого. Это также решило бы проблемы UX, упомянутые @code. Я обновил свой вопрос, чтобы отразить мои новые выводы.

tosi 20.03.2022 01:04
Ответ принят как подходящий

Не уверен, с какой проблемой вы имеете дело, но это работает хорошо...

document.getElementById("test").addEventListener("keydown", e => {
  if (!e.ctrlKey) return;
  if (e.keyCode === 66 || e.keyCode === 73) {
    e.preventDefault();
  }
});
<div id = "test" contenteditable>This div is editable</div>

И однострочник для вашего удовольствия:

document.getElementById("test").onkeydown = e => !(e.ctrlKey && (e.keyCode === 66 || e.keyCode === 73));
<div id = "test" contenteditable>This div is editable</div>

Другие вопросы по теме