/*fetch basic Исследуйте сайт swapi.dev, рассмотрите JSON-ы, которые предоставляются этим сервисом (например: https://swapi.dev/api/people/1/, https://swapi.dev/api/people/2/, https://swapi.dev/api/starships/12/ С помощью следующего кода считать и вывести информацию о Люке Скайвокере: fetch('https://swapi.dev/api/people/1/') .then(res => res.json()) .then(luke => console.log(luke)) Напишите функцию для отображения любого JSON в форме таблицы. Функция должна принимать два параметра: DOM - элемент, в котором строится таблица JSON, который нужно отобразить.*/ { function jsonToTable(parent = document.body, jsonObj){ const jsonTable = document.createElement('table') //Создаём и добавляем в родительский єлемент будущую таблицу parent.append(jsonTable) for (const key in jsonObj){ const tr = document.createElement('tr') //одно свойтсво - одна строка jsonTable.append(tr) const tdProperty = document.createElement('td') //столбик со свойствами обьекта tr.append(tdProperty) tdProperty.innerText = key const tdValue = document.createElement('td') // столбик со значениями свойств обьекта JSON tr.append(tdValue) tdValue.innerText = jsonObj[key] } } fetch('https://swapi.dev/api/people/1/') .then(res => res.json()) .then(jsonObj => jsonToTable(document.body, jsonObj)) } /* fetch improved Расширить функцию отображения: Если одно из полей строка или массив. Если строки или строка содержат в себе https://swapi.dev/api/ То выводить вместо текста строки кнопку, при нажатии на которую: делается fetch данных по этой ссылке функция отображения запускает сама себя(рекурсивно) для отображения новых данных в том же элементе.*/ { function buttonVisionText(button, element) { element.style.display = "block" button.innerText = 'Скрыть' button.style.backgroundColor = "SteelBlue" button.onclick = () => buttonHidetext(button, element) } function buttonHidetext(button, element) { element.style.display = "none" button.innerText = 'Показать' button.style.backgroundColor = "darkgrey" button.onclick = () => buttonVisionText(button, element) } function jsonToTable(parent = document.body, jsonObj) { const jsonTable = document.createElement('table') //Создаём и добавляем в родительский єлемент будущую таблицу parent.append(jsonTable) for (const key in jsonObj) { const tr = document.createElement('tr') //одно свойтсво - одна строка jsonTable.append(tr) const tdProperty = document.createElement('td') //столбик со свойствами обьекта tr.append(tdProperty) tdProperty.innerText = key const tdValue = document.createElement('td') // столбик со значениями свойств обьекта JSON tr.append(tdValue) //console.log(jsonObj[key]) let regexp = /^\s*https?:\/\/./i; //тут проверяем является ли значение ссылкой if (regexp.test(jsonObj[key]) && typeof jsonObj[key] === "string") { //если значение ссылка но не массив const valueDiv = document.createElement('div') //div контейнер внутри ячейки tdValue.append(valueDiv) const button = document.createElement('button') // если да то создаём кнопку, текст изначально скрыт tdValue.append(button) button.innerText = 'Показать' //при первом нажатии получаем данные по ссылке, выводим в valueDiv button.onclick = () => { fetch(jsonObj[key]) .then(res => res.json()) .then(obj => { jsonToTable(valueDiv, obj) button.innerText = 'Cкрыть' button.style.backgroundColor = "SteelBlue" button.onclick = () => buttonHidetext(button, valueDiv) //вешаем на кнопку, изменяемый при каждом нажатии, онклик скрывающий или отображающий контент внутри ячейки }) } } else if (Array.isArray(jsonObj[key])) { for (arrayItem of jsonObj[key]) { console.log(arrayItem) if (regexp.test(arrayItem) && typeof arrayItem === "string") { //если значение ссылка и строка const valueDiv = document.createElement('div') //div контейнер внутри ячейки tdValue.append(valueDiv) const button = document.createElement('button') // если да то создаём кнопку, текст изначально скрыт tdValue.append(button) button.innerText = 'Показать' //при первом нажатии получаем данные по ссылке, выводим в valueDiv button.onclick = () => { fetch(arrayItem) .then(res => res.json()) .then(obj => { jsonToTable(valueDiv, obj) button.innerText = 'Cкрыть' button.style.backgroundColor = "SteelBlue" button.onclick = () => buttonHidetext(button, valueDiv) //вешаем на кнопку, изменяемый при каждом нажатии, онклик скрывающий или отображающий контент внутри ячейки }) } } else { } } } else { tdValue.innerText = jsonObj[key] //если значение не является ссылкой, запихиваем занчение в innertext } } } fetch('https://swapi.dev/api/people/1/') .then(res => res.json()) .then(jsonObj => jsonToTable(document.body, jsonObj)) } /*race Используя Promise.race запустите запрос на API (swapi.dev) параллельно с delay. По результату определите, что было быстрее, запрос по сети, или определенный интервал времени. Подберите параметр delay так, что бы результат был неизвестен изначально, и при многократных запусках быстрее был то delay, то myfetch. */ { function delay(ms) { return new Promise(function (resolve, reject) { setTimeout(() => resolve('выиграл delay'), ms) }) } let p = Promise.race([delay(580), fetch('https://swapi.dev/api/people/1/') .then(res => res.json())]) p.then((res) => console.log(res)) } /* Promisify: confirm Промисифицируйте confirm. Напишите функцию, которая возвращает промис, который переходит в состояние fulfilled при нажатии "OK" и реджектится при нажатии "Cancel". Функция должна принимать строку для confirm: */ { function confirmPromise(text) { return new Promise((resolve, reject) => { let confResult = confirm(text) if (confResult) resolve() else reject() }) } confirmPromise('Промисы это сложно?').then( () => console.log('не так уже и сложно'), () => console.log('respect за усидчивость и внимательность') ) } /*Promisify: prompt Аналогично предыдующему заданию промисифицируйте prompt. В случае нажатия "ОК" промис резолвится и его результатом становится текст, введенный пользователем в окне prompt. В случае нажатия "Отмены" - промис реджектится. Параметром функции будет текст сообщения в prompt*/ { function promptPromise(text) { return new Promise((resolve, reject) => { let promptResult = prompt(text) if (promptResult) resolve(promptResult) else reject() }) } promptPromise("Как тебя зовут?").then(name => console.log(`Тебя зовут ${name}`), () => console.log('Ну зачем морозиться, нормально же общались')) } /*Promisify: LoginForm Промисифицируйте конструктор LoginForm. В промисифицированную функцию передается DOM-элемент - родитель для формы, В колбэке, предназначенном для получения логина и пароля в момент нажатия кнопки "Login...", который вы назначаете в объекте LoginForm, зарезолвите промис. Результатом промиса должен быть объект с ключами login и password, ключи должны содержать значения полей ввода.*/ { function loginPromise(parent){ function executor(resolve, reject){ const form = new LoginForm(parent, false) form.inputButtonOnclick = function () { //console.log({login: this.getLogin(), password: this.getPass()}) resolve({login: this.getLogin(), password: this.getPass()}) } } return new Promise(executor) } loginPromise(document.body).then(({login, password}) => console.log(`Вы ввели ${login} и ${password}`)) function LoginForm(parent, passOpenDefault = open){ function Password(parent, open) { const inputPass = document.createElement('input') parent.append(inputPass) const checkboxPass = document.createElement('input') checkboxPass.type = 'checkbox' parent.append(checkboxPass) this.setValue = (value) => { inputPass.value = value if (typeof this.onChange === 'function') this.onChange(this.getValue()) // запускается по событию oninput в поле ввода, передает текст в колбэк } //задает значение this.getValue = () => inputPass.value //читает значение this.setOpen = (open) => { if (open) { checkboxPass.checked = true inputPass.type = "text" } if (!open) { checkboxPass.checked = false inputPass.type = "password" } if (typeof this.onOpenChange === 'function') this.onOpenChange(this.getOpen()) // запускается по изменению состояния открытости пароля } //задает открытость текста в поле ввода this.getOpen = () => checkboxPass.checked //читает открытость текста в поле ввода this.setOpen(open) inputPass.oninput = () => this.setValue(this.getValue()) checkboxPass.oninput = () => this.setOpen(this.getOpen()) } const LoginForm = document.createElement('div') parent.append(LoginForm) const inputLogin = document.createElement('input') LoginForm.append(inputLogin) let p = new Password(LoginForm, passOpenDefault) const inputButton = document.createElement('input') inputButton.type = 'button' inputButton.value = 'войти' LoginForm.append(inputButton) inputButton.disabled = true p.onChange = () => checkButtonDisabled() inputLogin.oninput = () => checkButtonDisabled() function checkButtonDisabled () { if (p.getValue() && inputLogin.value) inputButton.disabled = false else inputButton.disabled = true } this.getLogin = () => inputLogin.value this.setLogin = (value) => { inputLogin.value = value checkButtonDisabled() } this.getPass = () => p.getValue() this.setPass = (value) => { p.setValue(value) checkButtonDisabled() } inputButton.onclick = () => { if (typeof this.inputButtonOnclick === 'function') this.inputButtonOnclick() //функция при нажатии на кнопку войти } } }