const labels = document.querySelectorAll('#price_block .change_model_iphone .item label');
const select = document.querySelector('#select_model');
const getFor = el => el.getAttribute('for');
// или
const getFor = el => el.attributes.for.value;
// или
const getFor = el => el.htmlFor;
// можно перезаписать разметку
select.innerHTML = Array
.from(labels, n => `<option value="${getFor(n)}">iPhone ${n.innerText}</option>`)
.join('');
// или, напрямую создавать новые элементы
select.append(...Array.prototype.map.call(
labels,
n => new Option(`iPhone ${n.textContent}`, getFor(n))
));
<div class="text">hello, world!!</div>
<div class="text">fuck the world</div>
<div class="text">fuck everything</div>
<select></select>
const texts = document.querySelectorAll('.text');
const select = document.querySelector('select');
select.append(...Array.from(texts, n => new Option(n.textContent)));
select.value = null;
select.addEventListener('change', ({ target: { selectedIndex } }) => {
texts.forEach((n, i) => n.classList.toggle('active', i === selectedIndex));
});
const select = document.querySelector('[name="select_model"]');
const radios = document.querySelectorAll('[name="model"]');
select.addEventListener('change', ({ target: { value } }) => {
Array.prototype.find.call(radios, n => n.value === value).checked = true;
});
radios.forEach(function(n) {
n.addEventListener('change', this);
}, e => select.value = e.target.value);
const classPrefix = 'toggle-';
.// вариант попроще - хватаем всё, что содержит указанную подстроку; так можно нарваться
// на выполнение бессмысленной работы, будут отобраны элементы, у которых ничего
// не будет удалено - это если подстрока находится не в начале класса, например xxx-toggle-xxx
const elements = document.querySelectorAll(`[class*="${classPrefix}"]`);
// вариант посложнее, поуродливее, но без обработки лишнего - хватаем элементы,
// у которых класс начинается с указанной подстроки, или содержит указанную подстроку,
// а перед ней ещё есть пробел
const elements = document.querySelectorAll(`[class^="${classPrefix}"], [class*=" ${classPrefix}"]`);
const reg = RegExp(`(^|\\s)${classPrefix}`);
elements.forEach(n => n.className = n.className.split(reg).join(' ').trim());
// или
elements.forEach(function(n) {
n.classList.value = n.classList.value.replace(this, '$1');
}, RegExp(`(^| )${classPrefix}`, 'g'));
// или
for (const { classList: cl } of elements) {
for (const n of [...cl]) {
if (n.startsWith(classPrefix)) {
cl.remove(n);
cl.add(n.slice(classPrefix.length));
}
}
}
$('#searchSity').autocomplete('search', '');
const getValues = (obj, count) =>
count > 0
? Object.values(obj).slice(0, count)
: [];
function getValues(obj, count) {
const result = [];
for (const k in obj) {
if (result.length >= count) {
break;
} else if (obj.hasOwnProperty(k)) {
result.push(obj[k]);
}
}
return result;
}
const groupUnique = (arr, idKey, ...keys) => Object
.values(arr.reduce((acc, n) => {
const id = n[idKey];
acc[id] = acc[id] || keys.reduce((group, k) => (group[k] = [], group), {...n});
keys.forEach(k => acc[id][k].push(...n[k]));
return acc;
}, {}))
.map(n => (keys.forEach(k => n[k] = [...new Set(n[k])]), n));
const result = groupUnique(arr, 'family', 'variants', 'subsets');
Как лучше удалять весь текст с input полей при клонировании елемента ?
.form-row
, а не один из элементов, которые присутствуют в #BodyForm
.подскажите как избежать удаления последнего элемента
#BodyForm
- тоже очевидно: получаете последний элемент в функции удаления и сравниваете его с удаляемым, если равны, ничего не делаете.<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.2/css/bootstrap.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css">
<div id="BodyForm">
<div class="form-row form-row-data">
<div class="form-group col-sm-3">
<input type="text" class="form-control" placeholder="Name">
</div>
<div class="form-group col-sm">
<input type="text" class="form-control" placeholder="Value">
</div>
<div class="form-group col-sm-auto">
<button type="button" class="btn btn-secondary btn-block" onclick="delRow(this)">
<em class="fa fa-minus"></em>
</button>
</div>
</div>
<div class="form-row justify-content-end">
<div class="col-sm-4">
<button type="button" class="btn btn-outline-success btn-block pull-right" onclick="addRow()">
<i class="fa fa-plus"> Add</i>
</button>
</div>
<div class="col-sm-4">
<button type="button" class="btn btn-outline-danger btn-block pull-right">
<i class="fa fa-trash"> Clear all</i>
</button>
</div>
</div>
</div>
const form = document.querySelector('#BodyForm');
const rows = form.getElementsByClassName('form-row-data');
const row = rows[0].cloneNode(true);
const footer = form.querySelector('.justify-content-end');
const addRow = () => footer.before(row.cloneNode(true));
const delRow = el => rows.length > 1 && el.closest('.form-row-data').remove();
var found = false
, в случае если совпадение найдено - устанавливаете её в true. А код из блока else выносите за цикл и оборачиваете в if (!found)
. const getCard = num => cards.find(n => n.id === num);
// ...
const card = getCard(cardRandom(1, 51));
id
. Может, лучше использовать случайное число как индекс? Типа так:const card = cards[Math.random() * cards.length | 0];
const TYPES = {
1: 'region',
3: 'area',
7: 'street',
};
const newItems = items.map(({ parents_names, parents_levels, ...n }) =>
parents_names.reduce((acc, name, i) => (
acc[TYPES[parents_levels[i]]] = name,
acc
), n)
);
const className = 'element';
const attrName = 'data-attr';
const attrValue = 'this-element';
const elem = document.querySelector(`.${className}[${attrName}="${attrValue}"]`);
const elems = document.getElementsByClassName(className);
// или
const elems = document.querySelectorAll('.' + className);
const elem = Array.prototype.find.call(
elems,
n => n.getAttribute(attrName) === attrValue
);
// или
let elem = null;
for (const n of elems) {
if ((n.attributes[attrName] || {}).value === attrValue) {
elem = n;
break;
}
}
// или
let elem = null;
for (let i = 0; !elem && i < elems.length; i++) {
elem = elems[i].matches(`[${attrName}="${attrValue}"]`) ? elems[i] : elem;
}
Подсказали что правильно сделать через атрибут data-*
data-key
, как у тех элементов, по клику на которые блоки надо показывать. По клику хватаете все блоки и показываете те, у которых data-key
совпал с кликнутым, остальные скрываете:$(document).on('click', 'a[data-key]', function() {
$('div[data-key]')
.hide()
.filter((i, n) => n.dataset.key === this.dataset.key)
.show();
});
Имеется довольно большая матрица (чем больше- тем лучше).
Как правильно отрисовать её на странице?
Хотелось бы еще и с нормальной частотой, хотя-бы раз в 50 ms.
не будет ли быстрее преобразовывать матрицу в строку через arr.toString()...
Картинка
const index = str.search(/\d\D*$/);
// или
const index = str.replace(/\D*$/, '').length - 1;
// или
const index = [...str].reduce((max, n, i) => +n === +n ? i : max, -1);
// или
const index = +(Object.entries(str).filter(n => !isNaN(n[1])).pop() || [ -1 ])[0];
// или
let index = str.length;
while (--index >= 0 && !'0123456789'.includes(str[index])) ;
$('#imgTitle').find('img').remove().end().prepend(...
$('.mod__l').append(function() {
return ({
m1: mod__c1,
m2: mod__c2,
m3: mod__c3,
})[$('.mod__input', this).data('mod')];
});