Как выводить значения в output при нажатии на элемент js?
Есть "счётная доска":
Нужно, чтобы выводились значения в поля по нажатию на фишки. Слева, значение набранное на каждой спице. Сверху - результат (сумма набранных фишек на каждой спице). При повторном нажатии на фишки нужно обнулить поля. Пыталась сделать по примеру калькулятора, но не получается то, что нужно..
const container = document.querySelector('.container');
const rows = container.querySelectorAll('.row');
rows.forEach(r => r.querySelectorAll('.fishka').forEach((el, i) => el.dataset.index = i));
container.addEventListener('click', (e) => {
const target = e.target;
if (!target.classList.contains('fishka')) return;
const row = target.parentNode;
const currentIndex = Number(target.dataset.index);
const isLeft = target.classList.contains('left');
const moveElements = [target];
const [direction, limit] = isLeft ? [1, row.children.length] : [-1, -1];
for (let i = currentIndex + direction; i !== limit; i += direction) {
const el = row.children[i];
if (el.classList.contains('left') === isLeft) {
moveElements.push(el);
continue;
}
break;
}
for (const el of moveElements) el.classList.toggle('left', !isLeft);
});
html{
scroll-behavior: smooth;
}
body {
padding: 0;
margin: 0;
font-family: 'Montserrat', sans-serif;
font-size: 16px;
line-height: 1.5;
background-color: #777;
}
section {
padding-top: 113px;
}
.container {
align-items: flex-end;
flex-direction: column;
width: 781.13px;
height: 933.96px;
/*позиционирование по центру*/
margin: 0 auto;
justify-content: center;
display: block;
}
.pole{
background: url('../img/1.svg') no-repeat center top / cover;
width: 900px;
height: 1052.83px;
text-align: center;
margin: auto;
position: relative;
margin-top: -50px;
}
.row {
margin-top: -10px;
margin-bottom: 15px;
display: flex;
float: right;
margin-right: 20px;
}
.fishka{
overflow: auto;
}
.fishka:hover {
cursor: grabbing;
}
.left {
transform: translateX(-260px);
}
.menu{
top: -80px;
display: flex;
text-align: center;
margin: auto;
position: relative;
margin: 0 auto;
justify-content: center;
overflow: auto;
}
.sum{
box-sizing: border-box;
width: 511px;
height: 64px;
background: #DAB26A;
border: 3px solid #96683B;
box-shadow: 0px 4px 4px #96683B;
border-radius: 20px;
text-align: center;
font-family: 'Roboto';
font-style: normal;
font-weight: 600;
font-size: 48px;
line-height: 56px;
color: #F9F9F9;
}
button {
outline: none;
border: 0;
background: transparent;
margin-left: 30px;
}
.result{
float: left;
display: flex;
flex-direction: column;
}
.outputs {
box-sizing: border-box;
width: 69px;
height: 64px;
background: #DAB26A;
border: 3px solid #96683B;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
border-radius: 20px;
margin-left: 200px;
margin-top: -60px;
margin-bottom: 80px;
font-family: 'Roboto';
font-style: normal;
font-weight: 600;
font-size: 48px;
line-height: 56px;
text-align: center;
color: #F9F9F9;
}
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="css/style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.."></script>
</head>
<body>
<section id="menu" class="menu">
<output name="result" class="sum"></output>
<button><img src="img/обновить.svg" alt="Кнопка сброса" id="btnup"></button>
</section>
<section class="result">
<output name="spica_1" value="" class="outputs" id="spica_1"></output>
<output name="spica_2" value="" class="outputs" id="spica_2"></output>
</section>
<section id="pole" class="pole">
<div class="container">
<div class="row">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/тёмная.svg" alt="fishka" class="fishka">
<img src="img/тёмная.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
</div>
<div class="row">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/тёмная.svg" alt="fishka" class="fishka">
<img src="img/тёмная.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
<img src="img/светлая.svg" alt="fishka" class="fishka">
</div>
</div>
</section>
</body>
</html>
Ответы (1 шт):
Используйте data-атрибуты для каждой строки счётной доски. Так мы можем установить множитель (вес разряда), а также атрибут для количества костяшек. Соответственно, сумма по строке будет перемножением этих атрибутов. Общий итог вычисляем как сумма рассчитанных значений по каждой строке.
В примере ниже я использовал flex для строк, включая возможность группировки через "margin-left: auto" для разделения костяшек, и data-атрибуты:
let rows = document.querySelector('.rows');
rows.onclick = e => {
let tar = e.target;
if (tar.classList.contains('fishka')) {
let row = tar.closest('.row');
let sep = row.querySelector('.separator');
let taken = +row.dataset.taken;
let index = +tar.dataset.idx;
if (sep) sep.classList.remove('separator');
let newIdx = index + (index >= taken);
let newSep = row.querySelector(`.fishka[data-idx="${newIdx}"]`);
if (newSep) newSep.classList.add('separator');
row.dataset.taken = newIdx;
calcRowSum(row);
}
}
function calcRowSum(row) {
let output = row.previousElementSibling;
output.value = row.dataset.taken * row.dataset.mult;
calcTotal();
}
function calcTotal() {
let rowSums = [...document.querySelectorAll('.row-sum')];
total.value = rowSums.reduce((a, v) => +v.value + a, 0);
}
.row {
display: flex;
height: 40px;
border: 1px solid gray;
gap: 10px;
}
.fishka {
width: 20px;
background: blue;
cursor: pointer;
}
.separator {
margin-left: auto;
}
#total {
display: inline-block;
border: 1px solid blue;
font-size: 150%;
}
<div>
<output name="total" id="total">0</output>
</div>
<hr>
<div class="rows">
<output class="row-sum">0</output>
<div class="row" data-taken="0" data-mult="10">
<div class="fishka separator" data-idx="0"></div>
<div class="fishka" data-idx="1"></div>
<div class="fishka" data-idx="2"></div>
<div class="fishka" data-idx="3"></div>
<div class="fishka" data-idx="4"></div>
<div class="fishka" data-idx="5"></div>
<div class="fishka" data-idx="6"></div>
<div class="fishka" data-idx="7"></div>
<div class="fishka" data-idx="8"></div>
<div class="fishka" data-idx="9"></div>
</div>
<output class="row-sum">0</output>
<div class="row" data-taken="0" data-mult="1">
<div class="fishka separator" data-idx="0"></div>
<div class="fishka" data-idx="1"></div>
<div class="fishka" data-idx="2"></div>
<div class="fishka" data-idx="3"></div>
<div class="fishka" data-idx="4"></div>
<div class="fishka" data-idx="5"></div>
<div class="fishka" data-idx="6"></div>
<div class="fishka" data-idx="7"></div>
<div class="fishka" data-idx="8"></div>
<div class="fishka" data-idx="9"></div>
</div>
<output class="row-sum">0</output>
<div class="row" data-taken="0" data-mult="0.25">
<div class="fishka separator" data-idx="0"></div>
<div class="fishka" data-idx="1"></div>
<div class="fishka" data-idx="2"></div>
<div class="fishka" data-idx="3"></div>
</div>
</div>
