Skip to content
Open

Main #29

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions async-requests/poll/task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
document.addEventListener('DOMContentLoaded', function() {
const pollTitle = document.getElementById('poll__title');
const pollAnswers = document.getElementById('poll__answers');

function renderPoll(pollData) {
pollTitle.textContent = pollData.data.title;
pollAnswers.innerHTML = '';
pollData.data.answers.forEach((answer, index) => {
const answerButton = document.createElement('button');
answerButton.classList.add('poll__answer');
answerButton.textContent = answer;
answerButton.addEventListener('click', function() {
sendVote(pollData.id, index);
});
pollAnswers.appendChild(answerButton);
});
}

function sendVote(pollId, answerIndex) {
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://students.netoservices.ru/nestjs-backend/poll');
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
if (xhr.status === 200) {
const response = JSON.parse(xhr.responseText);
showThankYou();
console.log(response);
} else {
console.error('Error sending vote:', xhr.status);
}
};
xhr.onerror = function() {
console.error('Error sending vote:', xhr.status);
};
const params = `vote=${pollId}&answer=${answerIndex}`;
xhr.send(params);
}

function showThankYou() {
alert('Спасибо, ваш голос засчитан!');
}

function loadPoll() {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://students.netoservices.ru/nestjs-backend/poll');
xhr.onload = function() {
if (xhr.status === 200) {
const pollData = JSON.parse(xhr.responseText);
renderPoll(pollData);
} else {
console.error('Error loading poll:', xhr.status);
}
};
xhr.onerror = function() {
console.error('Error loading poll:', xhr.status);
};
xhr.send();
}

loadPoll();
});
53 changes: 53 additions & 0 deletions async-requests/preloader/task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
document.addEventListener('DOMContentLoaded', function() {
const loader = document.getElementById('loader');
const items = document.getElementById('items');

function showLoader() {
loader.classList.add('loader_active');
}

function hideLoader() {
loader.classList.remove('loader_active');
}

function renderCurrency(currency) {
const item = document.createElement('div');
item.classList.add('item');

const code = document.createElement('div');
code.classList.add('item__code');
code.textContent = currency.CharCode;
item.appendChild(code);

const value = document.createElement('div');
value.classList.add('item__value');
value.textContent = currency.Value;
item.appendChild(value);

const currencyText = document.createElement('div');
currencyText.classList.add('item__currency');
currencyText.textContent = 'руб.';
item.appendChild(currencyText);

items.appendChild(item);
}

function loadCurrency() {
showLoader();
fetch('https://students.netoservices.ru/nestjs-backend/slow-get-courses')
.then(response => response.json())
.then(data => {
hideLoader();
const currencies = data.response.Valute;
for (const currency in currencies) {
renderCurrency(currencies[currency]);
}
})
.catch(error => {
console.error('Error fetching currency:', error);
hideLoader();
});
}

loadCurrency();
});
36 changes: 36 additions & 0 deletions async-requests/progressbar/task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
document.addEventListener('DOMContentLoaded', function() {
const progress = document.getElementById('progress');

function updateProgress(event) {
if (event.lengthComputable) {
const percentComplete = (event.loaded / event.total) * 100;
progress.value = percentComplete;
}
}

function sendFormData(formData) {
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://students.netoservices.ru/nestjs-backend/upload');
xhr.upload.addEventListener('progress', updateProgress);
xhr.onload = function() {
if (xhr.status === 200) {
console.log('File uploaded successfully');
} else {
console.error('Error uploading file:', xhr.status);
}
};
xhr.onerror = function() {
console.error('Error uploading file:', xhr.status);
};
xhr.send(formData);
}

function handleFormSubmit(event) {
event.preventDefault();
const formData = new FormData(event.target);
sendFormData(formData);
}

const form = document.getElementById('form');
form.addEventListener('submit', handleFormSubmit);
});
52 changes: 52 additions & 0 deletions document-structure/cart/task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
document.addEventListener('DOMContentLoaded', function() {
const productCards = document.querySelectorAll('.product');
const cart = document.querySelector('.cart');
const cartTitle = document.querySelector('.cart__title');

productCards.forEach(product => {
const addButton = product.querySelector('.product__quantity-control_inc');
const removeButton = product.querySelector('.product__quantity-control_dec');
const quantityValue = product.querySelector('.product__quantity-value');
const addToCartButton = product.querySelector('.product__add');

addButton.addEventListener('click', function() {
let newValue = parseInt(quantityValue.textContent) + 1;
quantityValue.textContent = newValue > 0 ? newValue : 1;
});

removeButton.addEventListener('click', function() {
let newValue = parseInt(quantityValue.textContent) - 1;
quantityValue.textContent = newValue > 0 ? newValue : 1;
});

addToCartButton.addEventListener('click', function() {
const productId = product.getAttribute('data-id');
const productImageSrc = product.querySelector('.product__image').getAttribute('src');
const productQuantity = parseInt(quantityValue.textContent);

const existingCartItem = cart.querySelector(`.cart__product[data-id="${productId}"]`);
if (existingCartItem) {
const existingQuantity = parseInt(existingCartItem.querySelector('.cart__product-count').textContent);
existingCartItem.querySelector('.cart__product-count').textContent = existingQuantity + productQuantity;
} else {
const cartProduct = document.createElement('div');
cartProduct.classList.add('cart__product');
cartProduct.setAttribute('data-id', productId);

const cartProductImage = document.createElement('img');
cartProductImage.classList.add('cart__product-image');
cartProductImage.setAttribute('src', productImageSrc);
cartProduct.appendChild(cartProductImage);

const cartProductCount = document.createElement('div');
cartProductCount.classList.add('cart__product-count');
cartProductCount.textContent = productQuantity;
cartProduct.appendChild(cartProductCount);
cart.appendChild(cartProduct);
}

cartTitle.style.display = 'block';
});
});
});

