const menuQuerySelector = (selectors) => selectors.map((s) => menuWrapper.querySelector(s));
const buttonSelectors = ['.b1', '.b2', '.b3', '.b4', ...];
const [button1, button2, button3, button4, ...] = menuQuerySelector(buttonSelectors);
const buttons = {};
'all,love,chef,girl,boy,grandma,grandpa'
.split(',').forEach((name) => buttons[name] = menuWrapper.querySelector('.' + name));
Использовать потом, например, вместо girlButton
— buttons.girl
async function start() {
const user = await getUser();
console.log(user);
}
function getUser() {
return fetch('https://jsonplaceholder.typicode.com/users/1')
.then(response => response.json());
}
start();
/*
{
id: 1,
name: 'Leanne Graham',
username: 'Bret',
email: 'Sincere@april.biz',
address: {
street: 'Kulas Light',
suite: 'Apt. 556',
city: 'Gwenborough',
zipcode: '92998-3874',
geo: { lat: '-37.3159', lng: '81.1496' }
},
phone: '1-770-736-8031 x56442',
website: 'hildegard.org',
company: {
name: 'Romaguera-Crona',
catchPhrase: 'Multi-layered client-server neural-net',
bs: 'harness real-time e-markets'
}
}
*/
async function start() {
const user = await getUser();
console.log(user);
}
function getUser() {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/users/1');
xhr.addEventListener('load', () => {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.response));
} else {
reject(xhr.response);
}
});
xhr.send();
});
}
function start() {
getUser(user => {
console.log(user);
});
}
function getUser(callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/users/1');
xhr.addEventListener('load', () => {
if (xhr.status === 200) {
callback(JSON.parse(xhr.response));
} else {
callback(xhr.response);
}
});
xhr.send();
}
start();
function start() {
getUser((error, user) => {
if (!error) {
console.log(user);
}
});
}
function getUser(callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/users/1');
xhr.addEventListener('load', () => {
if (xhr.status === 200) {
callback(null, JSON.parse(xhr.response));
} else {
callback(new Error(xhr.response));
}
});
xhr.send();
}
start();
Вопрос: почему ... перезаписывает его
setItem()
перезаписывает значение по ключу. Ключ у вас один и тот же всегда: "src".const links = new Set(); // TODO: надо считать из LS ранее сохранённый
const key = 'photos'; // ключ в Storage
const addLink = (e) => {
const size = links.size; // размер до добавления
links.add(e.target.src); // добавили ссылку
if (size === links.size) return; // уже была эта ссылка в наборе
localStorage.setItem(key, JSON.stringify([...links]));
alert('Фото добавлено в избранное!');
}
photo.forEach((el) => el.addEventListener('click', addLink));
[...new Set(data.variations.map(n => n.color.name))]
Object.values(Object.fromEntries(data.variations.map(n => [ n.color.name, n.color ])))
// или
Object.values(data.variations.reduce((acc, { color: n }) => (acc[n.name] ??= n, acc), {}))
// или
data.variations.map(n => n.color).filter(function(n) {
return !(this[n.name] = this.hasOwnProperty(n.name));
}, {})
const unique = (data, key = n => n) =>
Array.prototype.filter.call(data, function(n) {
const k = key(n);
return !this.has(k) && this.add(k);
}, new Set);
// получаем массив уникальных имён цветов
const uniqueStrColors = unique(data.variations.map(n => n.color.name));
// получаем массив объектов цветов, свойства name которых уникальны
const uniqueObjColors = unique(data.variations.map(n => n.color), n => n.name);
browserSync.init({
proxy: 'http://myproject.dev/',
host: 'myproject.dev',
open: 'external'
});
{
const max1 = 9;
const max2 = 30; // max of two nums
let cur = max2 / max1;
const inc = cur;
const len = 3;
const log = (a, b) => {
console.log(b > -Infinity ? `a: ${` ${a}`.slice(-len)} | b: ${` ${b}`.slice(-len)}` : `a: ${` ${a}`.slice(-len)} |`)
}
log(0, 0);
for(let i = 1, j = 1; i < max2; i++) {
const nums = [i];
if(i >= cur) {
nums.push(j);
j++;
cur += inc;
}
log(...nums);
}
log(max2, max1);
}
(now - start) / (end - start) = x / total
, откуда x = total * (now - start) / (end - start)
requestAnimationFrame()
вызывать функцию, которая отрисует очередной кадр: текущие значения счётчиков.const elements = document.querySelectorAll('.ch')
const show = (Event) => {
console.log('Навел!');
// ошибка. elements - коллекция, а element вообще здесь не определен
elements.classList.add('bgc');
}
elements.forEach(element =>{
element.addEventListener('mouseover', show)
})
const elements = document.querySelectorAll('.ch')
elements.forEach(element => {
element.addEventListener('mouseover', event => {
console.log('Навел!');
element.classList.add('bgc')
})
})
const elements = document.querySelectorAll('.ch')
const show = (event, element) => {
element.classList.add('bgc')
}
elements.forEach(element => {
element.addEventListener('mouseover', event => {
show(event, element)
})
})
const elements = document.querySelectorAll('.ch')
const show = event => {
event.currentTarget.classList.add('bgc')
}
elements.forEach(element =>{
element.addEventListener('mouseover', show)
})
$image = new SVG('100mm','100mm');
$doc = $image->getDocument();
$square = new SVGLine('0mm', '0mm', '55mm', '55mm'); // x0 y0 x1 y1
$square->setStyle('stroke', '#FF0000'); //цвет
$doc->addChild($square);
$arc = new SVGPath('m 40,40 A 30,30,0,0,1,150,150');
$arc->setStyle('stroke', '#FF0000');
$doc->addChild($arc);
header('Content-Type: image/svg+xml');
echo $image;