Вход

Просмотр полной версии : Автоматическая остановка таймера после завершения интеракции


Борис К
24.12.2021, 11:39
Здравствуйте!)
В нижеприведённом примере кнопкой Start запускается таймер, далее необходимо кликами на "H" и "w" поменять их местами, после чего сработает alert("Hello world!"), потом вручную кнопкой Stop останавливается таймер.
Вопрос: какой код необходимо прописать вместо alert("Hello world!"), чтобы таймер останавливался автоматически без задействования кнопки Stop?

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript">
let temp = [];
let end = ["H", "e", "l", "l", "o", "w", "o", "r", "l", "d"];
let win;
function exch(event) {
if(win) return;
let img;
if (img = event.target.closest(".click")) {
let cellIndex = event.target.closest("td").cellIndex;
let rowIndex = event.target.closest("tr").rowIndex;
if (temp.length) {
temp[0].classList.remove("active");
let x = Math.abs(cellIndex - temp[1]);
let y = Math.abs(rowIndex - temp[2]);
if ((x == 0 && y == 1) || (x == 1 && y == 0) || img === temp[0]) {
[img.src, temp[0].src] = [temp[0].src, img.src]
temp = [];
} else {
img.classList.add("active");
temp = [img, cellIndex, rowIndex];
}
} else {
img.classList.add("active");
temp = [img, cellIndex, rowIndex];
}
const numbers = Array.from(document.querySelectorAll(".click")).map(({src}) => src.split('=')[2]);
win = numbers.every((a, i) => a === end[i]);
if(win) alert("Hello world!");
}
}
</script>
</head>
<body>
<form onclick="exch(event)">
<table align="center" cellspacing="1" cellpadding="0">
<tr>
<td><img class="click" name="1" src="https://placehold.co/100x100/0000ff/ffffff?font=playfair-display&text=w"></td>
<td><img class="click" name="2" src="https://placehold.co/100x100/ff0000/ffffff?font=playfair-display&text=e"></td>
<td><img class="click" name="3" src="https://placehold.co/100x100/ff0000/ffffff?font=playfair-display&text=l"></td>
<td><img class="click" name="4" src="https://placehold.co/100x100/ff0000/ffffff?font=playfair-display&text=l"></td>
<td><img class="click" name="5" src="https://placehold.co/100x100/ff0000/ffffff?font=playfair-display&text=o"></td>
</tr>
<tr>
<td><img class="click" name="6" src="https://placehold.co/100x100/ff0000/ffffff?font=playfair-display&text=H"></td>
<td><img class="click" name="7" src="https://placehold.co/100x100/0000ff/ffffff?font=playfair-display&text=o"></td>
<td><img class="click" name="8" src="https://placehold.co/100x100/0000ff/ffffff?font=playfair-display&text=r"></td>
<td><img class="click" name="9" src="https://placehold.co/100x100/0000ff/ffffff?font=playfair-display&text=l"></td>

<td><img class="click" name="10" src="https://placehold.co/100x100/0000ff/ffffff?font=playfair-display&text=d"></td>
</tr>
</table>
</form>
<br /><br /><br />

<div style="text-align: center">
<label id="seconds">00</label>
<br />
<input type="button" id="gobutton" onclick="startTimer()" value="Start">
<input type="button" id="stopbutton" onclick="stopTimer()" value="Stop">
<br />
<label id="totalTime">
</label>
</div>
<script type="text/javascript">
let secondsLabel = document.getElementById("seconds");
let totalSeconds = 0;
let counter;
let timerOn;
let htmlResets;
let totalMills = 0;
function startTimer() {
if (timerOn == 1) {
return;
}
else {
counter = setInterval(setTime, 10);
timerOn = 1;
htmlResets = 0;
}
}
function pauseTimer() {
if (timerOn == 1) {
clearInterval(counter);
timerOn = 0;
}
if (htmlResets == 1) {
secondsLabel.innerHTML = "00";
totalMills = 0;
totalSeconds = 0;
}
else {
htmlResets = 1;
}
}
function stopTimer() {
totalTime.innerHTML = secondsLabel.innerHTML;
secondsLabel.innerHTML = "00";
totalMills = 0;
totalSeconds = 0;
clearInterval(counter);
timerOn = 0;
}
function setTime() {
++totalMills;
if (totalSeconds == 60) {
totalSeconds = 0;
secondsLabel.innerHTML = "00";
clearInterval(counter);
}
if (totalMills == 100) {
totalSeconds++;
secondsLabel.innerHTML = pad(totalSeconds % 60);
totalMills = 0;
}
if (totalSeconds == 60) {
totalSeconds = 0;
}
}
function pad(val) {
let valString = val + "";
if (valString.length < 2) {
return "0" + valString;
}
else {
return valString;
}
}
</script>
</body>
</html>

