Как программно выделить текст в редактируемом div

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

      const el = document.getElementById("some_input_field");
      const words = "Find me";
      searchText = el.value;  //Would use el.textContent for contenteditable div, not innerHTML
      if (searchText !== "") {
        foundPosition = findText(searchText, words); //Returns the start and end index of the first match ie: [5,14]
        if (foundPosition != []) {
          el.focus();
          el.setSelectionRange(foundPosition[0], foundPosition[1]); //This is where i want to highlight the text
        } else {
          console.info("Word(s) not found in text");
        }
      } else {
        console.info("No text to search");
      }

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

Поведение ключевого слова "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
0
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете сделать это так (с примером немного переборщил).

const div = document.querySelector("div");
const btn = document.querySelector("button");
const inp = document.querySelector("#txt");
const chkCase = document.querySelector("#chkCase");

btn.addEventListener("click",function() {
  let txt = inp.value;
  if (txt) {
    find(txt,div);
  }
});

function find(needle, haystack) {
  let sel = window.getSelection();
  let range = document.createRange();
  let state = chkCase.checked;
  let hayTxt = haystack.textContent;

  if (!state) {
    hayTxt = hayTxt.toLowerCase();
    needle = needle.toLowerCase();
  }

  if (hayTxt.indexOf(needle) >= 0) {
    range.setStart(haystack.childNodes[0], hayTxt.indexOf(needle));
    range.setEnd(haystack.childNodes[0], hayTxt.indexOf(needle) + needle.length);

    sel.removeAllRanges();
    sel.addRange(range);
  }
}
<div contenteditable = "true">Where's Waldo? Where in the world is Carmen Sandiego? They both say "Find me". Well, maybe not Carmen.</div>
<button type = "button">Find</button>
<input type = "text" name = "txt" id = "txt" value = "Find me">
<input type = "checkbox" name = "chkCase" id = "chkCase" value = "1" checked>Case sensitive?

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

Это абсолютно идеально и работает именно так, как ожидалось. Я столкнулся с проблемой, из-за которой это не работает, если в редактируемых элементах div есть теги <span> или <p>. Например, если у меня есть пустой элемент div и я набираю предложение, выделение работает, если я вставляю необработанный текст, это не удается, поскольку вставка создает тег диапазона. Мне придется поиграть, чтобы понять, как с этим справиться. Я обнаружил, что когда-нибудь у меня может быть несколько тегов диапазона, с которыми мне придется иметь дело.

Ryan H 18.04.2024 22:06

Возможно, вам подойдет что-то вроде этого: stackoverflow.com/questions/75323101/…

FiddlingAway 20.04.2024 12:44

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