Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Удаление последней буквы и добавление в начало слова (https://javascript.ru/forum/events/78610-udalenie-poslednejj-bukvy-i-dobavlenie-v-nachalo-slova.html)

agent21 09.10.2019 15:03

Удаление последней буквы и добавление в начало слова
 
Есть задание написать прогу, которая изменяет строку 'Всем привет' каждые 100 мс, удаляя одну букву с конца строки и добавляя удаленную букву к началу строки.Я смог только написать код для удаления буквы с конца.Как теперь ее добавить в начало используя цикл?
<html>
<head>
</head>
<body>
<script type="text/javascript"> 
var str = "Всем привет";
var del = str.substring(0, str.length - 1);
var newstr = str.replace
alert(del);
</script> 
</body>

SuperZen 09.10.2019 15:18

<div class="rotate"></div>
<script>
  document.addEventListener('DOMContentLoaded', () => {
    const obj = { text: 'Всем привет' }
    const rotateEl = document.querySelector('.rotate')
    setInterval(
      () => rotateEl.innerText = obj.text = obj.text[obj.text.length - 1] + obj.text.slice(0, -1),
      100
    )
  })
</script>

laimas 09.10.2019 15:19

А зачем цикл, или задача развернуть строку?

laimas 09.10.2019 15:21

А, бегущая строка, тогда по идее надо пробел добавить.

рони 09.10.2019 15:57

:)
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  div{
       font-size: 2em;
  }

  </style>
  <script>
   addEventListener('DOMContentLoaded', function() {
   let str = 'Всем привет ',
   elem = document.querySelector('div'),
   timer = () => {
       let [...a] = str;
       elem.textContent = str = a.pop() + a.join('');
       setTimeout(timer, 100)
   };
   timer()
     });
  </script>
</head>

<body>
<div></div>

</body>
</html>

laimas 09.10.2019 16:10

Вроде бы не арабы и двигать надо в обратном направлении. :)

Malleys 10.10.2019 11:33

Цитата:

Сообщение от laimas
Вроде бы не арабы

С арабским текстом код от рони не работает. Оно тоже не в ту сторону идёт и разбивка на символы также отделяет диакритические знаки. В общем этот скрипт вообще не правильно работает, он не правильно обрабатывает испанские, еврейские, маратхи и пр. тексты. В русском языке буквы Ё и Й могут быть не в нормализованном виде. Хотя и существует метод normalize у строк, большинство символов не могут быть нормализованы, поскольку лигатурное начертание является единственно возможным. Также это относится и к эмоджи, флагам, и пр.



Вот, к примеру от рони добавил некоторые тексты, чтобы было видно проблему...
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<style>
		p {
			font-size: 2em;
		}
	</style>
	<script>
		addEventListener("DOMContentLoaded", () => {
			const ps = document.querySelectorAll("p");
			(function timer() {
				for(const p of ps) {
					const [...a] = p.textContent
					p.textContent = a.pop() + a.join('')
				}
				setTimeout(timer, 100)
			})();
		});
	</script>
</head>

<body>
	<p>اَلسَّلَامُ عَلَيْكُمْ </p>
	<p>שלום עליכם </p>
	<p>שָׁלוֹם עֲלֵיכֶם </p>
	<p>Head ööd! Tere päevast! </p>
	<p>اَلسَّلَامُ عَلَيْكُمْ‎ </p>
	<p>Ñoño Yáñez come ñame en las mañanas con el niño. </p>
</body>
</html>
Как видите, это весьма странно, поскольку в некоторых языках мы не можем отрывать составные части от слова!

#funfact


Цитата:

Сообщение от laimas
А, бегущая строка, тогда по идее надо пробел добавить.

У меня это плохо сравнивается с такой строкой, например, на автобусе это не так выглядит, вот соорудил, похожее на бегущую строку... Бегущая строка, которая работает правильно на любом языке... а также с эмоджи и флагами и составными символами...
<text-display text="שלום עליכם" lang="he"></text-display>
<text-display text="Hello world!"></text-display>
<text-display text="اَلسَّلَامُ عَلَيْكُمْ‎" lang="ar"></text-display>

<style>

text-display {
	background: radial-gradient(closest-side at center, transparent 30%, black 65%) center / 0.055em 0.055em;
	background-color: #111;
	color: transparent;
	font: 900 5em / 1.5 monospace, system-ui;
	border: 0.1em solid black;
	text-shadow: 0 0 #fdf609, 0 0 0.05em #de1b08, 0 0 0.1em #de1b08;
	display: flex;
	overflow: hidden;
	white-space: nowrap;
}

text-display::before, text-display::after {
	content: attr(text) "\a0";
	min-width: 100%;
	will-change: transform;
	animation: text-display 15s linear infinite;
	animation-direction: inherit;
	flex: 1 0 auto;
	text-align: center;
	mix-blend-mode: color-dodge;
}

:lang(ar), :lang(he) {
	animation-direction: reverse;
}

@keyframes text-display {
	to {
		transform: translateX(-100%);
	}
}

</style>

laimas 10.10.2019 12:14

Цитата:

Сообщение от Malleys
С арабским текстом код от рони не работает

Да вряд ли автору он и нужен, а вот то что направление движения для нашего языка "в арабскую" сторону, это странно. :)

Malleys 10.10.2019 13:02

Цитата:

Сообщение от laimas
Да вряд ли автору он и нужен

Даже если ему и не нужна такая письменность, это не значит, что решение должно ломаться при первом же случае. Что мешает сразу рассмотреть общий случай и решить его?

Общее решение позволяет больше не заморачиваться над тем, что текст не может адекватно отображаться.

