document.querySelectorAll('tbody > tr').forEach(n => n.parentNode.prepend(n));
// или
const tbody = document.querySelector('tbody');
tbody.append(...Array.from(tbody.children).reverse());
// или
for (const n of [...document.querySelector('tbody').rows].reverse()) {
n.parentNode.appendChild(n);
}
// или
const tbody = document.querySelector('tbody');
for (let i = tbody.rows.length; i--;) {
tbody.insertAdjacentElement('beforeend', tbody.rows[i]);
}
Как из этого массива, создать новый массив, и чтобы в нем были значения из массива user, что-то типа такого массива должно получиться res = [5,12,2,22,'5,23',cost,'5',numbers,1,5,33,count,props,4,area,7];
const toArray = val =>
val instanceof Object
? [].concat(...(val instanceof Array
? val
: Object.entries(val)
).map(toArray))
: [ val ];
const res = toArray(user);
Есть ли способ для снятия чекбоксов таким же способом, если делать по аналогии выходит коряво ?
вот аналогия и вот почему коряво
https://codepen.io/sasha1998dmitalex/pen/OZbyYo
Причем, если поле уже чем-то уже заполнено по умолчанию, то этот текст уже должен быть транслирован в параграф. Так-что ввод с клавиатуры отслеживать не подходит.
$('input').on('input', function() {
$('p').text($(this).val());
}).trigger('input');
// или
const input = document.querySelector('input');
const p = document.querySelector('p');
input.addEventListener('input', e => p.textContent = e.target.value);
input.dispatchEvent(new Event('input'));
что делать, если параграф содержит текст по умолчанию, который должен отображаться пока в поле ввода не начали что-то вводить?
Проще говоря, когда инпут пустой, надо отображать текст параграфа.
<p data-default-text="Текст по умолчанию"></p>
.$('p').text($(this).val() || $('p').data('default-text'));
// или
p.textContent = e.target.value || p.dataset.defaultText
const grouped = data
.reduce((acc, n, i, a) => {
if (i && n.id === a[i - 1].id + 1) {
acc[acc.length - 1][1][1] = n.id;
} else {
acc.push([ [], [ n.id ] ]);
}
acc[acc.length - 1][0].push(n);
return acc;
}, [])
.reduce((acc, n) => {
acc[n[1].join('-')] = n[0];
return acc;
}, {});
$('input').on('input', function() {
const
$this = $(this),
newVal = +$this.val(),
oldVal = +$this.data('oldVal') || 0;
if (oldVal !== newVal) {
console.log(`новое ${['больше', 'меньше'][+(oldVal > newVal)]}`);
}
$this.data('oldVal', newVal);
});
Как я понимаю, при клике я каждый раз вызываю функцию и переменная val опять принимает значение равное нулю?
.value-btn-plus
и .value-btn-minus
, сами обработчики срабатывают в порядке подключения, поэтому в value-text
последним будет записано значение val, к которому имеет доступ последний же подключенный обработчик - т.е. 0, или что там у вас.$(document).on('click', '.value-btn-plus, .value-btn-minus', function() {
const $this = $(this);
const change = $this.hasClass('value-btn-plus') ? 1 : -1;
$this
.closest('.input-box')
.find('.value-text')
.text((i, text) => Math.max(0, +text + change));
});
document.addEventListener('click', ({ target: t }) => {
const change =
t.classList.contains('value-btn-plus') ? 1 :
t.classList.contains('value-btn-minus') ? -1 :
0;
if (change) {
const valueEl = t.closest('.input-box').querySelector('.value-text');
valueEl.innerText = Math.max(0, +valueEl.innerText + change);
}
});
new RegExp('^\\d+$')
const numberValidator = str => /^\d+$/.test(str);
// можно и наоборот - вместо проверки, что все символы являются цифрами,
// убедиться, что отсутствует хотя бы один не являющийся цифрой
const numberValidator = str => !/\D/.test(str);
Про let слышал, но нужно сделать без него
for (var i = 0; i < 10; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000);
})(i);
}
for (var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(+this);
}.bind(i), 1000);
}
for (var i = 0; i < 10; i++) {
setTimeout(console.log, 1000, i);
}
for (var i = 0; i < 10; i++) {
setTimeout(new Function(`console.log(${i})`), 1000);
}
for (var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(10 - i--);
}, 1000);
}
<div class="container">
<div class="yellow"></div>
<textarea></textarea>
</div>
.container {
display: inline-flex;
width: 200px;
height: 400px;
flex-direction: column;
border: 10px solid red;
}
.yellow {
background: yellow;
flex-grow: 1;
}
textarea {
background: #47f;
line-height: 20px;
resize: none;
}
const textarea = document.querySelector('textarea');
textarea.addEventListener('input', function() {
const maxHeight = 300;
const height = 20 * this.value.split('\n').length;
this.style.height = `${Math.min(height, maxHeight)}px`;
});
textarea.dispatchEvent(new Event('input'));
$('.pups').each(function() {
this.innerHTML -= -2;
});
// или
$('.pups').text((i, text) => Number(text) + 2);
// или
document.querySelectorAll('.pups').forEach(n => {
n.innerText = -~-~n.innerText;
});
// или
for (const n of document.getElementsByClassName('pups')) {
n.textContent = parseInt(n.textContent) + 2;
}
$(this)
и $(this).get(0)
?$(this).paused
всегда будет undefined, а вовсе не true или false.if (this.paused) {
this.play();
} else {
this.pause();
}
// или
this[this.paused ? 'play' : 'pause']();
let intervalId = null;
$(window).on('scroll', function() {
const scr = $(this).scrollTop();
const elem = $('.count-wrapper').offset().top;
if (scr > elem - 400 && !intervalId) {
intervalId = setInterval(count, 10);
}
}).scroll();
function count() {
let countEnd = true;
$('.count span').each(function() {
const num = $(this).data('num');
const currNum = $(this).text();
if (currNum < num) {
$(this).text(+currNum + 1);
countEnd = false;
}
});
if (countEnd) {
clearInterval(intervalId);
}
}
$elems.not(i => i % N).addClass('xxx');
// или
elems.forEach((n, i) => n.classList.toggle('xxx', !(i % N)));
// или
for (let i = 0; i < elems.length; i += N) {
elems[i].classList.add('xxx');
}
array2.forEach(n => {
const obj = array1.find(m => m.name === n.name);
if (obj) {
Object.assign(obj, n);
} else {
array1.push({ ...n });
}
});
<div class="tab-headers">
<button data-id="1">69</button>
<button data-id="2">187</button>
<button data-id="3">666</button>
</div>
<div class="tab-contents">
<div data-id="1">hello, world!!</div>
<div data-id="2">fuck the world</div>
<div data-id="3">fuck everything</div>
</div>
.tab-contents div {
display: none;
}
.tab-contents div.active {
display: block;
}
.tab-headers button.active {
background: red;
color: white;
}
const headerSelector = '.tab-headers button';
const contentSelector = '.tab-contents div';
const activeClass = 'active';
// делегирование, назначаем обработчик клика один раз для всех кнопок;
// соответствие кнопок и блоков устанавливаем через равенство атрибутов
document.addEventListener('click', e => {
const header = e.target.closest(headerSelector);
if (header) {
const { id } = header.dataset;
const toggle = n => n.classList.toggle(activeClass, id === n.dataset.id);
document.querySelectorAll(headerSelector).forEach(toggle);
document.querySelectorAll(contentSelector).forEach(toggle);
}
});
// или, назначаем обработчик клика каждой кнопке индивидуально;
// соответствие кнопок и блоков устанавливаем через равенство индексов
const headers = document.querySelectorAll(headerSelector);
const contents = document.querySelectorAll(contentSelector);
headers.forEach(n => n.addEventListener('click', onClick));
function onClick() {
const index = Array.prototype.indexOf.call(headers, this);
const toggle = (n, i) => n.classList.toggle(activeClass, i === index);
headers.forEach(toggle);
contents.forEach(toggle);
}
'1 2 3 4 5 6 7 8 9 0'.replace(/([^ ]+ [^ ]+) /g, '$1;') // "1 2;3 4;5 6;7 8;9 0"
<button data-step="-1">Prev</button>
<button data-step="+1">Next</button>
$(document).on('click', '[data-step]', function({ target: { dataset: { step } } }) {
const $wrapper = $(this).closest('.wrapper');
const $blocks = $wrapper.find('.wrapper-small-block .small-block');
const $active = $blocks.filter('.active');
const $nextActive = $blocks.eq(($active.index() + +step) % $blocks.length);
$active.removeClass('active');
$nextActive.addClass('active');
$wrapper.find('.preview').html($nextActive.html());
});
// или
document.addEventListener('click', ({ target: t }) => {
const { step } = t.dataset;
if (step) {
const wrapper = t.closest('.wrapper');
const blocks = wrapper.querySelector('.wrapper-small-block').children;
const iActive = Array.prototype.findIndex.call(blocks, n => n.matches('.active'));
const nextActive = blocks[(iActive + +step + blocks.length) % blocks.length];
blocks[iActive].classList.remove('active');
nextActive.classList.add('active');
wrapper.querySelector('.preview').innerHTML = nextActive.innerHTML;
}
});
const newData = Object
.entries(data)
.reduce((acc, [ k, v ]) => (v.length && (acc[k] = v), acc), {});
Object.keys(data).forEach(n => data[n].length || delete data[n]);
Можно использовать Lodash.
const newData = _.pickBy(data, n => n.length);
// или
_.each(data, (v, k) => v.length || delete data[k]);