Я написал на JavaScript функции добавления и удаления элементов на странице, но я очень часто обращаюсь к документу, пример:
task = document.querySelectorAll('.task')
И также я в любой ситуации получаю все данные из массива элементов, которые я получил через querySelector
. Могу ли я в такой массив, через который я выбрал элементы, добавить элемент, созданный с помощью createElement
?
Я очень не хочу лишний раз обращаться к document
, хочу писать качественный код, поэтому меня это интересует, а сам не понимаю как это написать.
let task, tasks, task__close;
let add__button = document.querySelector('.add__button');
let add__input = document.querySelector('.add__input');
let arr = [];
tasks = document.querySelector('.tasks');
task = document.querySelectorAll('.task');
function addElem() {
if (add__input.value === '') {
return false;
}
let block = document.createElement('div');
task = document.querySelectorAll('.task');
block.className = 'task';
arr = [];
for (let i = 0; i < task.length; i++) {
arr.unshift(task[i].getAttribute('data-id'));
}
arr.sort(function(a, b) {
return a - b;
});
let num = addNext(arr);
block.setAttribute('data-id', num);
block.setAttribute('data-listener', false);
block.innerHTML = '<div class="task__close"></div>';
block.innerHTML += add__input.value;
tasks.prepend(block);
add__input.value = '';
task__close = document.querySelector('.task__close');
task = document.querySelectorAll('.task');
startClose();
} // function addElem()
function startClose() {
task__close = document.querySelectorAll('.task__close');
for (let i = 0; i < task.length; i++) {
if (task[i].getAttribute('data-listener') == 'false') {
task__close[i].addEventListener('click', (event) => {
event.path[1].remove();
});
task[i].setAttribute('data-listener', true);
}
}
} // function startClose()
add__button.addEventListener('click', () => {
addElem();
});
add__input.addEventListener('keydown', (event) => {
if (event.code == 'Enter' || event.keyCode == '13' || event.key == 'Enter') {
addElem();
}
});
startClose();
function addNext(arr) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] != i) {
arr.splice(i, 0, i);
return i;
}
}
arr.push(arr.length);
return arr.length - 1;
}
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700&display=swap');
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
padding: 0;
font-size: 16px;
font-family: 'Open Sans', sans-serif;
color: black;
}
h1,
h2,
h3,
h4,
h5,
h6,
ul {
margin: 0;
}
ul {
list-style: none;
}
img {
display: block;
max-width: 100%;
height: auto;
}
.container {
max-width: 1100px;
width: 100%;
margin: 0 auto;
}
.container.fluid {
max-width: 100%;
}
.spheres {
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
}
.sphere {
border-right: 1px solid black;
flex-grow: 1;
padding: 15px 0;
}
.sphere:first-child {
border-left: 1px solid black;
}
.sphere .svg__icon {
max-width: 70px;
margin: 0 auto;
}
.sphere .svg__icon img {
width: 100%;
}
.sphere__title {
text-align: center;
margin-top: 10px;
font-size: 20px;
}
.add {
background-color: #46a049;
padding: 25px 0;
}
.add__title {
font-size: 22px;
text-align: center;
color: white;
}
.add__input-wrapper {
position: relative;
max-width: 500px;
margin: 10px auto 0;
padding: 0 15px;
}
.add__input {
outline: 0;
font-family: inherit;
font-size: inherit;
border: 1px solid white;
display: block;
border-radius: 5px;
padding: 7px 55px 7px 20px;
width: 100%;
}
.add__button {
position: absolute;
top: 50%;
right: 15px;
transform: translate(0, -50%);
width: 50px;
height: 50px;
}
.add__button:before {
position: absolute;
display: block;
content: '';
top: 50%;
transform: translate(-40%, -50%) rotate(90deg);
width: 2px;
background-color: #91a8c4;
height: 20px;
right: 40%;
}
.add__button:after {
position: absolute;
display: block;
content: '';
top: 50%;
transform: translate(-40%, -50%);
width: 2px;
background-color: #91a8c4;
height: 20px;
right: 40%;
}
.add__button:hover {
cursor: pointer;
}
.add__button:hover:before {
background-color: #3675bc;
}
.add__button:hover:after {
background-color: #3675bc;
}
.tasks {
margin-top: 20px;
padding: 0 20px;
}
.task {
position: relative;
border-bottom: 2px solid #f0f0f0;
padding: 10px 0;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
}
.task__close {
width: 20px;
height: 20px;
border: 1px solid gray;
border-radius: 50%;
margin-right: 15.5px;
position: relative;
}
.task__close:before {
position: absolute;
display: block;
content: '';
right: 6px;
top: 3px;
transform: rotate(45deg);
width: 5px;
height: 10px;
border-bottom: 1px solid rgba(128, 128, 128, 0.8);
border-right: 1px solid rgba(128, 128, 128, 0.8);
opacity: 0;
transition: .2s linear opacity;
}
.task__close:hover {
background-color: rgba(128, 128, 128, 0.2);
cursor: pointer;
}
.task__close:hover:before {
opacity: 1;
}
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Document</title>
</head>
<body>
<section class="section">
<div class="container">
<div class="spheres">
<div class="sphere health">
<div class="svg__icon">
<img src="https://image.flaticon.com/icons/svg/148/148838.svg" alt="">
</div>
<div class="sphere__title">
Здоровье
</div>
</div>
<div class="sphere intelligence">
<div class="svg__icon">
<img src="https://image.flaticon.com/icons/svg/1491/1491214.svg" alt="">
</div>
<div class="sphere__title">
Развитие
</div>
</div>
<div class="sphere sociality">
<div class="svg__icon">
<img src="https://image.flaticon.com/icons/svg/1078/1078011.svg" alt="">
</div>
<div class="sphere__title">
Отношения
</div>
</div>
</div>
<!-- .spheres -->
</div>
<!-- .container -->
<div class="container fluid">
<div class="add">
<div class="add__title">
Добавить задачу
</div>
<div class="add__input-wrapper">
<input type="text" placeholder="Бег 1 км" class="add__input">
<div class="add__button"></div>
</div>
</div>
</div>
<!-- .container.fluid -->
<div class="container">
<div class="tasks">
<div class="task" data-id="0" data-listener='false'>
<div class="task__close"></div>
Моя первая задача
</div>
</div>
</div>
<!-- .container -->
</section>
</body>
</html>
Предлагаю для начала преобразовать task в обычный массив, далее потом при создании нового блока task мы добавляем его в массив, методом push и сразу же цепляем обработчик закрытия task на task__close, избегая лишний раз вызова функции startClose()
let task, tasks, task__close;
let add__button = document.querySelector('.add__button');
let add__input = document.querySelector('.add__input');
let arr = [];
tasks = document.querySelector('.tasks');
task = [...document.querySelectorAll('.task')];
function addElem() {
if (add__input.value === '') {
return false;
}
let block = document.createElement('div');
block.className = 'task';
arr = [];
for (let i = 0; i < task.length; i++) {
arr.unshift(task[i].getAttribute('data-id'));
}
arr.sort(function(a,b){
return a - b;
});
let num = addNext(arr);
block.setAttribute('data-id', num);
block.setAttribute('data-listener', false);
block.innerHTML = '<div class="task__close"></div>';
block.innerHTML += add__input.value;
task.push(block);
tasks.prepend(block);
add__input.value = '';
block.querySelector('.task__close').addEventListener('click', (event) => {
event.path[1].remove();
});
//task__close = document.querySelector('.task__close');
//startClose();
} // function addElem()
function startClose() {
task__close = document.querySelectorAll('.task__close');
for (let i = 0; i < task.length; i++) {
if (task[i].getAttribute('data-listener') == 'false') {
task__close[i].addEventListener('click', (event) => {
event.path[1].remove();
});
task[i].setAttribute('data-listener', true);
}
}
} // function startClose()
add__button.addEventListener('click', () => {
addElem();
});
add__input.addEventListener('keydown', (event) => {
if (event.code == 'Enter' || event.keyCode == '13' || event.key == 'Enter') {
addElem();
}
});
startClose();
function addNext(arr) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] != i) {
arr.splice(i, 0, i);
return i;
}
}
arr.push(arr.length);
return arr.length - 1;
}
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700&display=swap');
*, *:before, *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html{
scroll-behavior: smooth;
}
body {
margin: 0;
padding: 0;
font-size: 16px;
font-family: 'Open Sans', sans-serif;
color: black;
}
h1, h2, h3, h4, h5, h6, ul {
margin: 0;
}
ul {
list-style: none;
}
img {
display: block;
max-width: 100%;
height: auto;
}
.container {
max-width: 1100px;
width: 100%;
margin: 0 auto;
}
.container.fluid {
max-width: 100%;
}
.spheres {
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
}
.sphere {
border-right: 1px solid black;
flex-grow: 1;
padding: 15px 0;
}
.sphere:first-child {
border-left: 1px solid black;
}
.sphere .svg__icon {
max-width: 70px;
margin: 0 auto;
}
.sphere .svg__icon img {
width: 100%;
}
.sphere__title {
text-align: center;
margin-top: 10px;
font-size: 20px;
}
.add {
background-color: #46a049;
padding: 25px 0;
}
.add__title {
font-size: 22px;
text-align: center;
color: white;
}
.add__input-wrapper {
position: relative;
max-width: 500px;
margin: 10px auto 0;
padding: 0 15px;
}
.add__input {
outline: 0;
font-family: inherit;
font-size: inherit;
border: 1px solid white;
display: block;
border-radius: 5px;
padding: 7px 55px 7px 20px;
width: 100%;
}
.add__button {
position: absolute;
top: 50%;
right:15px;
transform: translate(0, -50%);
width: 50px;
height: 50px;
}
.add__button:before {
position: absolute;
display: block;
content: '';
top: 50%;
transform: translate(-40%, -50%) rotate(90deg);
width: 2px;
background-color: #91a8c4;
height: 20px;
right: 40%;
}
.add__button:after {
position: absolute;
display: block;
content: '';
top: 50%;
transform: translate(-40%, -50%);
width: 2px;
background-color: #91a8c4;
height: 20px;
right: 40%;
}
.add__button:hover {
cursor: pointer;
}
.add__button:hover:before {
background-color: #3675bc;
}
.add__button:hover:after {
background-color: #3675bc;
}
.tasks {
margin-top: 20px;
padding: 0 20px;
}
.task {
position: relative;
border-bottom: 2px solid #f0f0f0;
padding: 10px 0;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
}
.task__close {
width: 20px;
height: 20px;
border: 1px solid gray;
border-radius: 50%;
margin-right: 15.5px;
position: relative;
}
.task__close:before {
position: absolute;
display: block;
content: '';
right: 6px;
top: 3px;
transform: rotate(45deg);
width: 5px;
height: 10px;
border-bottom: 1px solid rgba(128,128,128,0.8);
border-right: 1px solid rgba(128,128,128,0.8);
opacity: 0;
transition: .2s linear opacity;
}
.task__close:hover {
background-color: rgba(128,128,128,0.2);
cursor: pointer;
}
.task__close:hover:before {
opacity: 1;
}
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Document</title>
</head>
<body>
<section class="section">
<div class="container">
<div class="spheres">
<div class="sphere health">
<div class="svg__icon">
<img src="https://image.flaticon.com/icons/svg/148/148838.svg" alt="">
</div>
<div class="sphere__title">
Здоровье
</div>
</div>
<div class="sphere intelligence">
<div class="svg__icon">
<img src="https://image.flaticon.com/icons/svg/1491/1491214.svg" alt="">
</div>
<div class="sphere__title">
Развитие
</div>
</div>
<div class="sphere sociality">
<div class="svg__icon">
<img src="https://image.flaticon.com/icons/svg/1078/1078011.svg" alt="">
</div>
<div class="sphere__title">
Отношения
</div>
</div>
</div> <!-- .spheres -->
</div> <!-- .container -->
<div class="container fluid">
<div class="add">
<div class="add__title">
Добавить задачу
</div>
<div class="add__input-wrapper">
<input type="text" placeholder="Бег 1 км" class="add__input">
<div class="add__button"></div>
</div>
</div>
</div> <!-- .container.fluid -->
<div class="container">
<div class="tasks">
<div class="task" data-id="0" data-listener='false'>
<div class="task__close"></div>
Моя первая задача
</div>
</div>
</div> <!-- .container -->
</section>
</body>
</html>
Я сделал код, который правильно выставляет data-id
элементам .task
, правда при удалении элемента, data-id
как-то случайно проставляются, но работает всё правильно.
let task, tasks, task__close;
let add__button = document.querySelector('.add__button');
let add__input = document.querySelector('.add__input');
let arr = [];
tasks = document.querySelector('.tasks');
task = [...tasks.querySelectorAll('.task')];
function addElem() {
if (add__input.value === '') {
return false;
}
let block = document.createElement('div');
block.className = 'task';
arr = [];
for (let i = 0; i < task.length; i++) {
arr.unshift(task[i].getAttribute('data-id'));
}
arr.sort(function(a,b){
return a - b;
});
let num = addNext(arr);
block.setAttribute('data-id', num);
block.setAttribute('data-listener', false);
block.innerHTML = '<div class="task__close"></div>';
block.innerHTML += add__input.value;
task.unshift(block);
tasks.prepend(block);
add__input.value = '';
startClose();
} // function addElem()
function startClose() {
task__close = tasks.querySelectorAll('.task__close');
for (let i = 0; i < task.length; i++) {
if (task[i].getAttribute('data-listener') == 'false') {
task__close[i].addEventListener('click', (event) => {
let id = event.path[1].getAttribute('data-id');
task.splice(id, 1);
for (let i = 0; i < task.length; i++) {
task[i].setAttribute('data-id', i);
}
event.path[1].remove();
});
task[i].setAttribute('data-listener', true);
}
}
} // function startClose()
add__button.addEventListener('click', () => {
addElem();
});
add__input.addEventListener('keydown', (event) => {
if (event.code == 'Enter' || event.keyCode == '13' || event.key == 'Enter') {
addElem();
}
});
startClose();
function addNext(arr) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] != i) {
arr.splice(i, 0, i);
return i;
}
}
arr.push(arr.length);
return arr.length - 1;
}
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700&display=swap');
*, *:before, *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html{
scroll-behavior: smooth;
}
body {
margin: 0;
padding: 0;
font-size: 16px;
font-family: 'Open Sans', sans-serif;
color: black;
}
h1, h2, h3, h4, h5, h6, ul {
margin: 0;
}
ul {
list-style: none;
}
img {
display: block;
max-width: 100%;
height: auto;
}
.container {
max-width: 1100px;
width: 100%;
margin: 0 auto;
}
.container.fluid {
max-width: 100%;
}
.spheres {
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
}
.sphere {
border-right: 1px solid black;
flex-grow: 1;
padding: 15px 0;
}
.sphere:first-child {
border-left: 1px solid black;
}
.sphere .svg__icon {
max-width: 70px;
margin: 0 auto;
}
.sphere .svg__icon img {
width: 100%;
}
.sphere__title {
text-align: center;
margin-top: 10px;
font-size: 20px;
}
.add {
background-color: #46a049;
padding: 25px 0;
}
.add__title {
font-size: 22px;
text-align: center;
color: white;
}
.add__input-wrapper {
position: relative;
max-width: 500px;
margin: 10px auto 0;
padding: 0 15px;
}
.add__input {
outline: 0;
font-family: inherit;
font-size: inherit;
border: 1px solid white;
display: block;
border-radius: 5px;
padding: 7px 55px 7px 20px;
width: 100%;
}
.add__button {
position: absolute;
top: 50%;
right:15px;
transform: translate(0, -50%);
width: 50px;
height: 50px;
}
.add__button:before {
position: absolute;
display: block;
content: '';
top: 50%;
transform: translate(-40%, -50%) rotate(90deg);
width: 2px;
background-color: #91a8c4;
height: 20px;
right: 40%;
}
.add__button:after {
position: absolute;
display: block;
content: '';
top: 50%;
transform: translate(-40%, -50%);
width: 2px;
background-color: #91a8c4;
height: 20px;
right: 40%;
}
.add__button:hover {
cursor: pointer;
}
.add__button:hover:before {
background-color: #3675bc;
}
.add__button:hover:after {
background-color: #3675bc;
}
.tasks {
margin-top: 20px;
padding: 0 20px;
}
.task {
position: relative;
border-bottom: 2px solid #f0f0f0;
padding: 10px 0;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
}
.task__close {
width: 20px;
height: 20px;
border: 1px solid gray;
border-radius: 50%;
margin-right: 15.5px;
position: relative;
}
.task__close:before {
position: absolute;
display: block;
content: '';
right: 6px;
top: 3px;
transform: rotate(45deg);
width: 5px;
height: 10px;
border-bottom: 1px solid rgba(128,128,128,0.8);
border-right: 1px solid rgba(128,128,128,0.8);
opacity: 0;
transition: .2s linear opacity;
}
.task__close:hover {
background-color: rgba(128,128,128,0.2);
cursor: pointer;
}
.task__close:hover:before {
opacity: 1;
}
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Document</title>
</head>
<body>
<section class="section">
<div class="container">
<div class="spheres">
<div class="sphere health">
<div class="svg__icon">
<img src="https://image.flaticon.com/icons/svg/148/148838.svg" alt="">
</div>
<div class="sphere__title">
Здоровье
</div>
</div>
<div class="sphere intelligence">
<div class="svg__icon">
<img src="https://image.flaticon.com/icons/svg/1491/1491214.svg" alt="">
</div>
<div class="sphere__title">
Развитие
</div>
</div>
<div class="sphere sociality">
<div class="svg__icon">
<img src="https://image.flaticon.com/icons/svg/1078/1078011.svg" alt="">
</div>
<div class="sphere__title">
Отношения
</div>
</div>
</div> <!-- .spheres -->
</div> <!-- .container -->
<div class="container fluid">
<div class="add">
<div class="add__title">
Добавить задачу
</div>
<div class="add__input-wrapper">
<input type="text" placeholder="Бег 1 км" class="add__input">
<div class="add__button"></div>
</div>
</div>
</div> <!-- .container.fluid -->
<div class="container">
<div class="tasks">
<div class="task" data-id="0" data-listener='false'>
<div class="task__close"></div>
Моя первая задача
</div>
</div>
</div> <!-- .container -->
</section>
</body>
</html>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Хотелось сделать красивую функцию, чтобы можно было одной "цепочкой" вызовов создать и вернуть вложенные HTML-элементыВызовы функций получились...
при нажатии на верхний ряд или нижний, выдает ошибку (Uncaught TypeError: Cannot read property '3' of undefined), и кубик не передвигается