Цитата:

Сообщение от laimas
а вот то что направление движения для нашего языка «в арабскую» сторону, это странно.

Ровным счётом как и то странно, что направление движения для арабского языка (и для урду, персидского, пушту и пр.) «в нашу», как вы выразились, сторону!

j0hnik 10.10.2019 16:31

<div id="text" style="font-size: 2em;">Бегущаяя строка! </div>

  <script>
    text.innerHTML = text.innerHTML.replace(/./gi, '<span>$&</span>');
    setInterval(() => text.appendChild(document.querySelector('span')), 50);
  </script>

Malleys 10.10.2019 21:56

j0hnik, а сочетанные буквы?

j0hnik 11.10.2019 03:20

Malleys,
сочетанные?
хочется взять букварь свернуть его в трубку... но...
не сегодня! :)

Malleys 11.10.2019 03:58

j0hnik, а сочетанные буквы? Вы вбросили свой пример на форум даже не проверив его работоспособность!

Ваш пример неправильно разбивает на графемы! Вот пример...

Неправильная разбивка текста
<div id="text" style="font-size: 2em;">안녕하세요 &#128514; </div>

<script>
	text.innerHTML = text.innerHTML.replace(/./gi, '<span>$&</span>');
	setInterval(() => text.appendChild(document.querySelector('span')), 50);
</script>


В данном случае нужна нормализация!

Немного более правильная разбивка текста
<div id="text" style="font-size: 2em;">안녕하세요 &#128514; </div>

<script>
	text.innerHTML = text.innerHTML.normalize().replace(/./gi, '<span>$&</span>');
	setInterval(() => text.appendChild(document.querySelector('span')), 50);
</script>
Хотя метод normalize не может обработать все случаи, он достаточно хорошо работает с большинством старых текстов. Современные тексты, которые содержат новые символы, эмоджи, флаги и пр. не могут быть правильно обработаны при помощи этого метода.

Для правильного разбиения текста используйте Grapheme Splitter.

Правильная разбивка текста
<script src="https://unpkg.com/grapheme-splitter@1.0.4/index.js"></script>
<div id="text" style="font-size: 2em;">안녕하세요 &#128514; </div>

<script>
	var splitter = new GraphemeSplitter();
	text.innerHTML = splitter.splitGraphemes(text.innerHTML).map(g => `<span>${g}</span>`).join("");
	setInterval(() => text.appendChild(text.querySelector('span')), 50);
</script>

j0hnik 11.10.2019 05:14

Malleys,
:stop: Grapheme Splitter будет работать с древнеегипетским????
Если нет, то весь макет коту под хвост!

Malleys 11.10.2019 18:36

Цитата:

Сообщение от j0hnik
с древнеегипетским????

Каждый египетский иероглиф занимает одну кодовую точку, также как это делают буквы русского алфавита в нормализованном (это касается букв Ё и Й) виде. Где вы вообще увидели проблему?

Речь идёт о составных символах, например, флаги, расы (негритянки, мулаты, белые и пр.), хангыль (чамо), причёски, буквы с диакритикой, профессии и пр., которые состоят из нескольких кодовых точек.

Например, рассмотрим флаг России 🇷🇺. Он состоит из двух региональных индикаторов (🇷 и 🇺 ), однако когда эти индикаторы стоят рядом, то они означают один флаг, соответственно только одну графему!

<style>
  @font-face {
    font-family: "Flags";
    src: url("https://cdn.glitch.com/348d485e-4ba6-4841-a41e-5865874b2d66%2FBabelStoneFlags.ttf");
    unicode-range: U+1F1E6-FF;
  }

  html {
    font: 300% "Flags";
    background: #ddd;
  }
</style>

&#127479; + &#127482; = &#127479;&#127482;


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

Не говоря уже о ситуации, когда вы каждую кодовую точку оборачиваете в <span>, тем самым ломая текст! Нужно оборачивать каждую графему в <span>, тогда всё будет в порядке!

На самом деле это проблема в JavaScript, в котором нет способа перечислять графемы в строке. Или я что-то пропустил?

j0hnik 12.10.2019 02:54

Цитата:

Сообщение от Malleys
Или я что-то пропустил?

:yes: а если еще немножечко глубже вникнуть

Malleys 23.10.2019 14:00

Цитата:

Сообщение от j0hnik
а если еще немножечко глубже вникнуть

Вникнул, ничего не нашёл! Пожалуйста, поделитесь вашим способом перечислять графемы в строке.

SuperZen 24.10.2019 13:22

Malleys,
https://github.com/orling/grapheme-splitter

рони 24.10.2019 14:18

Цитата:

Сообщение от SuperZen
grapheme-splitter

Цитата:

Сообщение от Malleys
grapheme-splitter@1.0.4/index.js

пост #13
SuperZen, это разве не одно и тоже?

SuperZen 24.10.2019 14:41

Цитата:

Сообщение от рони (Сообщение 514488)
пост #13
SuperZen, это разве не одно и тоже?

если этот сплиттер не работает, надо руками его допилить, в исходном коде дописать ) недостающие условия определения графемы...

рони 24.10.2019 14:44

Цитата:

Сообщение от SuperZen
если этот сплиттер не работает

не понимаю, почему не работает?

SuperZen 24.10.2019 14:53

Цитата:

Сообщение от рони (Сообщение 514492)
не понимаю, почему не работает?

не понимаю предмет разговора: что не работает, где не работает, когда не работает ))

рони 24.10.2019 14:55

SuperZen,
ок, прервёмся, иначе испорченный телефон.


Часовой пояс GMT +3, время: 06:25.