data-passwordrepeat="Проверьте правильность пароля"
...
const passwordMessage = _element.dataset.password;
const passwordMessageRepeat = _element.dataset.passwordrepeat;
...
if(passwordMessage) {
this.checkPassword(_element, passwordMessage, successMessage);
}
if(passwordMessageRepeat) {
this.checkPassword(_element, passwordMessage, successMessage);
this.matchingPasswords(passwordMessage, successMessage);
}
...
this.checkPassword = function (_element, message, successMessage) {
const passwordRegExp = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
const checkPassByRegExp = passwordRegExp.test(_element.value);
if (!checkPassByRegExp) {
this.createErrorTemplate(_element, message);
} else {
this.createSuccessTemplate(_element, successMessage);
}
}
this.matchingPasswords = function (message, successMessage) {
const allPasswords = _form.querySelectorAll('input[type="password"]');
const arrPasswordValues = Array.from(allPasswords).map(item => item.value.trim());
const checkPassByUniqueness = new Set(arrPasswordValues).size === 1;
if (!checkPassByUniqueness) {
allPasswords.forEach((value) => this.createErrorTemplate(value, message));
} else {
allPasswords.forEach(value => this.createSuccessTemplate(value, successMessage));
}
}
this.createErrorTemplate = function (_element, message) {
const parent = _element.closest(`.${labelClass}`);
parent.classList.add(errorClass);
parent.classList.remove(successClass);
parent.querySelectorAll(`.${errorItemClass}, .${successItemClass}`).forEach(item => item.remove());
parent.insertAdjacentHTML('beforeend', `<small class=${errorItemClass}>${message}</small>`);
}
this.createSuccessTemplate = function (_element, message) {
const parent = _element.closest(`.${labelClass}`);
if (parent) {
parent.classList.add(successClass);
parent.classList.remove(errorClass);
parent.querySelectorAll(`.${errorItemClass}, .${successItemClass}`).forEach(item => item.remove());
parent.insertAdjacentHTML('beforeend',`<small class=${successItemClass}>${message}</small>`)
}
}
<div class="container">
<div class="fig"></div>
</div>
.container {
position: relative;
border: 1px solid #000;
width: 800px;
height: 400px;
overflow: hidden;
}
.fig {
position: absolute;
top: 0;
left: -105%;
width: 150%;
height: 150%;
transform: skew(-20deg, -25deg);
background: linear-gradient(180deg, #C91C04 0%, #4B0900 100%);
}
<select>
и <option>
с помощью CSS в некоторых аспектах ограничена. Это связано с тем, что рендеринг выпадающего списка и его пунктов (<option>
) веб-браузерами в значительной степени зависит от нативного операционной системы интерфейса пользователя (OS UI). В результате многие аспекты этих элементов, такие как ширина выпадающего списка, оформление выпадающего списка, и стилизация пунктов списка, могут оказаться сложными для полного контроля с помощью обычных CSS.#include <iostream>
#include <stack>
using namespace std;
int main() {
int n, max_quality = 0, prev_max_quality = 0;
stack<int> s;
cin >> n;
for (int i = 0; i < n; i++) {
int event;
cin >> event;
if (event == 0) {
// если извлекаем желудь, то выводим максимальное качество
int top = s.top();
s.pop();
if (top == max_quality) {
max_quality = prev_max_quality;
}
cout << max_quality << endl;
} else {
// если нашли новый желудь, то добавляем его в стек
prev_max_quality = max_quality;
s.push(event);
max_quality = max(max_quality, event);
}
}
return 0;
}
function installWeather(props) {
const request = new Promise((resolve, reject) => {
console.log('Запрос данных на сервер...')
fetch('https://api.openweathermap.org/data/2.5/weather?q=LVIV&units=metric&APPID=5d066958a60d315387d9492393935c19')
.then(response => {
if (response.ok) {
return resolve(response.json());
} else {
reject('Что-то пошло нет так');
}
});
});
return request
.then(data => {
return (
<div className='wrapper'>
<div className='container'>
<h1 className="place" id="place">City: {data.name}</h1>
<p className="temp" id="temp"></p>
<p className="pressure" id="pressure"></p>
<p className="description" id="description"></p>
<p className="humidity" id="humidity"></p>
<p className="speed" id="speed"></p>
<p className="degree" id="degree"></p>
<img className="image" id="image" src="" alt="clouds" title="Weather"/>
</div>
</div>
)
})
}
export default installWeather;
freeSeats
, можно добавить аргумент функции bookTickets
, который будет принимать массив выбранных мест. Затем нужно проверить, что все места из выбранного массива находятся в списке свободных мест freeSeats
. Если все места доступны, то их можно забронировать.bookTickets
. Затем можно добавить проверки на соответствие параметров формата и наличия еды заданным значениям в объекте seats
. Если формат фильма или наличие еды не соответствуют требованиям, можно выкинуть ошибку.async function bookTickets(date, time, numTickets, selectedSeats = [], is3D = false, hasFood = false){
try{
const availableSeats = await checkTicketsAvailable(date, time, numTickets);
// проверка наличия выбранных мест
const unavailableSeats = selectedSeats.filter(seat => !seats[date][time].freeSeats.includes(seat));
if (unavailableSeats.length > 0) {
throw new Error(`Места ${unavailableSeats.join(', ')} недоступны`);
}
// проверка формата и наличия продуктов питания
if ((is3D && !seats[date][time].format) || (hasFood && !seats[date][time].food)) {
throw new Error(`Невозможно забронировать билеты с выбранными параметрами`);
}
console.log(`${date} вы забронировали ${numTickets} билетов на время: ${time}`);
if (selectedSeats.length > 0) {
console.log(`Выбранные места: ${selectedSeats.join(', ')}`);
}
if (is3D) {
console.log(`Формат фильма: 3D`);
} else {
console.log(`Формат фильма: 2D`);
}
if (hasFood) {
console.log(`С едой`);
} else {
console.log(`Без еды`);
}
} catch (error) {
console.error(error);
}
}
bookTickets('2023-02-17', '15:00', 2, ['11', '21'], false, true);
selectedSeats
, is3D
и hasFood
для выбора мест, формата фильма и наличия еды соответственно. Затем в функции bookTickets
проверяется доступность выбранных мест и соответствие параметров формата и наличия еды требованиям. Выводится сообщение о бронировании билетов и выбранных параметрах. this
для функции, объявленной как function
определяется в момент её вызова. Если её вызывают будто она свойство объекта, этот объект будет this'ом.this === window
.window
это не user
. И там нет искомого свойства, скорее всего. Или есть, но неожиданно другое. .closest()
ищет исключительно вверх по дереву, начиная с самого элемента. А .text
не является родительским элементом для картинки.-const message = event.target.closest('.text').textContent;
+ const message = event.target.closest('.message_container').querySelector('.text').textContent;
.product
. Вместо первого .product
нужен тот, внутри которого находится нажатая кнопка:document.querySelector('.wrapper_product')
---> event.target
menu.addEventListener('click', ({ target: t }) => {
if (t.tagName === 'SPAN') {
const parent = t.parentNode;
parent.classList.toggle('active');
for (const n of menu.querySelectorAll('.active')) {
if (n !== parent) {
n.classList.toggle('active', n.contains(parent));
}
}
}
});
- .menu_list_item.active .submenu {
+ .active > .submenu {
- .submenu_list_item.active .product {
+ .active > .product {
const container = document.querySelector('#menu');
const itemSelector = 'li';
const buttonSelector = `${itemSelector} span`;
const activeClass = 'active';
container.addEventListener('click', function(e) {
const item = e.target.closest(buttonSelector)?.closest(itemSelector);
if (item) {
item.classList.toggle(activeClass);
this.querySelectorAll(`.${activeClass}`).forEach(n => {
if (n !== item) {
n.classList.toggle(activeClass, n.contains(item));
}
});
}
});