From b5fe24eda03ddc948c0beab5ebe9b7a095d7a1da Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Fri, 10 Mar 2023 10:04:26 +0300 Subject: [PATCH 1/4] week-3 --- projects/dom/index.js | 121 ++++++ projects/dom/index.spec.js | 112 ++++++ .../loft-photo-lite-2/images/arrow-left.svg | 4 + projects/loft-photo-lite-2/images/button.svg | 17 + projects/loft-photo-lite-2/images/chat.svg | 3 + projects/loft-photo-lite-2/images/exit.svg | 5 + .../loft-photo-lite-2/images/heart-red.svg | 3 + projects/loft-photo-lite-2/images/heart.svg | 3 + projects/loft-photo-lite-2/images/logo.svg | 11 + projects/loft-photo-lite-2/images/send.svg | 3 + projects/loft-photo-lite-2/images/vert1.svg | 22 ++ projects/loft-photo-lite-2/images/vert2.svg | 22 ++ projects/loft-photo-lite-2/images/vert3.svg | 22 ++ projects/loft-photo-lite-2/index.js | 8 + projects/loft-photo-lite-2/layout.html | 63 ++++ projects/loft-photo-lite-2/pages.js | 10 + projects/loft-photo-lite-2/readme.md | 29 ++ projects/loft-photo-lite-2/styles.css | 348 ++++++++++++++++++ 18 files changed, 806 insertions(+) create mode 100644 projects/dom/index.js create mode 100644 projects/dom/index.spec.js create mode 100644 projects/loft-photo-lite-2/images/arrow-left.svg create mode 100644 projects/loft-photo-lite-2/images/button.svg create mode 100644 projects/loft-photo-lite-2/images/chat.svg create mode 100644 projects/loft-photo-lite-2/images/exit.svg create mode 100644 projects/loft-photo-lite-2/images/heart-red.svg create mode 100644 projects/loft-photo-lite-2/images/heart.svg create mode 100644 projects/loft-photo-lite-2/images/logo.svg create mode 100644 projects/loft-photo-lite-2/images/send.svg create mode 100644 projects/loft-photo-lite-2/images/vert1.svg create mode 100644 projects/loft-photo-lite-2/images/vert2.svg create mode 100644 projects/loft-photo-lite-2/images/vert3.svg create mode 100644 projects/loft-photo-lite-2/index.js create mode 100644 projects/loft-photo-lite-2/layout.html create mode 100644 projects/loft-photo-lite-2/pages.js create mode 100644 projects/loft-photo-lite-2/readme.md create mode 100644 projects/loft-photo-lite-2/styles.css diff --git a/projects/dom/index.js b/projects/dom/index.js new file mode 100644 index 000000000..91d315206 --- /dev/null +++ b/projects/dom/index.js @@ -0,0 +1,121 @@ +/* ДЗ 4 - работа с DOM */ + +/* + Задание 1: + + 1.1: Функция должна создать элемент с тегом DIV + + 1.2: В созданный элемент необходимо поместить текст, переданный в параметр text + + Пример: + createDivWithText('loftschool') // создаст элемент div, поместит в него 'loftschool' и вернет созданный элемент + */ +function createDivWithText(text) { +} + +/* + Задание 2: + + Функция должна вставлять элемент, переданный в параметре what в начало элемента, переданного в параметре where + + Пример: + prepend(document.querySelector('#one'), document.querySelector('#two')) // добавит элемент переданный первым аргументом в начало элемента переданного вторым аргументом + */ +function prepend(what, where) { +} + +/* + Задание 3: + + 3.1: Функция должна перебрать все дочерние элементы узла, переданного в параметре where + + 3.2: Функция должна вернуть массив, состоящий из тех дочерних элементов следующим соседом которых является элемент с тегом P + + Пример: + Представим, что есть разметка: + +
+

+ + +

+ + + findAllPSiblings(document.body) // функция должна вернуть массив с элементами div и span т.к. следующим соседом этих элементов является элемент с тегом P + */ +function findAllPSiblings(where) { +} + +/* + Задание 4: + + Функция представленная ниже, перебирает все дочерние узлы типа "элемент" внутри узла переданного в параметре where и возвращает массив из текстового содержимого найденных элементов + Но похоже, что в код функции закралась ошибка и она работает не так, как описано. + + Необходимо найти и исправить ошибку в коде так, чтобы функция работала так, как описано выше. + + Пример: + Представим, что есть разметка: + +
привет
+
loftschool
+ + + findError(document.body) // функция должна вернуть массив с элементами 'привет' и 'loftschool' + */ +function findError(where) { + const result = []; + + for (const child of where.childNodes) { + result.push(child.textContent); + } + + return result; +} + +/* + Задание 5: + + Функция должна перебрать все дочерние узлы элемента переданного в параметре where и удалить из него все текстовые узлы + + Задачу необходимо решить без использования рекурсии, то есть можно не уходить вглубь дерева. + Так же будьте внимательны при удалении узлов, т.к. можно получить неожиданное поведение при переборе узлов + + Пример: + После выполнения функции, дерево
привет

loftchool!!! + должно быть преобразовано в

+ */ +function deleteTextNodes(where) { +} + +/* + Задание 6 *: + + Необходимо собрать статистику по всем узлам внутри элемента переданного в параметре root и вернуть ее в виде объекта + Статистика должна содержать: + - количество текстовых узлов + - количество элементов каждого класса + - количество элементов каждого тега + Для работы с классами рекомендуется использовать classList + Постарайтесь не создавать глобальных переменных + + Пример: + Для дерева
привет! loftschool
+ должен быть возвращен такой объект: + { + tags: { DIV: 1, B: 2}, + classes: { "some-class-1": 2, "some-class-2": 1 }, + texts: 3 + } + */ +function collectDOMStat(root) { +} + +export { + createDivWithText, + prepend, + findAllPSiblings, + findError, + deleteTextNodes, + collectDOMStat, +}; diff --git a/projects/dom/index.spec.js b/projects/dom/index.spec.js new file mode 100644 index 000000000..3d85e7c67 --- /dev/null +++ b/projects/dom/index.spec.js @@ -0,0 +1,112 @@ +import { randomValue } from '../../scripts/helper'; +import { + collectDOMStat, + createDivWithText, + deleteTextNodes, + findAllPSiblings, + findError, + prepend, +} from './index'; + +function random(type) { + const result = randomValue(type); + + if (type === 'string') { + return encodeURIComponent(result); + } + + return result; +} + +describe('ДЗ 4 - Работа с DOM', () => { + describe('createDivWithText', () => { + it('должна возвращать элемент с тегом DIV', () => { + const text = random('string'); + const result = createDivWithText(text); + + expect(result).toBeInstanceOf(Element); + expect(result.tagName).toBe('DIV'); + }); + + it('должна добавлять текст в элемент', () => { + const text = random('string'); + const result = createDivWithText(text); + + expect(result.textContent).toBe(text); + }); + }); + + describe('prepend', () => { + it('должна добавлять элемент в начало', () => { + const where = document.createElement('div'); + const what = document.createElement('p'); + const whereText = random('string'); + const whatText = random('string'); + + where.innerHTML = `, ${whereText}!`; + what.textContent = whatText; + + prepend(what, where); + + expect(where.firstChild).toBe(what); + expect(where.innerHTML).toBe(`

${whatText}

, ${whereText}!`); + }); + }); + + describe('findAllPSiblings', () => { + it('должна возвращать массив с элементами, соседями которых являются P', () => { + const where = document.createElement('div'); + + where.innerHTML = '

'; + const result = findAllPSiblings(where); + + expect(Array.isArray(result)); + expect(result).toEqual([where.children[0], where.children[3]]); + }); + }); + + describe('findError', () => { + it('должна возвращать массив из текстового содержимого элементов', () => { + const where = document.createElement('div'); + const text1 = random('string'); + const text2 = random('string'); + + where.innerHTML = `
${text1}
,
${text2}
!!!`; + const result = findError(where); + + expect(Array.isArray(result)); + expect(result).toEqual([text1, text2]); + }); + }); + + describe('deleteTextNodes', () => { + it('должна удалить все текстовые узлы', () => { + const where = document.createElement('div'); + + where.innerHTML = `
${random('string')}

${random('string')}`; + deleteTextNodes(where); + + expect(where.innerHTML).toBe('

'); + }); + }); + + describe('collectDOMStat', () => { + it('должна вернуть статистику по переданному дереву', () => { + const where = document.createElement('div'); + const class1 = `class-${random('number')}`; + const class2 = `class-${random('number')}-${random('number')}`; + const text1 = random('string'); + const text2 = random('string'); + const stat = { + tags: { P: 1, B: 2 }, + classes: { [class1]: 2, [class2]: 1 }, + texts: 3, + }; + + where.innerHTML = `

${text1} ${text2}

`; + const result = collectDOMStat(where); + + expect(result).toEqual(stat); + }); + }); +}); diff --git a/projects/loft-photo-lite-2/images/arrow-left.svg b/projects/loft-photo-lite-2/images/arrow-left.svg new file mode 100644 index 000000000..a4e4c339a --- /dev/null +++ b/projects/loft-photo-lite-2/images/arrow-left.svg @@ -0,0 +1,4 @@ + + + + diff --git a/projects/loft-photo-lite-2/images/button.svg b/projects/loft-photo-lite-2/images/button.svg new file mode 100644 index 000000000..6ce85ea9f --- /dev/null +++ b/projects/loft-photo-lite-2/images/button.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/projects/loft-photo-lite-2/images/chat.svg b/projects/loft-photo-lite-2/images/chat.svg new file mode 100644 index 000000000..fc47d01e1 --- /dev/null +++ b/projects/loft-photo-lite-2/images/chat.svg @@ -0,0 +1,3 @@ + + + diff --git a/projects/loft-photo-lite-2/images/exit.svg b/projects/loft-photo-lite-2/images/exit.svg new file mode 100644 index 000000000..d28c122e1 --- /dev/null +++ b/projects/loft-photo-lite-2/images/exit.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/projects/loft-photo-lite-2/images/heart-red.svg b/projects/loft-photo-lite-2/images/heart-red.svg new file mode 100644 index 000000000..e9985dca6 --- /dev/null +++ b/projects/loft-photo-lite-2/images/heart-red.svg @@ -0,0 +1,3 @@ + + + diff --git a/projects/loft-photo-lite-2/images/heart.svg b/projects/loft-photo-lite-2/images/heart.svg new file mode 100644 index 000000000..4bcdacd80 --- /dev/null +++ b/projects/loft-photo-lite-2/images/heart.svg @@ -0,0 +1,3 @@ + + + diff --git a/projects/loft-photo-lite-2/images/logo.svg b/projects/loft-photo-lite-2/images/logo.svg new file mode 100644 index 000000000..12685673d --- /dev/null +++ b/projects/loft-photo-lite-2/images/logo.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/projects/loft-photo-lite-2/images/send.svg b/projects/loft-photo-lite-2/images/send.svg new file mode 100644 index 000000000..5a55b025c --- /dev/null +++ b/projects/loft-photo-lite-2/images/send.svg @@ -0,0 +1,3 @@ + + + diff --git a/projects/loft-photo-lite-2/images/vert1.svg b/projects/loft-photo-lite-2/images/vert1.svg new file mode 100644 index 000000000..d5d86e658 --- /dev/null +++ b/projects/loft-photo-lite-2/images/vert1.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/loft-photo-lite-2/images/vert2.svg b/projects/loft-photo-lite-2/images/vert2.svg new file mode 100644 index 000000000..0f5e75ed2 --- /dev/null +++ b/projects/loft-photo-lite-2/images/vert2.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/loft-photo-lite-2/images/vert3.svg b/projects/loft-photo-lite-2/images/vert3.svg new file mode 100644 index 000000000..7b481af03 --- /dev/null +++ b/projects/loft-photo-lite-2/images/vert3.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/loft-photo-lite-2/index.js b/projects/loft-photo-lite-2/index.js new file mode 100644 index 000000000..482dd617f --- /dev/null +++ b/projects/loft-photo-lite-2/index.js @@ -0,0 +1,8 @@ +import pages from './pages'; +import('./styles.css'); + +const pageNames = ['login', 'main', 'profile']; + +document.addEventListener('click', () => { + pages.openPage('main'); +}); diff --git a/projects/loft-photo-lite-2/layout.html b/projects/loft-photo-lite-2/layout.html new file mode 100644 index 000000000..4f477b34c --- /dev/null +++ b/projects/loft-photo-lite-2/layout.html @@ -0,0 +1,63 @@ + + + + + + Loft Photo + + +
+ + + +
+ + diff --git a/projects/loft-photo-lite-2/pages.js b/projects/loft-photo-lite-2/pages.js new file mode 100644 index 000000000..9f7b54021 --- /dev/null +++ b/projects/loft-photo-lite-2/pages.js @@ -0,0 +1,10 @@ +const pagesMap = { + login: '.page-login', + main: '.page-main', + profile: '.page-profile', +}; + +export default { + openPage(name) { + }, +}; diff --git a/projects/loft-photo-lite-2/readme.md b/projects/loft-photo-lite-2/readme.md new file mode 100644 index 000000000..ab89a239e --- /dev/null +++ b/projects/loft-photo-lite-2/readme.md @@ -0,0 +1,29 @@ +## Работа с DOM + +### Часть 1 + +В [layout.html](layout.html) находятся три div-а с классами: + +- `page-login` +- `page-main` +- `page-profile` + +В каждом из них находится разметка соответствующей страницы. +div-ы скрыты при помощи класса `hidden`. + +В файле [pages.js](pages.js) реализуйте метод `openPage(name)` который должен "открывать" страницу по ее имени. +Например: + +```js +pages.openPage('main'); // сделать видимым элемент с классом page-main +pages.openPage('profile'); // сделать видимым элемент с классом page-profile, а page-main скрыть +pages.openPage('login'); // сделать видимым элемент с классом page-login, а page-profile скрыть +``` + +Таким образом, одновременно можно быть "открыта" только одна страница + +### Часть 2 + +В файле [index.js](index.js) добавьте обработчик кликов на document и напишите его логику таким образом, чтобы при каждом клике "открывалась" случайная страница + +> Можно использовать `getRandomElement` из ДЗ предыдущей недели diff --git a/projects/loft-photo-lite-2/styles.css b/projects/loft-photo-lite-2/styles.css new file mode 100644 index 000000000..62d5fba21 --- /dev/null +++ b/projects/loft-photo-lite-2/styles.css @@ -0,0 +1,348 @@ +/* base */ + +body { + font-family: "Roboto Light", Geneva, Arial, Helvetica, sans-serif; +} + +.hidden { + display: none !important; +} + +a { + text-decoration: none; +} + +/* app */ + +#app { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: flex; + + align-items: center; + justify-content: center; +} + +.page { + height: 100%; + width: 360px; + position: relative; +} + +/* page login */ + +.page-login { + display: flex; + justify-content: center; + background: #1C1B1F; +} + +.page-login-button { + border: none; + background: url('images/button.svg'); + width: 219px; + height: 40px; + position: absolute; + bottom: 60px; + margin: 0 auto; +} + +.page-login-logo { + top: 429px; + position: absolute; + gap: 16px; + display: flex; + flex-direction: column; + align-items: center; +} + +.page-login-image { + width: 147px; + height: 24px; + background: url('images/logo.svg'); +} + +.page-login-text { + font-size: 14px; + line-height: 20px; + text-align: center; + width: 237px; + color: #B0B0B0; +} + +.page-login-vert1, .page-login-vert2, .page-login-vert3 { + width: 71px; + height: 333px; + position: absolute; +} + +.page-login-vert1 { + top: 59px; + left: 49px; + background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert1.svg'); +} + +.page-login-vert2 { + top: 81px; + left: 144px; + background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert2.svg'); +} + +.page-login-vert3 { + top: 59px; + left: 239px; + background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert3.svg'); +} + +/* page main */ + +.page-main .component-header { + position: absolute; + display: flex; + height: 80px; + top: 0; + left: 0; + right: 0; + background: rgba(0 0 0 / 25%); + padding: 0 24px; +} + +.page-main .component-header-profile-link { + display: flex; + align-items: center; +} + +.page-main .component-header-photo { + width: 40px; + height: 40px; + border-radius: 50%; + flex-shrink: 0; +} + +.page-main .component-header-name { + margin-left: 8px; + font-weight: 400; + font-size: 16px; + color: white; +} + +.page-main .component-footer { + position: absolute; + display: flex; + height: 80px; + bottom: 0; + left: 0; + right: 0; + background: rgba(0 0 0 / 25%); + padding: 0 24px; +} + +.page-main .component-footer-container { + display: flex; + align-items: center; + width: 100%; +} + +.page-main .component-footer-container-profile-link { + margin-left: auto; +} + +.page-main .component-footer-photo { + width: 40px; + height: 40px; + border-radius: 50%; +} + +.page-main .component-footer-container-social-comments, +.page-main .component-footer-container-social-likes { + color: white; + display: flex; + align-items: center; +} + +.page-main .component-footer-container-social-comments:before, +.page-main .component-footer-container-social-likes:before { + display: inline-block; + content: ''; + width: 20px; + height: 20px; + margin-right: 6px; +} + +.page-main .component-footer-container-social-comments:before { + background: url("images/chat.svg"); +} + +.page-main .component-footer-container-social-likes:before { + background: url("images/heart.svg"); + margin-left: 18px; +} + +.page-main .component-footer-container-social-likes.liked:before { + background: url("images/heart-red.svg"); + margin-left: 18px; +} + +.page-main .component-photo { + height: 100%; + width: 360px; + position: relative; + + background-size: cover; + background-position: center; +} + +.component-comments { + position: fixed; + bottom: 0; + left: 0; + right: 0; + top: 0; + background: rgba(0, 0, 0, 0.4); +} + +.component-comments-container { + position: absolute; + display: flex; + flex-direction: column; + top: 50vh; + bottom: 0; + left: 0; + right: 0; + padding: 16px; + border-radius: 28px 28px 0 0; + background: white; +} + +.component-comments-container-title { + font-size: 14px; + text-align: center; + width: 100%; +} + +.component-comments-container-list { + margin-top: 24px; + flex-grow: 1; + display: flex; + gap: 12px; + flex-direction: column; + overflow-y: auto; + margin-bottom: 14px +} + +.component-comments-container-form { + display: flex; + align-items: center; + gap: 16px; + height: 48px; +} + +.component-comments-container-form-input { + box-sizing: border-box; + border: 1px solid #E0E0E0; + border-radius: 32px; + flex-grow: 1; + height: 48px; +} + +.component-comments-container-form-input, +.component-comments-container-form-input, +.component-comments-container-form-input, +.component-comments-container-form-input { + padding: 14px 16px; +} + +.component-comments-container-form-send { + background: url('images/send.svg'); + width: 40px; + height: 40px; +} + +.component-comment { + display: flex; + gap: 8px +} + +.component-comment-photo { + width: 24px; + height: 24px; + border-radius: 50%; + background-position: center; + background-size: cover; +} + +.component-comment-content { + flex-direction: column; +} + +.component-comment-name { + font-size: 12px; +} + +.component-comment-text { + font-size: 14px; +} + +/* page profile */ + +.page-profile { + margin-top: 52px; +} + +.page-profile-back { + background: url('images/arrow-left.svg'); + width: 24px; + height: 24px; + + position: absolute; + left: 24px; +} + +.page-profile-exit { + background: url('images/exit.svg'); + width: 24px; + height: 24px; + + position: absolute; + right: 24px; +} + +.component-user-photos { + display: flex; + flex-wrap: wrap; + gap: 8px; + padding: 24px 16px 16px 16px; +} + +.component-user-photo { + width: 104px; + height: 104px; + background-size: cover; + background-repeat: no-repeat; + background-position: center; +} + +.page-profile .component-user-info { + display: flex; + flex-direction: column; + align-items: center; +} + +.page-profile .component-user-info-photo { + height: 72px; + width: 72px; + border-radius: 50%; + + background-size: cover; + background-position: center; +} + +.page-profile .component-user-info-name { + font-weight: 400; + font-size: 18px; + line-height: 26px; + margin-top: 8px; +} \ No newline at end of file From 505ad4766cd13ae6e8bde57d94e168909a43188e Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Sat, 15 Apr 2023 16:56:39 +0300 Subject: [PATCH 2/4] update --- .../loft-photo-lite-2/images/arrow-left.svg | 4 - projects/loft-photo-lite-2/images/button.svg | 17 - projects/loft-photo-lite-2/images/chat.svg | 3 - projects/loft-photo-lite-2/images/exit.svg | 5 - .../loft-photo-lite-2/images/heart-red.svg | 3 - projects/loft-photo-lite-2/images/heart.svg | 3 - projects/loft-photo-lite-2/images/logo.svg | 11 - projects/loft-photo-lite-2/images/send.svg | 3 - projects/loft-photo-lite-2/images/vert1.svg | 22 -- projects/loft-photo-lite-2/images/vert2.svg | 22 -- projects/loft-photo-lite-2/images/vert3.svg | 22 -- projects/loft-photo-lite-2/index.js | 8 - projects/loft-photo-lite-2/layout.html | 63 ---- projects/loft-photo-lite-2/pages.js | 10 - projects/loft-photo-lite-2/readme.md | 29 -- projects/loft-photo-lite-2/styles.css | 348 ------------------ 16 files changed, 573 deletions(-) delete mode 100644 projects/loft-photo-lite-2/images/arrow-left.svg delete mode 100644 projects/loft-photo-lite-2/images/button.svg delete mode 100644 projects/loft-photo-lite-2/images/chat.svg delete mode 100644 projects/loft-photo-lite-2/images/exit.svg delete mode 100644 projects/loft-photo-lite-2/images/heart-red.svg delete mode 100644 projects/loft-photo-lite-2/images/heart.svg delete mode 100644 projects/loft-photo-lite-2/images/logo.svg delete mode 100644 projects/loft-photo-lite-2/images/send.svg delete mode 100644 projects/loft-photo-lite-2/images/vert1.svg delete mode 100644 projects/loft-photo-lite-2/images/vert2.svg delete mode 100644 projects/loft-photo-lite-2/images/vert3.svg delete mode 100644 projects/loft-photo-lite-2/index.js delete mode 100644 projects/loft-photo-lite-2/layout.html delete mode 100644 projects/loft-photo-lite-2/pages.js delete mode 100644 projects/loft-photo-lite-2/readme.md delete mode 100644 projects/loft-photo-lite-2/styles.css diff --git a/projects/loft-photo-lite-2/images/arrow-left.svg b/projects/loft-photo-lite-2/images/arrow-left.svg deleted file mode 100644 index a4e4c339a..000000000 --- a/projects/loft-photo-lite-2/images/arrow-left.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/projects/loft-photo-lite-2/images/button.svg b/projects/loft-photo-lite-2/images/button.svg deleted file mode 100644 index 6ce85ea9f..000000000 --- a/projects/loft-photo-lite-2/images/button.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/projects/loft-photo-lite-2/images/chat.svg b/projects/loft-photo-lite-2/images/chat.svg deleted file mode 100644 index fc47d01e1..000000000 --- a/projects/loft-photo-lite-2/images/chat.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/projects/loft-photo-lite-2/images/exit.svg b/projects/loft-photo-lite-2/images/exit.svg deleted file mode 100644 index d28c122e1..000000000 --- a/projects/loft-photo-lite-2/images/exit.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/projects/loft-photo-lite-2/images/heart-red.svg b/projects/loft-photo-lite-2/images/heart-red.svg deleted file mode 100644 index e9985dca6..000000000 --- a/projects/loft-photo-lite-2/images/heart-red.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/projects/loft-photo-lite-2/images/heart.svg b/projects/loft-photo-lite-2/images/heart.svg deleted file mode 100644 index 4bcdacd80..000000000 --- a/projects/loft-photo-lite-2/images/heart.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/projects/loft-photo-lite-2/images/logo.svg b/projects/loft-photo-lite-2/images/logo.svg deleted file mode 100644 index 12685673d..000000000 --- a/projects/loft-photo-lite-2/images/logo.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/projects/loft-photo-lite-2/images/send.svg b/projects/loft-photo-lite-2/images/send.svg deleted file mode 100644 index 5a55b025c..000000000 --- a/projects/loft-photo-lite-2/images/send.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/projects/loft-photo-lite-2/images/vert1.svg b/projects/loft-photo-lite-2/images/vert1.svg deleted file mode 100644 index d5d86e658..000000000 --- a/projects/loft-photo-lite-2/images/vert1.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/loft-photo-lite-2/images/vert2.svg b/projects/loft-photo-lite-2/images/vert2.svg deleted file mode 100644 index 0f5e75ed2..000000000 --- a/projects/loft-photo-lite-2/images/vert2.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/loft-photo-lite-2/images/vert3.svg b/projects/loft-photo-lite-2/images/vert3.svg deleted file mode 100644 index 7b481af03..000000000 --- a/projects/loft-photo-lite-2/images/vert3.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/projects/loft-photo-lite-2/index.js b/projects/loft-photo-lite-2/index.js deleted file mode 100644 index 482dd617f..000000000 --- a/projects/loft-photo-lite-2/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import pages from './pages'; -import('./styles.css'); - -const pageNames = ['login', 'main', 'profile']; - -document.addEventListener('click', () => { - pages.openPage('main'); -}); diff --git a/projects/loft-photo-lite-2/layout.html b/projects/loft-photo-lite-2/layout.html deleted file mode 100644 index 4f477b34c..000000000 --- a/projects/loft-photo-lite-2/layout.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - Loft Photo - - -
- - - -
- - diff --git a/projects/loft-photo-lite-2/pages.js b/projects/loft-photo-lite-2/pages.js deleted file mode 100644 index 9f7b54021..000000000 --- a/projects/loft-photo-lite-2/pages.js +++ /dev/null @@ -1,10 +0,0 @@ -const pagesMap = { - login: '.page-login', - main: '.page-main', - profile: '.page-profile', -}; - -export default { - openPage(name) { - }, -}; diff --git a/projects/loft-photo-lite-2/readme.md b/projects/loft-photo-lite-2/readme.md deleted file mode 100644 index ab89a239e..000000000 --- a/projects/loft-photo-lite-2/readme.md +++ /dev/null @@ -1,29 +0,0 @@ -## Работа с DOM - -### Часть 1 - -В [layout.html](layout.html) находятся три div-а с классами: - -- `page-login` -- `page-main` -- `page-profile` - -В каждом из них находится разметка соответствующей страницы. -div-ы скрыты при помощи класса `hidden`. - -В файле [pages.js](pages.js) реализуйте метод `openPage(name)` который должен "открывать" страницу по ее имени. -Например: - -```js -pages.openPage('main'); // сделать видимым элемент с классом page-main -pages.openPage('profile'); // сделать видимым элемент с классом page-profile, а page-main скрыть -pages.openPage('login'); // сделать видимым элемент с классом page-login, а page-profile скрыть -``` - -Таким образом, одновременно можно быть "открыта" только одна страница - -### Часть 2 - -В файле [index.js](index.js) добавьте обработчик кликов на document и напишите его логику таким образом, чтобы при каждом клике "открывалась" случайная страница - -> Можно использовать `getRandomElement` из ДЗ предыдущей недели diff --git a/projects/loft-photo-lite-2/styles.css b/projects/loft-photo-lite-2/styles.css deleted file mode 100644 index 62d5fba21..000000000 --- a/projects/loft-photo-lite-2/styles.css +++ /dev/null @@ -1,348 +0,0 @@ -/* base */ - -body { - font-family: "Roboto Light", Geneva, Arial, Helvetica, sans-serif; -} - -.hidden { - display: none !important; -} - -a { - text-decoration: none; -} - -/* app */ - -#app { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - display: flex; - - align-items: center; - justify-content: center; -} - -.page { - height: 100%; - width: 360px; - position: relative; -} - -/* page login */ - -.page-login { - display: flex; - justify-content: center; - background: #1C1B1F; -} - -.page-login-button { - border: none; - background: url('images/button.svg'); - width: 219px; - height: 40px; - position: absolute; - bottom: 60px; - margin: 0 auto; -} - -.page-login-logo { - top: 429px; - position: absolute; - gap: 16px; - display: flex; - flex-direction: column; - align-items: center; -} - -.page-login-image { - width: 147px; - height: 24px; - background: url('images/logo.svg'); -} - -.page-login-text { - font-size: 14px; - line-height: 20px; - text-align: center; - width: 237px; - color: #B0B0B0; -} - -.page-login-vert1, .page-login-vert2, .page-login-vert3 { - width: 71px; - height: 333px; - position: absolute; -} - -.page-login-vert1 { - top: 59px; - left: 49px; - background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert1.svg'); -} - -.page-login-vert2 { - top: 81px; - left: 144px; - background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert2.svg'); -} - -.page-login-vert3 { - top: 59px; - left: 239px; - background: linear-gradient(180deg, rgba(28, 27, 31, 0) 80%, #1C1B1F 100%), url('images/vert3.svg'); -} - -/* page main */ - -.page-main .component-header { - position: absolute; - display: flex; - height: 80px; - top: 0; - left: 0; - right: 0; - background: rgba(0 0 0 / 25%); - padding: 0 24px; -} - -.page-main .component-header-profile-link { - display: flex; - align-items: center; -} - -.page-main .component-header-photo { - width: 40px; - height: 40px; - border-radius: 50%; - flex-shrink: 0; -} - -.page-main .component-header-name { - margin-left: 8px; - font-weight: 400; - font-size: 16px; - color: white; -} - -.page-main .component-footer { - position: absolute; - display: flex; - height: 80px; - bottom: 0; - left: 0; - right: 0; - background: rgba(0 0 0 / 25%); - padding: 0 24px; -} - -.page-main .component-footer-container { - display: flex; - align-items: center; - width: 100%; -} - -.page-main .component-footer-container-profile-link { - margin-left: auto; -} - -.page-main .component-footer-photo { - width: 40px; - height: 40px; - border-radius: 50%; -} - -.page-main .component-footer-container-social-comments, -.page-main .component-footer-container-social-likes { - color: white; - display: flex; - align-items: center; -} - -.page-main .component-footer-container-social-comments:before, -.page-main .component-footer-container-social-likes:before { - display: inline-block; - content: ''; - width: 20px; - height: 20px; - margin-right: 6px; -} - -.page-main .component-footer-container-social-comments:before { - background: url("images/chat.svg"); -} - -.page-main .component-footer-container-social-likes:before { - background: url("images/heart.svg"); - margin-left: 18px; -} - -.page-main .component-footer-container-social-likes.liked:before { - background: url("images/heart-red.svg"); - margin-left: 18px; -} - -.page-main .component-photo { - height: 100%; - width: 360px; - position: relative; - - background-size: cover; - background-position: center; -} - -.component-comments { - position: fixed; - bottom: 0; - left: 0; - right: 0; - top: 0; - background: rgba(0, 0, 0, 0.4); -} - -.component-comments-container { - position: absolute; - display: flex; - flex-direction: column; - top: 50vh; - bottom: 0; - left: 0; - right: 0; - padding: 16px; - border-radius: 28px 28px 0 0; - background: white; -} - -.component-comments-container-title { - font-size: 14px; - text-align: center; - width: 100%; -} - -.component-comments-container-list { - margin-top: 24px; - flex-grow: 1; - display: flex; - gap: 12px; - flex-direction: column; - overflow-y: auto; - margin-bottom: 14px -} - -.component-comments-container-form { - display: flex; - align-items: center; - gap: 16px; - height: 48px; -} - -.component-comments-container-form-input { - box-sizing: border-box; - border: 1px solid #E0E0E0; - border-radius: 32px; - flex-grow: 1; - height: 48px; -} - -.component-comments-container-form-input, -.component-comments-container-form-input, -.component-comments-container-form-input, -.component-comments-container-form-input { - padding: 14px 16px; -} - -.component-comments-container-form-send { - background: url('images/send.svg'); - width: 40px; - height: 40px; -} - -.component-comment { - display: flex; - gap: 8px -} - -.component-comment-photo { - width: 24px; - height: 24px; - border-radius: 50%; - background-position: center; - background-size: cover; -} - -.component-comment-content { - flex-direction: column; -} - -.component-comment-name { - font-size: 12px; -} - -.component-comment-text { - font-size: 14px; -} - -/* page profile */ - -.page-profile { - margin-top: 52px; -} - -.page-profile-back { - background: url('images/arrow-left.svg'); - width: 24px; - height: 24px; - - position: absolute; - left: 24px; -} - -.page-profile-exit { - background: url('images/exit.svg'); - width: 24px; - height: 24px; - - position: absolute; - right: 24px; -} - -.component-user-photos { - display: flex; - flex-wrap: wrap; - gap: 8px; - padding: 24px 16px 16px 16px; -} - -.component-user-photo { - width: 104px; - height: 104px; - background-size: cover; - background-repeat: no-repeat; - background-position: center; -} - -.page-profile .component-user-info { - display: flex; - flex-direction: column; - align-items: center; -} - -.page-profile .component-user-info-photo { - height: 72px; - width: 72px; - border-radius: 50%; - - background-size: cover; - background-position: center; -} - -.page-profile .component-user-info-name { - font-weight: 400; - font-size: 18px; - line-height: 26px; - margin-top: 8px; -} \ No newline at end of file From 74cf7887184bd3fda103db2e8dd28f84650e73cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9?= Date: Thu, 18 Jan 2024 16:31:16 +0500 Subject: [PATCH 3/4] =?UTF-8?q?3=D1=8F=20=D0=BD=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=B4=D0=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 274 +++++++++++++++++++++++++++--------------- package.json | 4 +- projects/dom/index.js | 82 +++++++++++-- 3 files changed, 251 insertions(+), 109 deletions(-) diff --git a/package-lock.json b/package-lock.json index 15211bdad..498ab645c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,8 +17,8 @@ "@babel/runtime": "^7.21.0", "@types/jest": "^29.4.0", "@types/node": "^16.18.13", - "@typescript-eslint/eslint-plugin": "^5.49.0", - "@typescript-eslint/parser": "^5.49.0", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", "babel-jest": "^29.4.3", "babel-loader": "^9.1.2", "css-loader": "^6.7.3", @@ -1785,6 +1785,42 @@ "node": ">=10.0.0" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", @@ -3009,19 +3045,19 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.53.0.tgz", - "integrity": "sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/type-utils": "5.53.0", - "@typescript-eslint/utils": "5.53.0", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" }, @@ -3076,14 +3112,14 @@ "dev": true }, "node_modules/@typescript-eslint/parser": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.53.0.tgz", - "integrity": "sha512-MKBw9i0DLYlmdOb3Oq/526+al20AJZpANdT6Ct9ffxcV8nKCHz63t/S0IhlTFNsBIHJv+GY5SFJ0XfqVeydQrQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/typescript-estree": "5.53.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" }, "engines": { @@ -3103,13 +3139,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.53.0.tgz", - "integrity": "sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/visitor-keys": "5.53.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3120,13 +3156,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.53.0.tgz", - "integrity": "sha512-HO2hh0fmtqNLzTAme/KnND5uFNwbsdYhCZghK2SoxGp3Ifn2emv+hi0PBUjzzSh0dstUIFqOj3bp0AwQlK4OWw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.53.0", - "@typescript-eslint/utils": "5.53.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -3147,9 +3183,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.53.0.tgz", - "integrity": "sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3160,13 +3196,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz", - "integrity": "sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/visitor-keys": "5.53.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3199,9 +3235,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -3220,18 +3256,18 @@ "dev": true }, "node_modules/@typescript-eslint/utils": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.53.0.tgz", - "integrity": "sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/typescript-estree": "5.53.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "engines": { @@ -3279,12 +3315,12 @@ "dev": true }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz", - "integrity": "sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -3296,12 +3332,15 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@webassemblyjs/ast": { @@ -6238,6 +6277,12 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -13582,6 +13627,29 @@ "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "dev": true }, + "@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true + } + } + }, + "@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true + }, "@eslint/eslintrc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", @@ -14596,19 +14664,19 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.53.0.tgz", - "integrity": "sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/type-utils": "5.53.0", - "@typescript-eslint/utils": "5.53.0", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" }, @@ -14640,53 +14708,53 @@ } }, "@typescript-eslint/parser": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.53.0.tgz", - "integrity": "sha512-MKBw9i0DLYlmdOb3Oq/526+al20AJZpANdT6Ct9ffxcV8nKCHz63t/S0IhlTFNsBIHJv+GY5SFJ0XfqVeydQrQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/typescript-estree": "5.53.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.53.0.tgz", - "integrity": "sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/visitor-keys": "5.53.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" } }, "@typescript-eslint/type-utils": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.53.0.tgz", - "integrity": "sha512-HO2hh0fmtqNLzTAme/KnND5uFNwbsdYhCZghK2SoxGp3Ifn2emv+hi0PBUjzzSh0dstUIFqOj3bp0AwQlK4OWw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.53.0", - "@typescript-eslint/utils": "5.53.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.53.0.tgz", - "integrity": "sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz", - "integrity": "sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/visitor-keys": "5.53.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -14704,9 +14772,9 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -14721,18 +14789,18 @@ } }, "@typescript-eslint/utils": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.53.0.tgz", - "integrity": "sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, "requires": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/typescript-estree": "5.53.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "dependencies": { @@ -14763,19 +14831,19 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz", - "integrity": "sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" }, "dependencies": { "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true } } @@ -17011,6 +17079,12 @@ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", "dev": true }, + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, "handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", diff --git a/package.json b/package.json index 88a301fd2..0074c2ca4 100644 --- a/package.json +++ b/package.json @@ -29,10 +29,10 @@ "@babel/preset-env": "^7.20.2", "@babel/preset-typescript": "^7.21.0", "@babel/runtime": "^7.21.0", - "@typescript-eslint/eslint-plugin": "^5.49.0", - "@typescript-eslint/parser": "^5.49.0", "@types/jest": "^29.4.0", "@types/node": "^16.18.13", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", "babel-jest": "^29.4.3", "babel-loader": "^9.1.2", "css-loader": "^6.7.3", diff --git a/projects/dom/index.js b/projects/dom/index.js index 91d315206..9ba39188a 100644 --- a/projects/dom/index.js +++ b/projects/dom/index.js @@ -8,11 +8,17 @@ 1.2: В созданный элемент необходимо поместить текст, переданный в параметр text Пример: - createDivWithText('loftschool') // создаст элемент div, поместит в него 'loftschool' и вернет созданный элемент + createDivWithText('loftSchool') // создаст элемент div, поместит в него 'loftSchool' и вернет созданный элемент */ function createDivWithText(text) { + const divElement = document.createElement('div'); + divElement.textContent = text; + return divElement; } +const myDiv = createDivWithText('loftSchool'); +console.log(myDiv); + /* Задание 2: @@ -22,8 +28,19 @@ function createDivWithText(text) { prepend(document.querySelector('#one'), document.querySelector('#two')) // добавит элемент переданный первым аргументом в начало элемента переданного вторым аргументом */ function prepend(what, where) { + if (!what || !where) { + console.error('Некорректные аргументы. Пожалуйста, укажите оба элемента.'); + return; + } + + where.insertBefore(what, where.firstChild); } +const elementToInsert = document.createElement('div'); +elementToInsert.textContent = 'Inserted Element'; + +const targetElement = document.querySelector('#target'); +prepend(elementToInsert, targetElement); /* Задание 3: @@ -44,6 +61,17 @@ function prepend(what, where) { findAllPSiblings(document.body) // функция должна вернуть массив с элементами div и span т.к. следующим соседом этих элементов является элемент с тегом P */ function findAllPSiblings(where) { + const result = []; + + const children = where.children; + + for (let i = 0; i < children.length; i++) { + if (i + 1 < children.length && children[i + 1].tagName === 'P') { + result.push(children[i]); + } + } + + return result; } /* @@ -58,10 +86,10 @@ function findAllPSiblings(where) { Представим, что есть разметка:
привет
-
loftschool
+
loftSchool
- findError(document.body) // функция должна вернуть массив с элементами 'привет' и 'loftschool' + findError(document.body) // функция должна вернуть массив с элементами 'привет' и 'loftSchool' */ function findError(where) { const result = []; @@ -82,12 +110,22 @@ function findError(where) { Так же будьте внимательны при удалении узлов, т.к. можно получить неожиданное поведение при переборе узлов Пример: - После выполнения функции, дерево
привет

loftchool!!! - должно быть преобразовано в

+ После выполнения функции, дерево
привет

loftSchool!!! + Должно быть преобразовано в

*/ function deleteTextNodes(where) { -} + const children = where.childNodes; + for (let i = children.length - 1; i >= 0; i--) { + const child = children[i]; + + if (child.nodeType === Node.TEXT_NODE) { + where.removeChild(child); + } else if (child.nodeType === Node.ELEMENT_NODE) { + deleteTextNodes(child); + } + } +} /* Задание 6 *: @@ -100,7 +138,7 @@ function deleteTextNodes(where) { Постарайтесь не создавать глобальных переменных Пример: - Для дерева
привет! loftschool
+ Для дерева
привет! loftSchool
должен быть возвращен такой объект: { tags: { DIV: 1, B: 2}, @@ -109,6 +147,36 @@ function deleteTextNodes(where) { } */ function collectDOMStat(root) { + const statistics = { + tags: {}, + classes: {}, + texts: 0, + }; + + function traverse(node) { + if (node.nodeType === Node.TEXT_NODE) { + statistics.texts++; + } + if (node.nodeType === Node.ELEMENT_NODE) { + const tagName = node.tagName.toUpperCase(); + statistics.tags[tagName] = (statistics.tags[tagName] || 0) + 1; + + const classList = node.classList; + if (classList && classList.length > 0) { + classList.forEach((className) => { + statistics.classes[className] = (statistics.classes[className] || 0) + 1; + }); + } + + for (const childNode of node.childNodes) { + traverse(childNode); + } + } + } + + traverse(root); + + return statistics; } export { From 6c624c404763b3bf75ec40bcc1ab348df8e187b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9?= Date: Tue, 6 Feb 2024 16:44:08 +0500 Subject: [PATCH 4/4] =?UTF-8?q?3=D1=8F=20=D0=BD=D0=B5=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=B4=D0=B7=20=D0=BF=D0=BE=D0=B4=D1=87=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D0=B8=D0=BB=20=D0=BB=D0=BE=D0=B3=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- projects/dom/index.js | 245 ++++++++++++++++++++---------------------- 1 file changed, 114 insertions(+), 131 deletions(-) diff --git a/projects/dom/index.js b/projects/dom/index.js index 9ba39188a..273af2257 100644 --- a/projects/dom/index.js +++ b/projects/dom/index.js @@ -1,14 +1,16 @@ -/* ДЗ 4 - работа с DOM */ - -/* - Задание 1: - - 1.1: Функция должна создать элемент с тегом DIV - - 1.2: В созданный элемент необходимо поместить текст, переданный в параметр text +/** + * ДЗ 4 - работа с DOM + */ - Пример: - createDivWithText('loftSchool') // создаст элемент div, поместит в него 'loftSchool' и вернет созданный элемент +/** + * Задание 1: + * + * 1.1: Функция должна создать элемент с тегом DIV + * + * 1.2: В созданный элемент необходимо поместить текст, переданный в параметр text + * + * Пример: + * createDivWithText('loftSchool') // создаст элемент div, поместит в него 'loftSchool' и вернет созданный элемент */ function createDivWithText(text) { const divElement = document.createElement('div'); @@ -16,167 +18,148 @@ function createDivWithText(text) { return divElement; } -const myDiv = createDivWithText('loftSchool'); -console.log(myDiv); - -/* - Задание 2: - - Функция должна вставлять элемент, переданный в параметре what в начало элемента, переданного в параметре where - - Пример: - prepend(document.querySelector('#one'), document.querySelector('#two')) // добавит элемент переданный первым аргументом в начало элемента переданного вторым аргументом +/** + * Задание 2: + * + * Функция должна вставлять элемент, переданный в параметре what в начало элемента, переданного в параметре where + * + * Пример: + * prepend(document.querySelector('#one'), document.querySelector('#two')) // добавит элемент переданный первым аргументом в начало элемента переданного вторым аргументом */ function prepend(what, where) { - if (!what || !where) { - console.error('Некорректные аргументы. Пожалуйста, укажите оба элемента.'); - return; - } - where.insertBefore(what, where.firstChild); } - -const elementToInsert = document.createElement('div'); -elementToInsert.textContent = 'Inserted Element'; - -const targetElement = document.querySelector('#target'); -prepend(elementToInsert, targetElement); -/* - Задание 3: - - 3.1: Функция должна перебрать все дочерние элементы узла, переданного в параметре where - - 3.2: Функция должна вернуть массив, состоящий из тех дочерних элементов следующим соседом которых является элемент с тегом P - - Пример: - Представим, что есть разметка: - -
-

- - -

- - - findAllPSiblings(document.body) // функция должна вернуть массив с элементами div и span т.к. следующим соседом этих элементов является элемент с тегом P +/** + * Задание 3: + * + * 3.1: Функция должна перебрать все дочерние элементы узла, переданного в параметре where + * + * 3.2: Функция должна вернуть массив, состоящий из тех дочерних элементов следующим соседом которых является элемент с тегом P + * + * Пример: + * Представим, что есть разметка: + * + *
+ *

+ * + * + *

+ * + * + * findAllPSiblings(document.body) // функция должна вернуть массив с элементами div и span т.к. следующим соседом этих элементов является элемент с тегом P */ function findAllPSiblings(where) { const result = []; - const children = where.children; - - for (let i = 0; i < children.length; i++) { - if (i + 1 < children.length && children[i + 1].tagName === 'P') { - result.push(children[i]); + for (const el of where.children) { + if (el.nextElementSibling && el.nextElementSibling.tagName === 'P') { + result.push(el); } } return result; } -/* - Задание 4: - - Функция представленная ниже, перебирает все дочерние узлы типа "элемент" внутри узла переданного в параметре where и возвращает массив из текстового содержимого найденных элементов - Но похоже, что в код функции закралась ошибка и она работает не так, как описано. - - Необходимо найти и исправить ошибку в коде так, чтобы функция работала так, как описано выше. - - Пример: - Представим, что есть разметка: - -
привет
-
loftSchool
- - - findError(document.body) // функция должна вернуть массив с элементами 'привет' и 'loftSchool' +/** + * Задание 4: + * + * Функция представленная ниже, перебирает все дочерние узлы типа "элемент" внутри узла переданного в параметре where и возвращает массив из текстового содержимого найденных элементов + * Но похоже, что в код функции закралась ошибка и она работает не так, как описано. + * + * Необходимо найти и исправить ошибку в коде так, чтобы функция работала так, как описано выше. + * + * Пример: + * Представим, что есть разметка: + * + *
привет
+ *
loftSchool
+ * + * + * findError(document.body) // функция должна вернуть массив с элементами 'привет' и 'loftSchool' */ function findError(where) { const result = []; - for (const child of where.childNodes) { + for (const child of where.children) { result.push(child.textContent); } return result; } -/* - Задание 5: - - Функция должна перебрать все дочерние узлы элемента переданного в параметре where и удалить из него все текстовые узлы - - Задачу необходимо решить без использования рекурсии, то есть можно не уходить вглубь дерева. - Так же будьте внимательны при удалении узлов, т.к. можно получить неожиданное поведение при переборе узлов - - Пример: - После выполнения функции, дерево
привет

loftSchool!!! - Должно быть преобразовано в

+/** + * Задание 5: + * + * Функция должна перебрать все дочерние узлы элемента переданного в параметре where и удалить из него все текстовые узлы + * + * Задачу необходимо решить без использования рекурсии, то есть можно не уходить вглубь дерева. + * Так же будьте внимательны при удалении узлов, т.к. можно получить неожиданное поведение при переборе узлов + * + * Пример: + * После выполнения функции, дерево
привет

loftSchool!!! + * Должно быть преобразовано в

*/ function deleteTextNodes(where) { - const children = where.childNodes; - - for (let i = children.length - 1; i >= 0; i--) { - const child = children[i]; + for (let i = 0; i < where.childNodes.length; i++) { + const el = where.childNodes[i]; - if (child.nodeType === Node.TEXT_NODE) { - where.removeChild(child); - } else if (child.nodeType === Node.ELEMENT_NODE) { - deleteTextNodes(child); + if (el.nodeType === Element.TEXT_NODE) { + where.removeChild(el); + i--; } } } -/* - Задание 6 *: - - Необходимо собрать статистику по всем узлам внутри элемента переданного в параметре root и вернуть ее в виде объекта - Статистика должна содержать: - - количество текстовых узлов - - количество элементов каждого класса - - количество элементов каждого тега - Для работы с классами рекомендуется использовать classList - Постарайтесь не создавать глобальных переменных - - Пример: - Для дерева
привет! loftSchool
- должен быть возвращен такой объект: - { - tags: { DIV: 1, B: 2}, - classes: { "some-class-1": 2, "some-class-2": 1 }, - texts: 3 - } +/** + * Задание 6 *: + * + * Необходимо собрать статистику по всем узлам внутри элемента переданного в параметре root и вернуть ее в виде объекта + * Статистика должна содержать: + * - количество текстовых узлов + * - количество элементов каждого класса + * - количество элементов каждого тега + * Для работы с классами рекомендуется использовать classList + * Постарайтесь не создавать глобальных переменных + * + * Пример: + * Для дерева
привет! loftSchool
+ * должен быть возвращен такой объект: + * { + * tags: { DIV: 1, B: 2}, + * classes: { "some-class-1": 2, "some-class-2": 1 }, + * texts: 3 + * } */ function collectDOMStat(root) { - const statistics = { + const stat = { tags: {}, classes: {}, texts: 0, }; - function traverse(node) { - if (node.nodeType === Node.TEXT_NODE) { - statistics.texts++; - } - if (node.nodeType === Node.ELEMENT_NODE) { - const tagName = node.tagName.toUpperCase(); - statistics.tags[tagName] = (statistics.tags[tagName] || 0) + 1; - - const classList = node.classList; - if (classList && classList.length > 0) { - classList.forEach((className) => { - statistics.classes[className] = (statistics.classes[className] || 0) + 1; - }); - } - - for (const childNode of node.childNodes) { - traverse(childNode); + function scan(root) { + for (const child of root.childNodes) { + if (child.nodeType === Node.TEXT_NODE) { + stat.texts++; + } else if (child.nodeType === Node.ELEMENT_NODE) { + if (child.tagName in stat.tags) { + stat.tags[child.tagName]++; + } else { + stat.tags[child.tagName] = 1; + } + + for (const className of child.classList) { + if (className in stat.classes) { + stat.classes[className]++; + } else { + stat.classes[className] = 1; + } + } + scan(child); } } } - - traverse(root); - - return statistics; + scan(root); + return stat; } export {