Выравнивание положений вертикальной прокрутки связанных деталей между основным блоком и желобом

Я передаю что-то вроде номеров стихов из Священных Писаний. На данный момент у меня есть примерно такой текст:

1В начале Бог сотворил небо и землю.  2 И земля
был без формы и пуст; и тьма была над бездной.
И Дух Божий носился над водами.

3 И сказал Бог: да будет свет: и стал свет.  4 И увидел Бог
свет, что он хорош: и отделил Бог свет от тьмы.
5И назвал Бог свет Днем, а тьму Ночью. И
вечер и утро были первый день.

Номера стихов являются гиперссылками, и я хочу, чтобы они всегда были доступны; Я также хочу, чтобы пользователи могли различать стихи. Но мне нужен более тонкий подход, чем бросать цифры в лицо читателю. Я также хочу, чтобы числа не отображались, когда пользователь копирует текст. (не критично.)

Мой план состоит в том, чтобы добавить разделитель слева от текста и поместить туда цифры, выровненные по началу стихов (как номера строк в редакторе кода):

1       В начале Бог сотворил небо и землю.  И земля
2       был безвиден и пуст; и тьма была над бездной.
         И Дух Божий носился над водами.

3       И сказал Бог: да будет свет: и стал свет.  И увидел Бог
4       свет, что он хорош: и отделил Бог свет от тьмы.
5       И назвал Бог свет Днем, а тьму Ночью. И
         вечер и утро были первым днем.

Если пользователь наводит курсор на номер стиха, скажем, 4, то выделяется сам соответствующий стих:

1       В начале Бог сотворил небо и землю.  И земля
2       был безвиден и пуст; и тьма была над бездной.
         И Дух Божий носился над водами.

3       И сказал Бог: да будет свет: и стал свет.  And God saw
4     the light, that it was good: and God divided the light from the darkness.
5       И назвал Бог свет Днем, а тьму Ночью. И
         вечер и утро были первым днем.

Но я понятия не имею, как это сделать. У меня есть полный контроль над HTML/CSS/JS, хотя я надеялся сделать это без JS, если это возможно. Существует множество техник для выполнения этого для добавления номеров строк, но я не вижу, как преобразовать их для обработки сценария, в котором номер строки совпадает со стихом, который может состоять из нескольких строк. или разделить строку с частью другого стиха.

Как я могу это реализовать?

Редактировать: я создал макетную версию того, что мне хотелось бы создать. HTML и (большой) CSS взяты из TiddlyWiki . Вы можете рассматривать это как попытку улучшить две разные версии с разным дизайном.

Обсуждение этого проекта в целом ведется на talk.tiddlywiki.com, если вам интересно. Важным моментом, который я понял и забыл в обсуждении выше, является то, что, хотя я отвечаю за разметку, это динамическая разметка, основанная на данных Книги/Главы/Стиха. Мне не приходится жестко кодировать вещи, как в этом макете.

Не могли бы вы показать нам структуру HTML, которую вы сейчас используете, как эти гиперссылки встроены в текст и какой CSS применен?

A Haworth 21.07.2024 08:26

Хотя большую часть этого можно сделать с помощью HTML/CSS, я думаю, что для правильного вертикального интервала потребуется небольшой объем JS. Это приемлемо?

A Haworth 21.07.2024 09:16

@AHaworth: Я могу создать HTML/CSS по мере необходимости. хотя я всегда предпочитаю что-то относительно смысловое. Я могу использовать JS и считаю себя вполне компетентным в этом, но среда сделает JS более сложным, чем обычно.

Scott Sauyet 21.07.2024 20:00

Действительно, на основе мнений? Вопрос о том, как добиться определенного эффекта с помощью HTML/CSS, основан на мнениях? Я удалил две фразы/предложения, неясно связанные с мнением, и надеюсь, что другие проголосуют за возобновление открытия. («Я бы, конечно, рассмотрел другие подходы...» и «Какие альтернативные подходы, по вашему мнению, стоит рассмотреть?»)

Scott Sauyet 21.07.2024 20:36

Проголосовав за возобновление открытия, я подозреваю, что доводчики сосредоточились на том, хорош ли предложенный макет или есть ли другие, которые могли бы быть «лучше», а не на том, был ли это интересный технический вопрос (а это так и есть).