рони
24.12.2021, 13:00
Борис К,
вместо if(win) alert("Hello world!");
будет

if(win) stopTimer();
:-?

Борис К
24.12.2021, 13:31
Учитель Рони!
Смешно и грустно... так всё просто, а я уж слишком усложнил всё, мучаясь три дня!((( Куда только не вставлял этот злополучный stopTimer())))
Фуууххх... но стыдно!(((
Как всегда, моя огромная благодарность Вам и глубокое уважение за ценный опыт и профессионализм!

Борис К
04.01.2022, 02:12
Рони, с Новым годом Вас!
Искренне желаю успехов во всех ваших начинаниях!))

Но, пожалуйста, помогите ещё по этой теме...
Хотелось бы таблицу вот в такой форме

<table align="center" cellspacing="0" cellpadding="0">
<tr>
<td id="blue"></td>
<td id="green"></td>
</tr>
<tr>
<td id="red"></td>
<td id="orange"></td>
</tr>
</table>

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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
#red {
background-color: #ff0000;
width: 100px;
height: 100px;
}
#orange {
background-color: #ff9900;
width: 100px;
height: 100px;
}
#green {
background-color: #006600;
width: 100px;
height: 100px;
}
#blue {
background-color: #0000ff;
width: 100px;
height: 100px;
}
</style>

<script type="text/javascript">
let temp = [];
let end = ["r", "g", "b", "o"];
let win;
function exch(event) {
if(win) return;
let img;
if (img = event.target.closest(".click")) {
let cellIndex = event.target.closest("td").cellIndex;
let rowIndex = event.target.closest("tr").rowIndex;
if (temp.length) {
let x = Math.abs(cellIndex - temp[1]);
let y = Math.abs(rowIndex - temp[2]);
if ((x == 0 && y == 1) || (x == 1 && y == 0) || img === temp[0]) {
[img.src, temp[0].src] = [temp[0].src, img.src]
temp = [];
}
} else {
temp = [img, cellIndex, rowIndex];
}
const numbers = Array.from(document.querySelectorAll(".click")).map(({src}) =>

src.split('=')[2]);
win = numbers.every((a, i) => a === end[i]);
if(win) alert("Hello world!");
}
}
</script>
</head>
<body>
<form onclick="exch(event)">
<table align="center" cellspacing="0" cellpadding="0">
<tr>
<td><img class="click" name="1" src="https://placehold.co/100x100/0000ff/ffffff?font=playfair-display&text=b"></td>
<td><img class="click" name="2" src="https://placehold.co/100x100/006600/ffffff?font=playfair-display&text=g"></td>
</tr>
<tr>
<td><img class="click" name="3" src="https://placehold.co/100x100/ff0000/ffffff?font=playfair-display&text=r"></td>
<td><img class="click" name="4" src="https://placehold.co/100x100/ff9900/ffffff?font=playfair-display&text=o"></td>
</tr>
</table>
</form>

</body>
</html>

Например: при кликах на синий и красный квадратики в "стилях" они меняются местами (в результате в таблице должна быть такая последовательность цветов слева направо, сверху вниз - красный, зелёный, синий, оранжевый), после чего срабатывает alert("Hello world!").
И тогда при таком решении, как сделать, чтобы при открытии странички каждый раз цветные квадратики в "стилях" располагались в табличке случайном порядке?
Фуууххх...

рони
04.01.2022, 08:21
Борис К,
картинки располагать в таблице по порядку.

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<style type="text/css">
#red {
background-color: #ff0000;
width: 100px;
height: 100px;
}

#orange {
background-color: #ff9900;
width: 100px;
height: 100px;
}

#green {
background-color: #006600;
width: 100px;
height: 100px;
}

#blue {
background-color: #0000ff;
width: 100px;
height: 100px;
}
</style>

<script type="text/javascript">
let temp = [];
let end = ["r", "g", "b", "o"];
let win;

function exch(event) {
if (win) return;
let img;
if (img = event.target.closest(".click")) {
let cellIndex = event.target.closest("td").cellIndex;
let rowIndex = event.target.closest("tr").rowIndex;
if (temp.length) {
let x = Math.abs(cellIndex - temp[1]);
let y = Math.abs(rowIndex - temp[2]);
if ((x == 0 && y == 1) || (x == 1 && y == 0) || img === temp[0]) {
[img.src, temp[0].src] = [temp[0].src, img.src]
temp = [];
}
} else {
temp = [img, cellIndex, rowIndex];
}
const numbers = Array.from(document.querySelectorAll(".click")).map(({
src
}) =>

src.split('=')[2]);
if (!event.random) win = numbers.every((a, i) => a === end[i]);
if (win) alert("Hello world!");
}
}
document.addEventListener("DOMContentLoaded", function() {
let img = Array.from(document.querySelectorAll(".click"));
img.sort(_ => Math.random() - .5);
img.forEach(target => exch({
target,
random: true
}));
temp = [];
});
</script>
</head>

