const clone = (data, replacements) =>
data instanceof Object
? data instanceof Array
? data.map(n => clone(replacements?.hasOwnProperty(n) ? replacements[n] : n, replacements))
: Object.fromEntries(Object.entries(data).map(([ k, v ]) => [
k,
clone(replacements?.hasOwnProperty(k) ? replacements[k] : v, replacements)
]))
: data;const products = arr.map(n => clone(obj.product[0], n));
"[object Object]". Всё.toString (конечно, поступать так имеет смысл только в том случае, если вы можете гарантировать, что строковые представления будут уникальны).
$doc = new DOMDocument();
$doc->loadHTML($html);
$a = $doc->getElementsByTagName('a');
$result = array_map([ $doc, 'saveHTML' ], iterator_to_array($a));$result = preg_split('/(?<=\/a>)(?=<a)/', $html);
// или
preg_match_all('/<a .*?>.*?<\/a>/', $html, $matches);
$result = $matches[0];
out.textContent = badWords.reduce(
(str, n) => str.replaceAll(n, '*'.repeat(n.length)),
field
);for (const n of badWords) {
field = field.replace(RegExp(n, 'g'), Array(n.length + 1).join('*'));
}
out.innerText = field;out.innerHTML = (function replace(str, i, n = badWords[i]) {
return n
? replace(str.split(n).join(Array(n.length).fill`*`.join``), -~i)
: str;
})(field, 0);out.replaceChildren(field.replace(
RegExp(badWords.join('|'), 'g'),
m => m.replaceAll(/./g, '*')
));
let index = -1;
setInterval(el => {
const show = !el.classList.contains('_active');
index = (index + show) % infoModal.length;
el.innerText = infoModal[index].title;
el.classList.toggle('_active', show);
}, 1000, document.querySelector('.modal__title'));Если, к примеру, нужно скрывать блок каждый раз через5 сек, а показывать блок через рандомный промежуток времени?
(function updateText(el, i) {
const show = el.classList.toggle('_active');
i = (i + show) % infoModal.length;
el.textContent = infoModal[i].title;
setTimeout(updateText, 1000 + !show * Math.random() * 3000, el, i);
})(document.querySelector('.modal__title'), -1);
Время, которое я задаю, применяется к fadeOut, а вот к runProgress нет
this.fadeOut = `fadeOut ${this.time}s linear forwards`, this.runProgress = `runProgress ${this.time}s liner forwards`,
v-for. Если изменить значение свойства time и добавить в messages новый элемент, то у тех, что были добавлены раньше, изменится длительность анимации. Наверное, стоит вырезать свойства fadeOut и runProgress, элементам messages при создании добавлять актуальное значение свойства time, типа time: this.time, и использовать его при задании стилей:methods: {
getStyle: (name, { time }) => ({
animation: `${name} ${time}s linear forwards`,
}),
...:style="getStyle('fadeOut', message)":style="getStyle('runProgress', message)"
сделал две функции, которые поочерёдно возвращают компонент согласно индексу
желаемого эффекта не получил
в консоль выводиться...
const Component1 = () => <h1>hello, world!!</h1>;
const Component2 = () => <h1>fuck the world</h1>;
const Component3 = () => <h1>fuck everything</h1>;
const components = [ Component1, Component2, Component3 ];
function App() {
const [ index, setIndex ] = useState(0);
const min = 0;
const max = components.length - 1;
const Component = components[index];
const onClick = ({ target: { dataset: { step } } }) =>
setIndex(Math.max(min, Math.min(max, index + +step)));
return (
<div>
<button onClick={onClick} data-step="-1" disabled={index <= min}>prev</button>
<button onClick={onClick} data-step="+1" disabled={index >= max}>next</button>
{Component && <Component />}
</div>
);
}
document.querySelector('form').addEventListener('input', e => {
document.querySelector('button').disabled = ![
[ 'input', el => el.value ],
[ 'select', el => el.selectedIndex ],
].every(([ selector, validator ]) => {
return [...e.currentTarget.querySelectorAll(selector)].every(validator);
});
});
const entries = Object.entries(obj); for (const entry of entries) { if (!isObject(entry)) { result = Object.assign(result, Object.fromEntries(entry)); } else return cloneDeep(entry);
const [ buttonText, setButtonText ] = useState('hello, world!!');
const [ clicked, setClicked ] = useState(false);
function onClick() {
setClicked(true);
setTimeout(() => {
setButtonText('fuck the world');
setClicked(false);
}, 1000);
}<button onClick={onClick} disabled={clicked}>{buttonText}</button>
{clicked ? <img src="..." /> : null}
const arrs = [ arr1, arr2 ];.const result = arrs.reduce((acc, n) => (
n.forEach((m, i) => Object.assign(acc[i] ??= {}, m)),
acc
), []);function* zip(data, defaultValue = null) {
const iterators = Array.from(data, n => n[Symbol.iterator]());
for (let doneAll = false; doneAll = !doneAll;) {
const values = [];
for (const n of iterators) {
const { value, done } = n.next();
values.push(done ? defaultValue : value);
doneAll &&= done;
}
if (!doneAll) {
yield values;
}
}
}
const result = Array.from(zip(arrs), n => Object.assign({}, ...n));
function replaceText(node, replacer) {
if (node.nodeType === Node.ELEMENT_NODE) {
node.childNodes.forEach(n => replaceText(n, replacer));
} else if (node.nodeType === Node.TEXT_NODE) {
node.textContent = replacer(node.textContent);
}
}function replaceText(node, replacer) {
const iter = document.createNodeIterator(node, NodeFilter.SHOW_TEXT);
for (let n = null; n = iter.nextNode();) {
n.nodeValue = replacer(n.nodeValue);
}
}replaceText(document.body, str => str.replace(/\d/g, 'hello, world!!'));
useCapture
A boolean value indicating whether events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree.
element.addEventListener(event, handler, true).
case ADD_PRODUCT:
const item = state.products.find(n => n.id === action.payload.id);
return {
...state,
products: item
? state.products.map(n => n === item ? { ...n, count: n.count + 1 } : n)
: [ ...state.products, { ...action.payload, count: 1 } ],
};
document.querySelector('.ticket_content').addEventListener('input', e => {
document.querySelector('.ticket_price').innerText =
Array.prototype.reduce.call(
e.currentTarget.querySelectorAll('.plus_minus'),
(acc, n) => acc + n.querySelector('input').value * n.nextElementSibling.innerText,
0
);
});