A Haworth 21.07.2024 21:28

@AHaworth Я так не думаю. «Неинтересный вопрос» не является веской причиной закрытия голосования, поэтому не следует предполагать, что именно поэтому кто-то вообще закрывает вопросы. Я понимаю, почему избиратели предпочли закрыть вопрос «на основе мнений» (запросы, основанные на мнениях, были разбросаны по всему телу вопроса). Я думаю, здесь есть объективный вопрос, но чтобы его раскрыть, нужно приложить немало усилий.

TylerH 25.07.2024 20:32

Что-то, что мешает мне проголосовать за повторное открытие, - это то, что вы подразумеваете под словами «Существует множество методов добавления номеров строк, но это довольно механистично; я не понимаю, как их преобразовать, чтобы справиться с этим». Первая ссылка, которую вы там предоставили, показывает, как именно добавлять номера строк и предотвращать их копирование, когда пользователь копирует текст. Так у вас есть проблемы с реализацией этого или нет? Кроме того, почему то, что он «механический» (что это значит?), вызывает проблему? Мы здесь не для того, чтобы угождать предпочтениям; мы здесь, чтобы отвечать на объективные вопросы/решать объективные проблемы.

TylerH 25.07.2024 20:36

Ваш запрос на наведение курсора на номер строки и его наведение на текст — это отдельный вопрос от показа некопируемых номеров строк, а также, возможно, причина оставить вопрос закрытым, поскольку вопросы о переполнении стека должны задавать один вопрос. Если приведенная вами демонстрация кода для добавления некопируемых номеров строк достаточна для решения этой проблемы, тогда можно вместо этого спросить о том, как заставить работать функцию наведения, но не о том и другом (не включайте фразу о трудностях со вставкой строки цифры).

TylerH 25.07.2024 20:38