<body>
<form onclick="exch(event)">
<table align="center" cellspacing="0" cellpadding="0">
<tr>
<td><img class="click" name="1" src="https://placehold.co/100x100/0000ff/ffffff?font=playfair-display&text=r"></td>
<td><img class="click" name="2" src="https://placehold.co/100x100/006600/ffffff?font=playfair-display&text=g"></td>
</tr>
<tr>
<td><img class="click" name="3" src="https://placehold.co/100x100/ff0000/ffffff?font=playfair-display&text=b"></td>
<td><img class="click" name="4" src="https://placehold.co/100x100/ff9900/ffffff?font=playfair-display&text=o"></td>
</tr>
</table>
</form>

</body>

</html>

Борис К
04.01.2022, 15:10
Рони, благодарю за оперативный отклик, но, видимо, я недостаточно ясно изложил проблему тёмной ночкой((
Да, с расположением в табличке цветных изображений в случайном порядке всё отлично получилось!!! Огромный Thanx)))
Но хотелось бы, чтобы таблица была такого вида (с использованием стилей):

<table align="center" cellspacing="0" cellpadding="0">
<tr>
<td id="blue"></td>
<td id="green"></td>
</tr>
<tr>
<td id="red"></td>
<td id="orange"></td>
</tr>
</table>

А не так как есть - с использованием изображений (<td><img class="click" name="1" src="url"></td>)
Без понятия, как в этой строке - let end = ["r", "g", "b", "o"]; означать ячейки таблицы с использованием стилей (как это - <td id="blue"></td>), а не изображений (<img src="...>), чтобы при завершении последовательности, например, красный, зелёный, синий, оранжевый срабатывал alert("Hello world!").
Хочется, чтобы цветные квадратики были представлены через стили, а не как изображения!))
Фуууххх...

рони
04.01.2022, 15:51
красный, зелёный, синий, оранжевый
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<style type="text/css">
[data-id="red"] {
background-color: #ff0000;
width: 100px;
height: 100px;
}

[data-id="orange"] {
background-color: #ff9900;
width: 100px;
height: 100px;
}

[data-id="green"] {
background-color: #006600;
width: 100px;
height: 100px;
}

[data-id="blue"] {
background-color: #0000ff;
width: 100px;
height: 100px;
}
</style>

<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
let temp = [];
let form = document.querySelector(".game");
let tds = Array.from(form.querySelectorAll("[data-id]"));
let idEnd = tds.map(({
dataset: {
id
}
}) => id);
let win;

function exch(event) {
if (win) return;
let td = event.target.closest("[data-id]");
if (td) {
let cellIndex = td.cellIndex;
let rowIndex = td.closest("tr").rowIndex;
if (temp.length) {
let x = Math.abs(cellIndex - temp[1]);
let y = Math.abs(rowIndex - temp[2]);
if ((x == 0 && y == 1) || (x == 1 && y == 0) || td === temp[0]) {
[td.dataset.id, temp[0].dataset.id] = [temp[0].dataset.id, td.dataset.id]
temp = [];
}
} else {
temp = [td, cellIndex, rowIndex];
}

if (!event.random) win = tds.every(({
dataset: {
id
}
}, i) => id === idEnd[i]);
if (win) alert("Hello world!");
}
}

form.addEventListener("click", exch);

tds.slice(0).sort(_ => Math.random() - .5)
.forEach(target => exch({
target,
random: true
}));
temp = [];
});
</script>
</head>

<body>
<form class="game">
<table align="center" cellspacing="0" cellpadding="0">
<tr>
<td data-id="red"></td>
<td data-id="green"></td>
</tr>
<tr>
<td data-id="blue"></td>
<td data-id="orange"></td>
</tr>
</table>
</form>
</body>

</html>

Борис К
04.01.2022, 21:06
Рони... ну, что сказать?!
Гениально!
Низко склоняю седую голову и крепко жму руку!
Огромная благодарность за помощь и глубокое уважение за профессионализм!
Всего самого доброго в наступившем Новом году... и в жизни!)))

рони
04.01.2022, 21:31
Борис К,
:thanks: ... код можно сделать ещё интереснее, но лучше вы сами :lol:

Борис К
05.01.2022, 02:16
Рони, Вы обо мне хорошего мнения... но, к сожалению, я очень далёк от программирования(((
Условно можно было бы назвать мою незатейливую возню с JS время от времени хобби на склоне лет...
Но я непременно прислушаюсь к вашему совету и интуитивно поэкспериментирую с кодом. :-?
Спасибо Вам за всё хорошее!

Борис К
07.01.2022, 13:47
Рони, с Рождеством!
код можно сделать ещё интереснее
Следуя вашему совету, малость "поигрался" с последним кодом и обнаружил, что при увеличении количества ячеек в таблице перемешивание осуществляется не в полной мере... например, при таком варианте таблицы:

<table align="center" cellspacing="0" cellpadding="0">
<tr>
<td data-id="red"></td>
<td data-id="red"></td>
<td data-id="red"></td>
<td data-id="red"></td>
</tr>
<tr>
<td data-id="blue"></td>
<td data-id="blue"></td>
<td data-id="blue"></td>
<td data-id="blue"></td>
</tr>
<tr>
<td data-id="orange"></td>
<td data-id="orange"></td>
<td data-id="orange"></td>
<td data-id="orange"></td>
</tr>
<tr>
<td data-id="green"></td>
<td data-id="green"></td>
<td data-id="green"></td>
<td data-id="green"></td>
</tr>
</table>

Может быть, возможен какой-нибудь другой код для shuffle?)

рони
07.01.2022, 14:00
Борис К,
сделайте цикл для shuffle равный количеству клеток.

рони
07.01.2022, 14:16
Борис К,
или так ...
if ( event.random ||(x == 0 && y == 1) || (x == 1 && y == 0) || td === temp[0] )

Борис К
07.01.2022, 14:34
сделайте цикл для shuffle равный количеству клеток
Сделал так (может, и неправильно):

for (i = 0; i < 16; i++) {
tds.slice(0).sort(_ => Math.random() - .5)
.forEach(target => exch({
target,
random: true
}));
temp = [];
}

Заметно лучше!))
или так ...
if ( event.random ||(x == 0 && y == 1) || (x == 1 && y == 0) || td === temp[0] )И так попробовал... но через цикл для shuffle показалось лучше)
Рони, благодарю!

рони
07.01.2022, 14:44
Борис К,
let arr = tds.slice(0);
for (var i = 0; i < tds.length; i++) {
arr.sort(_ => Math.random() - .5)
.forEach(target => exch({
target,
random: true
}));
}
temp = [];

рони
07.01.2022, 14:59
Борис К,
на всякий случай https://javascript.ru/forum/events/83316-pomogite-reshit-zadachu.html#post541463

и вместо sort лучше менять пары при перемешивании, более равномерное перемешивание.

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<style type="text/css">
[data-id="red"] {
background-color: #ff0000;
width: 100px;
height: 100px;
}

[data-id="orange"] {
background-color: #ff9900;
width: 100px;
height: 100px;
}

[data-id="green"] {
background-color: #006600;
width: 100px;
height: 100px;
}

[data-id="blue"] {
background-color: #0000ff;
width: 100px;
height: 100px;
}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
let temp = [];
let form = document.querySelector(".game");
let tds = Array.from(form.querySelectorAll("[data-id]"));
let idEnd = tds.map(({
dataset: {
id
}
}) => id);
let win;

function exch(event) {
if (win) return;
let td = event.target.closest("[data-id]");
if (td) {
let cellIndex = td.cellIndex;
let rowIndex = td.closest("tr").rowIndex;
if (temp.length) {
let x = Math.abs(cellIndex - temp[1]);
let y = Math.abs(rowIndex - temp[2]);
if (event.random || (x == 0 && y == 1) || (x == 1 && y == 0) || td === temp[0]) {
[td.dataset.id, temp[0].dataset.id] = [temp[0].dataset.id, td.dataset.id]
temp = [];
}
} else {
temp = [td, cellIndex, rowIndex];
}
if (!event.random) win = tds.every(({
dataset: {
id
}
}, i) => id === idEnd[i]);
if (win) alert("Hello world!");
}
}
form.addEventListener("click", exch);
let arr = tds.slice(0), len = arr.length;
arr.forEach((_, i) => {
let a = Math.trunc(Math.random() * len);
[arr[i], arr[a]] = [arr[a], arr[i]];
});
arr.forEach(target => exch({
target,
random: true
}));
temp = [];
});
</script>
</head>

<body>
<form class="game">
<table align="center" cellspacing="0" cellpadding="0">
<tr>
<td data-id="red"></td>
<td data-id="red"></td>
<td data-id="red"></td>
<td data-id="red"></td>
</tr>
<tr>
<td data-id="blue"></td>
<td data-id="blue"></td>
<td data-id="blue"></td>
<td data-id="blue"></td>
</tr>
<tr>
<td data-id="orange"></td>
<td data-id="orange"></td>
<td data-id="orange"></td>
<td data-id="orange"></td>
</tr>
<tr>
<td data-id="green"></td>
<td data-id="green"></td>
<td data-id="green"></td>
<td data-id="green"></td>
</tr>
</table>
</form>
</body>

