const collectTree = (itemSelector, elementSelector, root = document) =>
[...root.querySelectorAll(itemSelector)].map((element) => ({
name: element.querySelector(elementSelector)?.textContent.trim(),
child: collectTree(itemSelector, elementSelector, element),
}));
collectTree('ul > li', 'a');
// или
collectTree(':scope > ul > li', 'a');
[
{
"name": "Вегетотропные средства",
"child": [
{
"name": "Адренолитические средства",
"child": [
{
"name": "Альфа- и бета-адреноблокаторы",
"child": []
},
{
"name": "Альфа-адреноблокаторы",
"child": [
{
"name": "Альфа-адреноблокаторы в комбинациях",
"child": []
}
]
},
{
"name": "Бета-адреноблокаторы",
"child": [
{
"name": "Бета-адреноблокаторы в комбинациях",
"child": []
}
]
},
{
"name": "Симпатолитики",
"child": [
{
"name": "Симпатолитики в комбинациях",
"child": []
}
]
}
]
},
{
"name": "Противоопухолевые средства",
"child": [
{
"name": "Алкилирующие средства",
"child": []
},
{
"name": "Антиметаболиты",
"child": []
},
{
"name": "Другие противоопухолевые средства",
"child": []
},
{
"name": "Противоопухолевые антибиотики",
"child": []
},
{
"name": "Противоопухолевые гормональные средства и антагонисты гормонов",
"child": []
},
{
"name": "Противоопухолевые средства — ингибиторы протеинкиназ",
"child": []
},
{
"name": "Противоопухолевые средства — моноклональные антитела",
"child": [
{
"name": "Противоопухолевые средства — моноклональные антитела в\n комбинациях",
"child": []
}
]
},
{
"name": "Противоопухолевые средства растительного происхождения",
"child": [
{
"name": "Противоопухолевые средства растительного происхождения в\n комбинациях",
"child": []
}
]
}
]
},
{
"name": "Разные средства",
"child": [
{
"name": "Вспомогательные вещества, реактивы и полупродукты",
"child": []
},
{
"name": "Детское питание (включая смеси)",
"child": []
},
{
"name": "Другие разные средства",
"child": []
},
{
"name": "Радиопрофилактические и радиотерапевтические средства",
"child": []
},
{
"name": "Склерозирующие средства",
"child": []
},
{
"name": "Средства для коррекции нарушений при алкоголизме, токсико- и\n наркомании",
"child": [
{
"name": "Средства для коррекции нарушений при алкоголизме, токсико-\n и наркомании в комбинациях",
"child": []
}
]
}
]
},
{
"name": "Регенеранты и репаранты",
"child": [
{
"name": "Регенеранты и репаранты в комбинациях",
"child": []
}
]
}
]
}
]
interface ComponentProps<V, D> {
value: V;
data: D;
}
const Component = <V, D>({ value, data }: ComponentProps<V, D>) => <></>;
type TResult = {
foo: boolean;
bar: string;
qux: number;
}
type TUnion = keyof TResult;
function fn<T extends TUnion>(value: T): TResult[T] {
switch (value) {
case 'bar': return '' as TResult[T];
case 'foo': return true as TResult[T];
case 'qux': return 1 as TResult[T];
default: throw new Error('Invalid value');
}
}
let a = fn('bar');
class Hamburger {
constructor(size, stuffing) {
this.size = size;
this.stuffing = stuffing;
this.toppings = [];
}
static get SIZE_SMALL() {
return { name: 'SIZE_SMALL', price: 50, calories: 20 };
}
static get SIZE_HUGE() {
return { name: 'SIZE_HUGE', price: 100, calories: 40 };
}
static get STUFFING_CHEESE() {
return { name: 'STUFFING_CHEESE', price: 10, calories: 20 };
}
static get STUFFING_SALAD() {
return { name: 'STUFFING_SALAD', price: 20, calories: 5 };
}
static get STUFFING_POTATOE() {
return { name: 'STUFFING_POTATOE', price: 15, calories: 10 };
}
static get TOPPING_SAUCE() {
return { name: 'TOPPING_SAUCE', price: 15, calories: 0 };
}
static get TOPPING_MAYO() {
return { name: 'TOPPING_MAYO', price: 20, calories: 5 };
}
addTopping(topping) {
this.toppings.push(topping);
return this;
}
calculateCalories() {
const toppingCalories = this.toppings.reduce((total, topping) => total + topping.calories, 0);
return this.size.calories + this.stuffing.calories + toppingCalories;
}
calculatePrice() {
const toppingPrice = this.toppings.reduce((total, topping) => total + topping.price, 0);
return this.size.price + this.stuffing.price + toppingPrice;
}
}
const hamburger = new Hamburger(Hamburger.SIZE_SMALL, Hamburger.STUFFING_CHEESE);
hamburger.addTopping(Hamburger.TOPPING_MAYO);
console.log('Calories:', hamburger.calculateCalories());
hamburger.addTopping(Hamburger.TOPPING_SAUCE);
console.log('Calories:', hamburger.calculateCalories());
console.log('Price with sauce:', hamburger.calculatePrice());
filter: drop-shadow(2px 4px 6px blue);
заменить на box-shadow: 2px 4px 6px blue;
. И можете добавить will-change: height;
. - if (sheep === undefined || sheep === null) sheep === 0;
+ if (sheep === undefined || sheep === null) sheep = 0;
header > div:not(:first-child) {
width: calc(100% - 36%);
padding: 68px 0 68px 48px;
border-left: 14px solid #fecb00;
background-color: #ebebeb;
}
h1, p {
margin: 0;
}
"
, в том случае, если они есть в строке.function escape(value, char = '"') {
const preparedValue = value?.toString() ?? String(value);
if (preparedValue.includes(char)) {
const escapedValue = preparedValue.replaceAll(char, char.repeat(2));
return char + escapedValue + char;
}
return preparedValue;
}
function toCSV(entries) {
return entries
.map((row) => row
.map((entry) => {
if (typeof entry === 'object') {
throw new Error('Unexpected value');
}
return escape(entry);
})
.join(',')
)
.join('\n');
}
console.assert(toCSV([]) === ``);
console.assert(toCSV([[]]) === ``);
console.assert(toCSV([['name', 'age']]) === `name,age`);
console.assert(toCSV([['name', 'age'], ['John', 30]]) === `name,age
John,30`);
console.assert(toCSV([[1, 2], ['a', 'b']]) === `1,2
a,b`);
console.assert(toCSV([[1, 2], ['a', 'b'], ['c', 'd']]) === `1,2
a,b
c,d`);
console.assert(toCSV([['"text"', 'other "long" text']]) === `"""text""","other ""long"" text"`);
window.addEventListener('DOMContentLoaded', () => {
const link = document.querySelector('[data-loop="3"] a');
if (link !== null) {
link.href = 'https://qna.habr.com/q/1232820';
}
});
document.querySelector('form')?.addEventListener('submit', (event) => {
const form = new FormData(event.currentTarget);
let isValid = true;
if (form.get('name').length <= 2) {
isValid = false;
}
if (!isValid) {
// Отмена отправки формы
event.preventDefault();
}
alert(`Is Valid: ${isValid}`);
});