@TylerH: Под «механическим» я имел в виду, что добавление номеров строк на самом деле не требует от нас никаких знаний о данных/разметке. В моем случае числа (предположительно) являются частью разметки, и их положение в желобе не является простой особенностью размещения их в последовательных строках; примерное совпадение с началом стиха имеет решающее значение. (Приблизительно, потому что иногда несколько стихов начинаются на одной строке, и для этого необходимо внести корректировку.

Scott Sauyet 26.07.2024 03:41

@TylerH: Я думаю о вопросе: «Как я могу добиться такого макета с учетом этих ограничений?» Но момент копирования текста гораздо менее важен, чем размещение чисел в желобе с помощью поведения наведения и выделения. В посте я об этом зачеркнул. Также спасибо за ваше редактирование. Определенно чище после этого!

Scott Sauyet 26.07.2024 03:51

@ScottSauyet Спасибо за дополнительные разъяснения. Я внес еще одну небольшую корректировку в вопрос и проголосовал повторно.

TylerH 26.07.2024 17:18

Я не совсем понимаю вашу недавно добавленную макетированную версию. например 31 находится рядом с пустой строкой. Есть ли в последнем предложении номер стиха? [и есть некоторые случаи, когда первое предложение в «стихе» не имеет номера, или стихи можно разделить на «абзацы»?]

A Haworth 29.07.2024 07:56

@AHaworth: Хм, я тестировал только в Brave, Chrome и Firefox, но во всех из них номера стихов совпадают с их текстом - обычно начало строки, но иногда следующая строка, если два стиха начните с той же строки. В любом случае, это цель, даже если макет вам этого не показывает. И нет, стихи никогда не разбиваются на абзацы.

Scott Sauyet 29.07.2024 13:52
Поведение ключевого слова "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) для оценки ваших знаний,...
2
13
79
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Хотя нумерацию и позиционирование стихов, а также связывание и выделение можно выполнить только с помощью HTML/CSS, для получения вертикального интервала потребуется небольшое количество JS, поскольку в настоящее время CSS не позволяет использовать значения счетчиков в вычислениях.

[На самом деле, это не совсем так, огромное количество CSS с использованием nth-child и :has было бы возможно, но это было бы несколько непрактично для чего-либо, кроме нескольких стихов].

Чтобы сохранить интервалы в показываемом вами тексте, я вставил элементы абзацев.

const paras = document.querySelectorAll('.verses p');
paras.forEach((p) => {
  const verses = p.querySelectorAll('a');
  p.style.setProperty('--numverses', verses.length);
  verses.forEach((verse, i) => {
    verse.style.setProperty('--i', i);
  });
})
.verses {
  counter-reset: verseNum;
  position: relative;
  padding-left: 1em;
}

.verses p {
  --numverses: 0;
  min-height: calc(var(--numverses) * 1em);
}

.verses p>a {
  position: absolute;
  left: 0;
  margin-top: calc(var(--i) * 16px);
  right: -0.2em;
  text-decoration: none;
  color: black;
  width: 2em;
}

.verses p>a::before {
  counter-increment: verseNum;
  content: counter(verseNum);
  font-family: monospace;
  width: 2em;
}

a:hover+span {
  background: yellow;
}
<div class = "verses">
  <p>
    <a href = "#"></a><span> In the beginning God created the heaven and the earth.</span>
    <a href = "#"></a><span> And the earth
was without form, and void; and darkness was upon the face of the deep.
And the Spirit of God moved upon the face of the waters.

</span>
  </p>
  <p>
    <a href = "#"></a><span> And God said, Let there be light: and there was light.</span>
    <a href = "#"></a><span> And God saw
the light, that it was good: and God divided the light from the darkness.</span>
    <a href = "#"></a><span>
 And God called the light Day, and the darkness he called Night. And the
evening and the morning were the first day.</span>
  </p>
</div>

Спасибо. Я поиграю с этим, особенно чтобы посмотреть, как это работает с более длинными отрывками и стихами. Здесь есть что-то очень умное, но я думаю, что мой пример мог ввести в заблуждение. Хотя номера стихов будут последовательными, нет никакой гарантии, что они начнутся с 1. Я предполагал, что фактические цифры будут частью наценки; это не обязательно, но мне нужно иметь возможность указать хотя бы первый из них, а не просто получить его из счетчиков.

Scott Sauyet 21.07.2024 20:16

Вы можете использовать их как часть разметки, поместив их в атрибуты data-versenum вместо выполнения вычислений. Кстати, я думаю, что понадобится больше JS, чтобы найти правильные вертикальные положения стихов разной длины.

A Haworth 21.07.2024 21:25

Да. Я надеялся избежать этого «большего JS», но не думаю, что этого можно избежать. Спасибо.

Scott Sauyet 22.07.2024 13:37

Это не соответствует требованию ОП о копировании текста (поскольку его нельзя выбрать). Или, по крайней мере, выделение довольно ошибочное: вам приходится начинать выделение за пределами всего абзаца, а затем перетаскивать его, чтобы выбрать нужную часть. Вы не можете навести курсор на фразу и одновременно выбрать ее. (Обратите внимание: я буду рад удалить свой отрицательный голос, если эту проблему можно исправить или если в обновлениях OP будет сказано, что они не заботятся о копировании или согласны с копированием с помощью JS с помощью кнопки «копировать» или аналогичного.)

TylerH 25.07.2024 20:45

@TylerH: О, я этого не заметил. Вы правы, это проблема. Мне действительно не нужен эффект наведения на основной текст, только на гиперссылки. (Хотя мое последнее временное решение - поскольку я не мог приблизиться к тому, что хочу - полностью скрывает номер куплета, за исключением всплывающей подсказки title, и просто выделяет стих при наведении курсора мыши. (Кроме того, когда вы нажимаете, он открывает стих самостоятельно.) Старые версии показывали номер строки внутри Хм.

Scott Sauyet 26.07.2024 03:35

@TylerH спасибо, что заметили ошибки. Я изменил код так, чтобы элементы a выходили за пределы элементов диапазона. Стихи теперь не подсвечиваются изнутри (нужен, чтобы иметь определенную ширину), и стихи можно копировать. Теперь все, что нам нужно, это немного JS, чтобы убедиться, что номера стихов находятся на правильном вертикальном уровне (как можно ближе к началу соответствующего вертикального положения стиха). Жаль, что это должен быть JS, но я думаю, что так и есть.

A Haworth 26.07.2024 18:49

Спасибо. Это большое улучшение! Однако я почти уверен, что вы правы насчет того, что для этого нужен JS. Я все еще возлюсь, но спасибо за помощь!

Scott Sauyet 27.07.2024 16:18

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