</html>

Борис К
07.01.2022, 15:07
Все варианты отлично работают!)))
на всякий случай https://javascript.ru/forum/events/8...tml#post541463

и вместо sort лучше менять пары при перемешивании, более равномерное перемешивание.Спасибо!
Рони, берегите, лелейте и цените себя!
Мои искренняя огромная благодарность, безграничное восхищение и глубокое уважение Вам!!!
:victory:

рони
07.01.2022, 15:13
Борис К,
убрал "лишнее" :)
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<style type="text/css">
[data-id="red"] {
background-color: #ff0000;
width: 100px;
height: 100px;
}

[data-id="orange"] {
background-color: #ff9900;
width: 100px;
height: 100px;
}

[data-id="green"] {
background-color: #006600;
width: 100px;
height: 100px;
}

[data-id="blue"] {
background-color: #0000ff;
width: 100px;
height: 100px;
}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
let temp = [];
let form = document.querySelector(".game");
let tds = Array.from(form.querySelectorAll("[data-id]"));
let idEnd = tds.map(({
dataset: {
id
}
}) => id);
let win;

function exch(event) {
if (win) return;
let td = event.target.closest("[data-id]");
if (td) {
let cellIndex = td.cellIndex;
let rowIndex = td.closest("tr").rowIndex;
if (temp.length) {
let x = Math.abs(cellIndex - temp[1]);
let y = Math.abs(rowIndex - temp[2]);
if ((x == 0 && y == 1) || (x == 1 && y == 0) || td === temp[0]) {
[td.dataset.id, temp[0].dataset.id] = [temp[0].dataset.id, td.dataset.id]
temp = [];
}
} else {
temp = [td, cellIndex, rowIndex];
}
win = tds.every(({
dataset: {
id
}
}, i) => id === idEnd[i]);
if (win) alert("Hello world!");
}
}
form.addEventListener("click", exch);
let color = idEnd.slice(0), len = color.length;
color.forEach((_, i) => {
let a = Math.trunc(Math.random() * len);
[color[i], color[a]] = [color[a], color[i]];
});
tds.forEach(({dataset}, i) => dataset.id = color[i]);
});
</script>
</head>

<body>
<form class="game">
<table align="center" cellspacing="0" cellpadding="0">
<tr>
<td data-id="red"></td>
<td data-id="red"></td>
<td data-id="red"></td>
<td data-id="red"></td>
</tr>
<tr>
<td data-id="blue"></td>
<td data-id="blue"></td>
<td data-id="blue"></td>
<td data-id="blue"></td>
</tr>
<tr>
<td data-id="orange"></td>
<td data-id="orange"></td>
<td data-id="orange"></td>
<td data-id="orange"></td>
</tr>
<tr>
<td data-id="green"></td>
<td data-id="green"></td>
<td data-id="green"></td>
<td data-id="green"></td>
</tr>
</table>
</form>
</body>

</html>

Борис К
07.01.2022, 15:40
убрал "лишнее"Я обязательно изучу изменения - это самый лучший способ учиться чему-то новому (никогда не поздно!)))
Роничка, СПАСИБО!!!

