From b5fe24eda03ddc948c0beab5ebe9b7a095d7a1da Mon Sep 17 00:00:00 2001 From: Sergey Melyukov Date: Fri, 10 Mar 2023 10:04:26 +0300 Subject: [PATCH 1/3] 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/3] 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 d1598c4e23b5d9eb4306ef76089cb2b1ea07f180 Mon Sep 17 00:00:00 2001 From: lFrodo Date: Mon, 8 May 2023 09:55:45 +0300 Subject: [PATCH 3/3] 3 week --- projects/dom/index.js | 81 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/projects/dom/index.js b/projects/dom/index.js index 91d315206..c3ca940b0 100644 --- a/projects/dom/index.js +++ b/projects/dom/index.js @@ -11,7 +11,11 @@ createDivWithText('loftschool') // создаст элемент div, поместит в него 'loftschool' и вернет созданный элемент */ function createDivWithText(text) { + const element = document.createElement('div'); + element.textContent = text; + return element; } +console.log(createDivWithText('loftschool')); /* Задание 2: @@ -21,9 +25,18 @@ function createDivWithText(text) { Пример: prepend(document.querySelector('#one'), document.querySelector('#two')) // добавит элемент переданный первым аргументом в начало элемента переданного вторым аргументом */ + +const where = document.createElement('div'); +where.id = 'one'; +const what = document.createElement('p'); +what.id = 'two'; + function prepend(what, where) { + where.prepend(what); + return where; } +console.log(prepend(what, where)); /* Задание 3: @@ -44,8 +57,16 @@ function prepend(what, where) { findAllPSiblings(document.body) // функция должна вернуть массив с элементами div и span т.к. следующим соседом этих элементов является элемент с тегом P */ function findAllPSiblings(where) { + let arr = []; + for (const node of where.children) { + if (node.nodeName === 'P') { + arr.push(node.previousElementSibling); + } + } + return arr; } + /* Задание 4: @@ -63,15 +84,17 @@ function findAllPSiblings(where) { findError(document.body) // функция должна вернуть массив с элементами 'привет' и 'loftschool' */ -function findError(where) { - const result = []; - - for (const child of where.childNodes) { - result.push(child.textContent); + function findError(where) { + const result = []; + for (const child of where.childNodes) { + if(child.nodeName === 'DIV'){ + result.push(child.textContent) } - - return result; -} + } + return result; + } + console.log(findError(document.body)) + /* Задание 5: @@ -85,9 +108,15 @@ function findError(where) { После выполнения функции, дерево
привет

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

*/ -function deleteTextNodes(where) { -} - + function deleteTextNodes(where) { + let newBody = where.childNodes + for (const node of newBody){ + if (node.nodeType == 3){ + node.remove(node) + } + } + return newBody + } /* Задание 6 *: @@ -108,7 +137,35 @@ function deleteTextNodes(where) { texts: 3 } */ -function collectDOMStat(root) { + function collectDOMStat(root) { + const stat = { + tags: {}, + classes: {}, + texts: 0 + }; + 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); + } + } + } + scan(root); + return stat; } export {