index.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. /*fetch basic
  2. Исследуйте сайт swapi.dev, рассмотрите JSON-ы, которые предоставляются этим сервисом (например: https://swapi.dev/api/people/1/, https://swapi.dev/api/people/2/, https://swapi.dev/api/starships/12/
  3. С помощью следующего кода считать и вывести информацию о Люке Скайвокере:
  4. fetch('https://swapi.dev/api/people/1/')
  5. .then(res => res.json())
  6. .then(luke => console.log(luke))
  7. Напишите функцию для отображения любого JSON в форме таблицы. Функция должна принимать два параметра:
  8. DOM - элемент, в котором строится таблица
  9. JSON, который нужно отобразить.*/
  10. {
  11. function jsonToTable(parent = document.body, jsonObj){
  12. const jsonTable = document.createElement('table') //Создаём и добавляем в родительский єлемент будущую таблицу
  13. parent.append(jsonTable)
  14. for (const key in jsonObj){
  15. const tr = document.createElement('tr') //одно свойтсво - одна строка
  16. jsonTable.append(tr)
  17. const tdProperty = document.createElement('td') //столбик со свойствами обьекта
  18. tr.append(tdProperty)
  19. tdProperty.innerText = key
  20. const tdValue = document.createElement('td') // столбик со значениями свойств обьекта JSON
  21. tr.append(tdValue)
  22. tdValue.innerText = jsonObj[key]
  23. }
  24. }
  25. fetch('https://swapi.dev/api/people/1/')
  26. .then(res => res.json())
  27. .then(jsonObj => jsonToTable(document.body, jsonObj))
  28. }
  29. /* fetch improved
  30. Расширить функцию отображения:
  31. Если одно из полей строка или массив.
  32. Если строки или строка содержат в себе https://swapi.dev/api/
  33. То выводить вместо текста строки кнопку, при нажатии на которую:
  34. делается fetch данных по этой ссылке
  35. функция отображения запускает сама себя(рекурсивно) для отображения новых данных в том же элементе.*/
  36. {
  37. function buttonVisionText(button, element) {
  38. element.style.display = "block"
  39. button.innerText = 'Скрыть'
  40. button.style.backgroundColor = "SteelBlue"
  41. button.onclick = () => buttonHidetext(button, element)
  42. }
  43. function buttonHidetext(button, element) {
  44. element.style.display = "none"
  45. button.innerText = 'Показать'
  46. button.style.backgroundColor = "darkgrey"
  47. button.onclick = () => buttonVisionText(button, element)
  48. }
  49. function jsonToTable(parent = document.body, jsonObj) {
  50. const jsonTable = document.createElement('table') //Создаём и добавляем в родительский єлемент будущую таблицу
  51. parent.append(jsonTable)
  52. for (const key in jsonObj) {
  53. const tr = document.createElement('tr') //одно свойтсво - одна строка
  54. jsonTable.append(tr)
  55. const tdProperty = document.createElement('td') //столбик со свойствами обьекта
  56. tr.append(tdProperty)
  57. tdProperty.innerText = key
  58. const tdValue = document.createElement('td') // столбик со значениями свойств обьекта JSON
  59. tr.append(tdValue)
  60. //console.log(jsonObj[key])
  61. let regexp = /^\s*https?:\/\/./i; //тут проверяем является ли значение ссылкой
  62. if (regexp.test(jsonObj[key]) && typeof jsonObj[key] === "string") { //если значение ссылка но не массив
  63. const valueDiv = document.createElement('div') //div контейнер внутри ячейки
  64. tdValue.append(valueDiv)
  65. const button = document.createElement('button') // если да то создаём кнопку, текст изначально скрыт
  66. tdValue.append(button)
  67. button.innerText = 'Показать'
  68. //при первом нажатии получаем данные по ссылке, выводим в valueDiv
  69. button.onclick = () => {
  70. fetch(jsonObj[key])
  71. .then(res => res.json())
  72. .then(obj => {
  73. jsonToTable(valueDiv, obj)
  74. button.innerText = 'Cкрыть'
  75. button.style.backgroundColor = "SteelBlue"
  76. button.onclick = () => buttonHidetext(button, valueDiv) //вешаем на кнопку, изменяемый при каждом нажатии, онклик скрывающий или отображающий контент внутри ячейки
  77. })
  78. }
  79. } else if (Array.isArray(jsonObj[key])) {
  80. for (arrayItem of jsonObj[key]) {
  81. console.log(arrayItem)
  82. if (regexp.test(arrayItem) && typeof arrayItem === "string") {
  83. //если значение ссылка и строка
  84. const valueDiv = document.createElement('div') //div контейнер внутри ячейки
  85. tdValue.append(valueDiv)
  86. const button = document.createElement('button') // если да то создаём кнопку, текст изначально скрыт
  87. tdValue.append(button)
  88. button.innerText = 'Показать'
  89. //при первом нажатии получаем данные по ссылке, выводим в valueDiv
  90. button.onclick = () => {
  91. fetch(arrayItem)
  92. .then(res => res.json())
  93. .then(obj => {
  94. jsonToTable(valueDiv, obj)
  95. button.innerText = 'Cкрыть'
  96. button.style.backgroundColor = "SteelBlue"
  97. button.onclick = () => buttonHidetext(button, valueDiv) //вешаем на кнопку, изменяемый при каждом нажатии, онклик скрывающий или отображающий контент внутри ячейки
  98. })
  99. }
  100. } else {
  101. }
  102. }
  103. } else {
  104. tdValue.innerText = jsonObj[key] //если значение не является ссылкой, запихиваем занчение в innertext
  105. }
  106. }
  107. }
  108. fetch('https://swapi.dev/api/people/1/')
  109. .then(res => res.json())
  110. .then(jsonObj => jsonToTable(document.body, jsonObj))
  111. }
  112. /*race
  113. Используя Promise.race запустите запрос на API (swapi.dev) параллельно с delay. По результату определите, что было быстрее, запрос по сети, или определенный интервал времени. Подберите параметр delay так, что бы результат был неизвестен изначально, и при многократных запусках быстрее был то delay, то myfetch. */
  114. {
  115. function delay(ms) {
  116. return new Promise(function (resolve, reject) {
  117. setTimeout(() => resolve('выиграл delay'), ms)
  118. })
  119. }
  120. let p = Promise.race([delay(580), fetch('https://swapi.dev/api/people/1/')
  121. .then(res => res.json())])
  122. p.then((res) => console.log(res))
  123. }
  124. /* Promisify: confirm
  125. Промисифицируйте confirm. Напишите функцию, которая возвращает промис, который переходит в состояние fulfilled при нажатии "OK" и реджектится при нажатии "Cancel". Функция должна принимать строку для confirm: */
  126. {
  127. function confirmPromise(text) {
  128. return new Promise((resolve, reject) => {
  129. let confResult = confirm(text)
  130. if (confResult) resolve()
  131. else reject()
  132. })
  133. }
  134. confirmPromise('Промисы это сложно?').then(
  135. () => console.log('не так уже и сложно'),
  136. () => console.log('respect за усидчивость и внимательность')
  137. )
  138. }
  139. /*Promisify: prompt
  140. Аналогично предыдующему заданию промисифицируйте prompt. В случае нажатия "ОК" промис резолвится и его результатом становится текст, введенный пользователем в окне prompt. В случае нажатия "Отмены" - промис реджектится. Параметром функции будет текст сообщения в prompt*/
  141. {
  142. function promptPromise(text) {
  143. return new Promise((resolve, reject) => {
  144. let promptResult = prompt(text)
  145. if (promptResult) resolve(promptResult)
  146. else reject()
  147. })
  148. }
  149. promptPromise("Как тебя зовут?").then(name => console.log(`Тебя зовут ${name}`), () => console.log('Ну зачем морозиться, нормально же общались'))
  150. }
  151. /*Promisify: LoginForm
  152. Промисифицируйте конструктор LoginForm. В промисифицированную функцию передается DOM-элемент - родитель для формы, В колбэке, предназначенном для получения логина и пароля в момент нажатия кнопки "Login...", который вы назначаете в объекте LoginForm, зарезолвите промис. Результатом промиса должен быть объект с ключами login и password, ключи должны содержать значения полей ввода.*/
  153. {
  154. function loginPromise(parent){
  155. function executor(resolve, reject){
  156. const form = new LoginForm(parent, false)
  157. form.inputButtonOnclick = function () {
  158. //console.log({login: this.getLogin(), password: this.getPass()})
  159. resolve({login: this.getLogin(), password: this.getPass()})
  160. }
  161. }
  162. return new Promise(executor)
  163. }
  164. loginPromise(document.body).then(({login, password}) => console.log(`Вы ввели ${login} и ${password}`))
  165. function LoginForm(parent, passOpenDefault = open){
  166. function Password(parent, open) {
  167. const inputPass = document.createElement('input')
  168. parent.append(inputPass)
  169. const checkboxPass = document.createElement('input')
  170. checkboxPass.type = 'checkbox'
  171. parent.append(checkboxPass)
  172. this.setValue = (value) => {
  173. inputPass.value = value
  174. if (typeof this.onChange === 'function') this.onChange(this.getValue()) // запускается по событию oninput в поле ввода, передает текст в колбэк
  175. } //задает значение
  176. this.getValue = () => inputPass.value //читает значение
  177. this.setOpen = (open) => {
  178. if (open) {
  179. checkboxPass.checked = true
  180. inputPass.type = "text"
  181. }
  182. if (!open) {
  183. checkboxPass.checked = false
  184. inputPass.type = "password"
  185. }
  186. if (typeof this.onOpenChange === 'function') this.onOpenChange(this.getOpen()) // запускается по изменению состояния открытости пароля
  187. } //задает открытость текста в поле ввода
  188. this.getOpen = () => checkboxPass.checked //читает открытость текста в поле ввода
  189. this.setOpen(open)
  190. inputPass.oninput = () => this.setValue(this.getValue())
  191. checkboxPass.oninput = () => this.setOpen(this.getOpen())
  192. }
  193. const LoginForm = document.createElement('div')
  194. parent.append(LoginForm)
  195. const inputLogin = document.createElement('input')
  196. LoginForm.append(inputLogin)
  197. let p = new Password(LoginForm, passOpenDefault)
  198. const inputButton = document.createElement('input')
  199. inputButton.type = 'button'
  200. inputButton.value = 'войти'
  201. LoginForm.append(inputButton)
  202. inputButton.disabled = true
  203. p.onChange = () => checkButtonDisabled()
  204. inputLogin.oninput = () => checkButtonDisabled()
  205. function checkButtonDisabled () {
  206. if (p.getValue() && inputLogin.value) inputButton.disabled = false
  207. else inputButton.disabled = true
  208. }
  209. this.getLogin = () => inputLogin.value
  210. this.setLogin = (value) => {
  211. inputLogin.value = value
  212. checkButtonDisabled()
  213. }
  214. this.getPass = () => p.getValue()
  215. this.setPass = (value) => {
  216. p.setValue(value)
  217. checkButtonDisabled()
  218. }
  219. inputButton.onclick = () => {
  220. if (typeof this.inputButtonOnclick === 'function') this.inputButtonOnclick() //функция при нажатии на кнопку войти
  221. }
  222. }
  223. }