Борис К
12.01.2022, 14:19
Рони, а возможно сделать, чтобы в стилях были не ссылки на изображения, а текстовый контент в самом коде?
Я немного упростил код для удобства:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
[data-id="red"] {
background-image:url(https://placehold.co/200x100/ff0000/EEE?font=playfair-display&text=Hello);
width: 200px;
height: 100px;
}

[data-id="orange"] {
background-image:url(https://placehold.co/200x100/ff9900/EEE?font=playfair-display&text=Java);
width: 200px;
height: 100px;
}

[data-id="green"] {
background-image:url(https://placehold.co/200x100/006600/EEE?font=playfair-display&text=script!);
width: 200px;
height: 100px;
}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
let temp = [];
let form = document.querySelector(".game");
let tds = Array.from(form.querySelectorAll("[data-id]"));
let idEnd = tds.map(({
dataset: {
id
}
}) => id);
let win;

function exch(event) {
if (win) return;
let td = event.target.closest("[data-id]");
if (td) {
let cellIndex = td.cellIndex;
let rowIndex = td.closest("tr").rowIndex;
if (temp.length) {
let x = Math.abs(cellIndex - temp[1]);
let y = Math.abs(rowIndex - temp[2]);
if ((x == 0 && y == 1) || (x == 1 && y == 0) || td === temp[0]) {
[td.dataset.id, temp[0].dataset.id] = [temp[0].dataset.id, td.dataset.id]
temp = [];
}
} else {
temp = [td, cellIndex, rowIndex];
}
win = tds.every(({
dataset: {
id
}
}, i) => id === idEnd[i]);
if (win) alert("Hello JavaScript!");
}
}
form.addEventListener("click", exch);
let color = idEnd.slice(0), len = color.length;
color.forEach((_, i) => {
let a = Math.trunc(Math.random() * len);
[color[i], color[a]] = [color[a], color[i]];
});
tds.forEach(({dataset}, i) => dataset.id = color[i]);
});
</script>
</head>
<body>
<div class="block">
<form class="game">
<table align="center" cellspacing="0" cellpadding="0">
<tr>
<td data-id="red"></td>
<td data-id="orange"></td>
<td data-id="green"></td>
</tr>
</table>
</form>
</div>
</body>
</html>

рони
12.01.2022, 20:29
Борис К,
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<style type="text/css">
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600&display=swap');
.color {
background-color: var(--color);
width: 200px;
height: 100px;
text-align: center;
line-height: 100px;
}

.color:after {
display: block;
content: var(--txt);
color: #FFFFFF;
font-size: 48px;
font-family: 'Playfair Display', serif;
}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
let temp = [];
let form = document.querySelector(".game");
let tds = Array.from(form.querySelectorAll(".color"));
let colors = "#FF0000|#008000|#0000CD".split("|");
let txts = "Hello|Java|script".split("|");
let win;

function show() {
tds.forEach(td => {
let i = td.dataset.id;
td.style.setProperty("--color", colors[i]);
td.style.setProperty("--txt", `"${txts[i]}"`);
});
}

function randomId() {
win = false; temp = [];
let length = colors.length;
let ids = Array.from({
length
}, (v, i) => i);

ids.forEach((_, i) => {
let a = Math.trunc(Math.random() * length);
[ids[i], ids[a]] = [ids[a], ids[i]];
});
tds.forEach(({
dataset
}, i) => dataset.id = ids[i]);

show();
}
randomId()

function exch(event) {
if (win) return;
let td = event.target.closest(".color");
if (td) {
let cellIndex = td.cellIndex;
let rowIndex = td.closest("tr").rowIndex;
if (temp.length) {
let x = Math.abs(cellIndex - temp[1]);
let y = Math.abs(rowIndex - temp[2]);
if ((x == 0 && y == 1) || (x == 1 && y == 0) || td === temp[0]) {
[td.dataset.id, temp[0].dataset.id] = [temp[0].dataset.id, td.dataset.id];
show();
temp = [];
}
} else {
temp = [td, cellIndex, rowIndex];
}
win = tds.every(({
dataset: {
id
}
}, i) => id == i);
if (win) alert("Hello JavaScript!");
}
}
form.addEventListener("click", exch);

});
</script>
</head>

<body>
<div class="block">
<form class="game">
<table align="center" cellspacing="0" cellpadding="0">
<tr>
<td class="color"></td>
<td class="color"></td>
<td class="color"></td>
</tr>
</table>
</form>
</div>
</body>

</html>

Борис К
13.01.2022, 11:04
Огромная благодарность за понимание, гениальный Рони!
Круто... очень круто!!!
С наступающим Старым Новым годом, Профессионал!)))
P.S. Уже есть по коду вопросы, но я ещё не решаюсь их задать... пока поэкспериментирую самостоятельно. :write:

Борис К
17.01.2022, 14:06
:help:
Рони, а вообще возможно реализовать так, чтобы кроме 30-ой строки (let txts = "Hello|Java|script".split("|");) в вашем последнем коде, была бы, например, ещё такая - let txts = "Good|morning|forum".split("|");... ну, и соответственно, чтобы под это было alert("Good morning forum!");?
И чтобы кнопкой можно было менять текстовые сообщения с их обновлением без перезагрузки страницы...
P.S. Я самостоятельно за четверо суток не справился. :cray:

рони
17.01.2022, 15:24
Борис К,
не понимаю.

Борис К
17.01.2022, 16:24
Рони, если бы была не одна фраза для сборки, а несколько, которые сменялись бы рандомно кнопкой, и, соответственно, alert был бы каждый раз другой под свою фразу...

рони
17.01.2022, 17:57
Борис К,
кнопку, массив фраз, элемент для вывода сообщения, набросайте, пожалуйста...:(

Борис К
17.01.2022, 18:43
кнопку, массив фраз, элемент для вывода сообщения, набросайте, пожалуйста...Слушаюсь, Учитель!))
кнопку
<button id=""></button>
массив фраз
Hello Java script (уже есть в вашем коде)
Good morning forum
Roney good luck))
элемент для вывода сообщения
<p id="out"></p>
для
out.append("Hello Java script");
out.append("Good morning forum");
out.append("Roney good luck");

