Как защитить текст от комбинации Ctrl+F в браузере

В спецификации HTML функция Ctrl+F определяется как find-in-page (“найти на странице”), поэтому в статье используется это выражение.

Недавно в спецификацию HTML был добавлен атрибут inert. Содержимое инертных элементов нельзя выбрать, на них также нельзя кликнуть. Такая новинка в спецификации предусматривает возможность введения функции, которую оценят пользователи и разработчики  —  браузер сможет игнорировать инертный узел при использовании find-in-page. Посмотрим, способна ли find-in-page в самом популярном браузере Chrome найти текст в инертных элементах.

Поэкспериментировать с тестовой страницей можно здесь.

Порой пользователям удобнее работать с текстом, если функция Ctrl+F игнорирует текст, находящийся за пределами всплывающего окна. В данном образце приложения содержится таблица с описанием HTML-тегов. Описания слишком велики, чтобы поместиться в ячейку в один ряд. Но при нажатии на ячейку с усеченным описанием во всплывающем окне отображается описание целиком. Затем пользователю может понадобиться найти какое-то ключевое слово в расширенном описании. Хорошо, что все совпадения выделяются желтым цветом, но за пределами всплывающего окна мы также получаем тысячи совпадений, поэтому стрелки в поле find-in-page становятся бесполезными.

К сожалению, мы видим, что атрибут inert не мешает функции find-in-page находить текст. Поэтому разработчикам приходится использовать обходные пути.

Есть сложный, но надежный способ сделать текст невидимым для поиска  —  показывать его с помощью CSS-свойства content. Эта техника продемонстрирована в другой версии тестовой страницы. При открытии всплывающего окна текст из каждой ячейки таблицы копируется в пользовательский атрибут data-txt той же ячейки. Когда всплывающее окно закрывается, значение из атрибута data-txt опять присваивается innerHTML той же ячейки.

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

tableDiv.querySelectorAll('.zoomable').forEach(e => e.addEventListener("click", show));

function show(e) {
    modalContentDiv.innerHTML = e.target.innerHTML;
    modalDiv.style.display = 'flex';
    tableDiv.querySelectorAll('.row>div').forEach(e => {
        e.dataset.txt = e.innerHTML;
        e.innerHTML = '';
    })
}

modalDiv.addEventListener("click", hide);

function hide() {
    modalDiv.style.display = 'none';
    tableDiv.querySelectorAll('[data-txt]').forEach(e => {
        e.innerHTML = e.dataset.txt;
        e.removeAttribute('data-txt');
    })
}

modalContentDiv.addEventListener("click", e => e.stopPropagation());

В качестве ссылок используются значимые идентификаторы элементов. Если бы это был необязательный document.getElementById(), код был бы несколько длиннее.

Подход на основе content может оказаться слишком сложным и работать очень медленно, если таблица огромная. Самый простой способ скрыть текст от find-in-page  —  сделать нерелевантный текст невидимым с помощью CSS-свойства visibility.

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

tableDiv.querySelectorAll('.zoomable').forEach(e => e.addEventListener("click", show));

function show(e) {
    modalContentDiv.innerHTML = e.target.innerHTML;
    modalDiv.style.display = 'flex';
    tableDiv.style.visibility = 'hidden';
}

modalDiv.addEventListener("click", hide);

function hide() {
    modalDiv.style.display = 'none';
    tableDiv.style.visibility = 'visible';
}

modalContentDiv.addEventListener("click", e => e.stopPropagation());

Вы можете загрузить код примера по этой ссылке или поэкспериментировать с тестовой страницей тут.

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Marian Čaikovski: Hiding text from Ctrl+F in a browser

Предыдущая статьяКакие типы изображений можно создавать в Midjourney
Следующая статьяКак оркестровать микросервисы с помощью Docker Compose