32 changes: 32 additions & 0 deletions document-structure/todo/task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
document.addEventListener('DOMContentLoaded', function() {
const taskList = document.getElementById('tasks__list');
const inputTask = document.getElementById('task__input');
const addButton = document.getElementById('tasks__add');

function addTask(taskContent) {
const taskHTML = `
<div class="task">
<div class="task__title">
${taskContent}
</div>
<a href="#" class="task__remove">&times;</a>
</div>
`;
taskList.insertAdjacentHTML('beforeend', taskHTML);

const removeButtons = taskList.querySelectorAll('.task__remove');
const lastRemoveButton = removeButtons[removeButtons.length - 1];
lastRemoveButton.addEventListener('click', function() {
lastRemoveButton.parentElement.remove();
});
}

addButton.addEventListener('click', function(event) {
event.preventDefault();
if (inputTask.value.trim() !== '') {
addTask(inputTask.value.trim());
inputTask.value = '';
}
});
});

33 changes: 33 additions & 0 deletions document-structure/tooltip/task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
document.addEventListener('DOMContentLoaded', function() {
let currentTooltip = null;

document.querySelectorAll('.has-tooltip').forEach(tooltip => {
tooltip.addEventListener('click', function(event) {
event.preventDefault();
const tooltipText = this.getAttribute('title');

if (currentTooltip) {
currentTooltip.remove();
}

currentTooltip = document.createElement('div');
currentTooltip.classList.add('tooltip');
currentTooltip.textContent = tooltipText;
document.body.appendChild(currentTooltip);
positionTooltip(this, currentTooltip);
});
});

function positionTooltip(tooltipTrigger, tooltipElement) {
const tooltipRect = tooltipElement.getBoundingClientRect();
const triggerRect = tooltipTrigger.getBoundingClientRect();
const bodyRect = document.body.getBoundingClientRect();

const top = triggerRect.top - tooltipRect.height - 5;
const left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;

tooltipElement.style.top = `${Math.max(top, bodyRect.top)}px`;
tooltipElement.style.left = `${Math.max(left, bodyRect.left)}px`;
}
});

29 changes: 29 additions & 0 deletions dom/ads/task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
class AdRotator {
constructor() {
this.rotatorElements = document.querySelectorAll('.rotator__case');
this.currentIndex = 0;
this.startRotation();
}

startRotation() {
this.intervalId = setInterval(() => {
this.rotate();
}, 1000); // Меняем текст каждую секунду
}

rotate() {
const currentElement = this.rotatorElements[this.currentIndex];
currentElement.classList.remove('rotator__case_active');

this.currentIndex++;
if (this.currentIndex >= this.rotatorElements.length) {
this.currentIndex = 0; // Возвращаемся к первому элементу после прохождения всех
}

const nextElement = this.rotatorElements[this.currentIndex];
nextElement.classList.add('rotator__case_active');
}
}

new AdRotator();

17 changes: 17 additions & 0 deletions dom/book-reader/task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const fontSizeSwitches = document.querySelectorAll('.font-size');
const book = document.querySelector('#book');

fontSizeSwitches.forEach(fontSizeSwitch => {
fontSizeSwitch.addEventListener("click", (event) => {
event.preventDefault();
const currentFontSize = document.querySelector('.font-size_active');
currentFontSize.classList.remove('font-size_active');
event.target.classList.add('font-size_active');
changeFont(event.target.dataset.size);
})
});

function changeFont(fontSize) {
book.className = `book ${fontSize ? `book_fs-${fontSize}` : ''}`;
}

36 changes: 36 additions & 0 deletions dom/reveal/task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
class RevealOnScroll {
constructor() {
this.revealElements = document.querySelectorAll('.reveal');
this.scrollHandler = this.handleScroll.bind(this);

this.registerEvents();
this.handleScroll(); // Вызываем метод handleScroll при инициализации, чтобы показать блоки, которые уже находятся в области видимости
}

registerEvents() {
window.addEventListener('scroll', this.scrollHandler);
}

handleScroll() {
this.revealElements.forEach(element => {
if (this.isElementInViewport(element)) {
element.classList.add('reveal_active');
} else {
element.classList.remove('reveal_active');
}
});
}

isElementInViewport(el) {
const rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
}

new RevealOnScroll();

23 changes: 23 additions & 0 deletions event-object/dropdown/task.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
document.addEventListener('DOMContentLoaded', function() {
const dropdowns = document.querySelectorAll('.dropdown');

dropdowns.forEach(function(dropdown) {
const valueElement = dropdown.querySelector('.dropdown__value');
const listElement = dropdown.querySelector('.dropdown__list');

valueElement.addEventListener('click', function() {
listElement.classList.toggle('dropdown__list_active');
});

const items = listElement.querySelectorAll('.dropdown__item');
items.forEach(function(item) {
item.addEventListener('click', function(event) {
event.preventDefault(); // Предотвращаем переход по ссылке

const newValue = item.querySelector('.dropdown__link').textContent;
valueElement.textContent = newValue;
listElement.classList.remove('dropdown__list_active');
});
});
});
});
Loading