P.S. Надеюсь, правильно Вас понял.

рони
17.01.2022, 23:43
Борис К,
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<style type="text/css">
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600&display=swap');

body {
background-color: #D3D3D3
}

.block {
background-color: var(--color);
text-align: center;
line-height: 100px;
margin: var(--rip);
flex-basis: calc(100% / var(--cols) - var(--rip) * 2);
font-family: 'Playfair Display', serif;
color: #FFFFFF;
font-size: 48px;
}

.out:after {
content: var(--snippet);
}

.btn:after {
content: "init";
}

.game {
display: flex;
flex-wrap: wrap;
--cols: 3;
--gap: 2px;
--rip: calc(var(--gap) - 1px);
padding: var(--gap);
}

.game {
width: 700px;
margin: 40px auto;
}

.win .block {
background-image: linear-gradient(45deg, rgba(255, 255, 255, .0) 50%, rgba(255, 255, 255, .8), rgba(255, 255, 255, .0) 70%), radial-gradient(190% 100% at 50% 0%, rgba(255, 255, 255, .7) 0%, rgba(255, 255, 255, .5) 50%, rgba(0, 0, 0, 0) 50%);
box-sizing: border-box;
background-position: 200% 0, 0 0;
box-shadow: rgba(0, 0, 0, .3) 0 2px 5px;
background-repeat: no-repeat;
background-size: 200% 100%, auto;
animation: anim 3s linear infinite;
}

@keyframes anim {
from {
background-position: 200% 0, 0 0;
}

to {
background-position: -200% 0, 0 0;
}
}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
let snippets = `Hello Java script !
1 2 3 4 5 6 7 8 9 10 11 12
Good morning forum
Roney good luck`.split(/\n/);
let colors = [
'#0000FF', //blue
'#FFFF00', //yellow
'#008000', //green
'#FFA500', // orange
'#FF0000', //red
'#800080', //purple
'#808000', //olive
'#00FF00', //lime
'#800000', //maroon
'#00FFFF', //aqua
'#008080', //team
'#000080', //navy
'#FF00FF', //fushua
'#808080' //gray
];
let out = document.querySelector(".out");
let btn = document.querySelector(".btn")
let game = document.querySelector(".game");
let win = _ => true;
let temp = [];
let cols = 3;

function shuffle(array, elem) {
let length = array.length,
arr = array.slice(0);
const randomIndex = _ => Math.trunc(Math.random() * length);
let k = randomIndex();
if (elem) return arr[k];
arr.forEach((_, i) => {
k = randomIndex();
[arr[i], arr[k]] = [arr[k], arr[i]];
});
return arr;
}
// rule
let [a, b] = [0, 1];

function rule(x, y) {
return a == x && b == y
}

function exch(event) {
if (win()) return;
let block = event.target.closest(".block");
if (block) {
let i = block.style.order;
let [c, d] = [i % cols, i / cols | 0];
if (temp.length) {
let x = Math.abs(c - temp[1]);
let y = Math.abs(d - temp[2]);
if (x > y)[x, y] = [y, x];
let move = rule(x, y);
if (move || block === temp[0]) {
[block.style.order, temp[0].style.order] = [temp[0].style.order, block.style.order];
temp = [];
}
} else {
temp = [block, c, d];
};
win()
}
}
game.addEventListener("click", exch);

function createContent() {
if (!win()) return;
temp = [];
let snippet = shuffle(snippets, true).trim();
let words = snippet.split(/\s+/);
let len = words.length;
cols = len > 5 ? 3 : len;
let bgColor = shuffle(colors);
out.style.setProperty("--snippet", `"collect ${snippet}"`);
let div = document.createElement('div');
div.classList.add('block');
let content = words.map((word, i) => {
let elem = div.cloneNode();
elem.textContent = word;
elem.style.setProperty("--color", bgColor[i % bgColor.length]);
return elem;
});
shuffle(content).forEach(({
style
}, i) => style.order = i);
game.classList.remove("win")
game.innerHTML = "";
game.style.setProperty("--cols", cols);
game.append(...content);
win = _ => {
let validate = content
.every(({
style: {
order
}
}, i) => order == i);
if (validate) {
out.style.setProperty("--snippet", `"${snippet} right!!! More? click init"`);
game.classList.add("win")
}
return validate
}
}
btn.addEventListener("click", createContent);
createContent()
});
</script>
<title></title>
</head>

<body>
<p class="out"></p>
<div class="game"></div>
<button class="btn"></button>
</body>

</html>

Борис К
18.01.2022, 12:23
"Я влюбился в программиста
За его талант - так быстро
Рони создал чудо-код,
Аж душа моя поёт!"

© Борис К.
:dance:

Борис К
22.01.2022, 13:53
Рони, сдаюсь!(((
Возможно ли сделать так, чтобы ячейки располагались просто одна под другой?
А чтобы текст в одной ячейке состоял из двух слов, например, "turn on"?
P.S. Я самостоятельно за несколько суток решение так и не нашёл(((((

рони
22.01.2022, 14:57
чтобы ячейки располагались просто одна под другой?
А чтобы текст в одной ячейке состоял из двух слов, например, "turn on"?

:-?
строки 141 - 143
let words = snippet.match(/\S+(\s+\S+)?/g);
let len = words.length;
cols = 1;

Борис К
22.01.2022, 15:41
Спасибо, Рони... Спасибо!
:dance:
Уже разбираюсь... поэтому есть вопрос: например, возможно ли по ячейкам разбить, например, следующее предложение со структурой (2/1/2):
"Forum JavaScript
loves
mister Roney"
?
И я так понимаю, что, например, другое предложение с другой структурой (1/2/1):
"I
very love
JavaScript"
уже не получится так разбить по ячейкам при тех же строках в коде?((

рони
22.01.2022, 16:27
Борис К,
что вам мешает разбить, как нужно изначально? может про массивы почитать?

Борис К
22.01.2022, 16:39
что вам мешает разбить, как нужно изначально?
Видимо, нехватка знаний и... здоровья(((
может про массивы почитать?
Виноват(( Понял, уже смотрю "Массивы" и "Методы массивов"...
Но мне вашего мастерства, увы, не достичь...
Но что делать? Буду стараться хоть что-то освоить!

рони
22.01.2022, 16:56
Борис К,
let snippets = [["1", "2", "3"], ["Но что " ,"делать?"], ["что вам мешает", "разбить, как нужно ", "изначально?"]];
...
let words = shuffle(snippets, true);
let snippet = words.join("");
cols = 1;

Борис К
22.01.2022, 17:47
Да, дорогой Рони, теперь всё работает как надо!)))
:dance:
Повторюсь... Рони, Вы - лучший из лучших!
Гений!!! Да, и не спорьте!))

рони
22.01.2022, 20:35
Борис К,
а лучше так)))

let snippets = [{words : ["1", "2", "3", "4"], cols : 2}, {words : ["Но что " ,"делать?"], cols : 1}, {words : ["что вам мешает ", "разбить, как нужно ", "изначально?"], cols : 1}];

...

let {words, cols : cols} = shuffle(snippets, true);
let snippet = words.join("");

Борис К
22.01.2022, 21:11
а лучше так)))Рони, всё безупречно работает!)))
Но моя "фантазия" несёт меня дальше... остановите меня!))
Рони, просто, пожалуйста, ответьте, возможно ли в принципе сделать так, чтобы изначально звучала фраза аудиофайлом, которая будет представлена, и по завершению интеракции опять? Практически это реально реализовать? Чтобы я зря не ломал себе голову ещё полмесяца...
P.S. Благодаря лично Вам, я подобное научился делать с другим более понятным кодом))

рони
22.01.2022, 21:16
Борис К,
я пас.

Борис К
22.01.2022, 22:08
Рони, видимо, Вы меня неправильно поняли - меня интересовало возможно ли это реализовать в принципе...
Но Спасибо Вам!!!

рони
22.01.2022, 22:45
возможно ли

{words : ["1", "2", "3", "4"], cols : 2, audio : "..."}

https://javascript.ru/forum/misc/77961-vosproizvedenie-muzyki-na-sajjte-s-prervannogo-mesta-2.html#post510003

Борис К
23.01.2022, 00:10
Рони, заменил {words : ["1", "2", "3", "4"], cols : 2, audio : "..."} на {words : ["1", "2", "3", "4"], cols : 2, audio : "https://www.w3schools.com/tags/horse.mp3"}
Но аудио-эффекта никакого нет(((
И почему-то ячейки с цифрами тоже до конца некорректно работают... буду разбираться.
Ну, ладно... извините!

рони
23.01.2022, 00:23
Рони, заменил
кнопочку audio надо создать, а на эту кнопку повесить запуск звука, а звук брать из свойства audio : ...
https://www.w3schools.com/jsref/met_audio_play.asp

https://www.w3schools.com/jsref/dom_obj_audio.asp

Борис К
23.01.2022, 00:32
Спасибо, Рони!
Буду понемногу разбираться...