script.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // fetch basic
  2. // Исследуйте сайт swapi.dev, рассмотрите JSON-ы, которые предоставляются этим сервисом
  3. // (например: https://swapi.dev/api/people/1/, https://swapi.dev/api/people/2/, https://swapi.dev/api/starships/12/
  4. // С помощью следующего кода считать и вывести информацию о Люке Скайвокере:
  5. // Напишите функцию для отображения любого JSON в форме таблицы. Функция должна принимать два параметра:
  6. // DOM - элемент, в котором строится таблица
  7. // JSON, который нужно отобразить.
  8. // fetch improved
  9. // Расширить функцию отображения:
  10. // Если одно из полей строка или массив.
  11. // Если строки или строка содержат в себе https://swapi.dev/api/
  12. // То выводить вместо текста строки кнопку, при нажатии на которую:
  13. // делается fetch данных по этой ссылке
  14. // функция отображения запускает сама себя(рекурсивно) для отображения новых данных в том же элементе.
  15. fetch_basic: {
  16. fetch('https://swapi.dev/api/people/1/')
  17. .then(res => res.json())
  18. .then(luke => {
  19. // console.log(luke);
  20. displayObjAsTable(document.body, luke);
  21. })
  22. function displayObjAsTable(domElement, jsonElement, elemForRemoval) {
  23. let table = document.createElement('table');
  24. table.border = 1;
  25. elemForRemoval?.remove();
  26. domElement.append(table);
  27. Object.keys(jsonElement).forEach(key => {
  28. let tr = document.createElement('tr');
  29. table.append(tr);
  30. let keyTd = document.createElement('td');
  31. keyTd.innerText = key;
  32. tr.append(keyTd);
  33. let valueTd = document.createElement('td');
  34. if (typeof jsonElement[key] == 'string' && jsonElement[key].includes('https://swapi.dev/api/')) {
  35. addButton(jsonElement[key], valueTd);
  36. } else if (Array.isArray(jsonElement[key])) {
  37. jsonElement[key].forEach((el) => {
  38. if (typeof el == 'string' && el.includes('https://swapi.dev/api/')) {
  39. addButton(el, valueTd);
  40. }
  41. });
  42. } else {
  43. valueTd.innerText = jsonElement[key];
  44. }
  45. tr.append(valueTd);
  46. });
  47. }
  48. function addButton(value, valueTd) {
  49. let button = document.createElement('button');
  50. button.innerText = 'Get ' + value.split('api/')[1];
  51. button.addEventListener('click', () => {
  52. fetch(value)
  53. .then(res => res.json())
  54. .then(data => {
  55. displayObjAsTable(valueTd, data, button);
  56. })
  57. });
  58. valueTd.append(button);
  59. }
  60. }
  61. // race
  62. // Используя Promise.race запустите запрос на API (swapi.dev) параллельно с delay. По результату определите,
  63. // что было быстрее, запрос по сети, или определенный интервал времени. Подберите параметр delay так, что бы
  64. // результат был неизвестен изначально, и при многократных запусках быстрее был то delay, то myfetch.
  65. race: {
  66. function delay(ms) {
  67. function executor(fulfill, reject) {
  68. setTimeout(() => fulfill(ms), ms);
  69. }
  70. return new Promise(executor);
  71. }
  72. let myfetch = fetch('https://swapi.dev/api/people/2/');
  73. Promise.race([myfetch, delay(100)]).then((value) => {
  74. console.log(value);
  75. });
  76. }
  77. // Promisify: confirm
  78. // Промисифицируйте confirm. Напишите функцию, которая возвращает промис, который переходит в состояние
  79. // fulfilled при нажатии "OK" и реджектится при нажатии "Cancel". Функция должна принимать строку для confirm:
  80. confirm: {
  81. function confirmPromise(text) {
  82. function executor(fulfill, reject) {
  83. if (confirm(text)) {
  84. fulfill();
  85. } else {
  86. reject();
  87. }
  88. }
  89. return new Promise(executor);
  90. }
  91. confirmPromise('Промисы это сложно?').then(() => console.log('не так уже и сложно'),
  92. () => console.log('respect за усидчивость и внимательность'))
  93. }
  94. // Promisify: prompt
  95. // Аналогично предыдующему заданию промисифицируйте prompt. В случае нажатия "ОК" промис резолвится и его
  96. // результатом становится текст, введенный пользователем в окне prompt. В случае нажатия "Отмены" - промис
  97. // реджектится. Параметром функции будет текст сообщения в prompt
  98. prompt: {
  99. function promptPromise(text) {
  100. function executor(fulfill, reject) {
  101. let answer = prompt(text);
  102. if (answer) {
  103. fulfill(answer);
  104. } else {
  105. reject();
  106. }
  107. }
  108. return new Promise(executor);
  109. }
  110. promptPromise("Как тебя зовут?").then(name => console.log(`Тебя зовут ${name}`),
  111. () => console.log('Ну зачем морозиться, нормально же общались'))
  112. }
  113. // Promisify: LoginForm
  114. // Промисифицируйте конструктор LoginForm. В промисифицированную функцию передается DOM-элемент - родитель для
  115. // формы, В колбэке, предназначенном для получения логина и пароля в момент нажатия кнопки "Login...", который
  116. // вы назначаете в объекте LoginForm, зарезолвите промис. Результатом промиса должен быть объект с ключами
  117. // login и password, ключи должны содержать значения полей ввода.
  118. login_form: {
  119. function LoginForm(parent) {
  120. let form = document.createElement('form');
  121. parent.append(form);
  122. let loginLabel = document.createElement('label');
  123. loginLabel.innerText = 'Login: ';
  124. form.append(loginLabel);
  125. let login = new Login(form);
  126. let passwordLabel = document.createElement('label');
  127. passwordLabel.innerText = 'Password: ';
  128. form.append(passwordLabel);
  129. let password = new Password(form, false);
  130. let submit = document.createElement('button');
  131. submit.innerText = 'Submit';
  132. form.append(submit);
  133. this.validateForm = () => {
  134. if (login.getValue() == '' || password.getValue() == '') {
  135. submit.disabled = true;
  136. } else {
  137. submit.disabled = false;
  138. if (this.onValidForm) {
  139. this.onValidForm();
  140. }
  141. }
  142. }
  143. submit.addEventListener('click', (e) => {
  144. e.preventDefault();
  145. if (this.onSubmitForm) {
  146. this.onSubmitForm();
  147. }
  148. });
  149. this.getLoginValue = () => {
  150. return login.getValue();
  151. }
  152. this.setLoginValue = (value) => {
  153. login.setValue(value);
  154. }
  155. this.getPasswordValue = () => {
  156. return password.getValue();
  157. }
  158. this.setPasswordValue = (value) => {
  159. password.setValue(value);
  160. }
  161. this.validateForm();
  162. login.onChange = this.validateForm;
  163. password.onChange = this.validateForm;
  164. }
  165. function Login(parent) {
  166. let loginInputEl = document.createElement('input');
  167. loginInputEl.type = 'text';
  168. parent.append(loginInputEl);
  169. loginInputEl.addEventListener('input', (event) => {
  170. if (this.onChange) {
  171. this.onChange();
  172. }
  173. });
  174. this.setValue = (value) => {
  175. loginInputEl.value = value;
  176. }
  177. this.getValue = () => {
  178. return loginInputEl.value;
  179. }
  180. }
  181. function Password(parent, open) {
  182. let passInputEl = document.createElement('input');
  183. parent.append(passInputEl);
  184. let passVisibilityCheckboxEl = document.createElement('input');
  185. passVisibilityCheckboxEl.type = 'checkbox';
  186. passVisibilityCheckboxEl.checked = open;
  187. parent.append(passVisibilityCheckboxEl);
  188. if (open) {
  189. passInputEl.type = 'text';
  190. } else {
  191. passInputEl.type = 'password';
  192. }
  193. passVisibilityCheckboxEl.addEventListener('change', (event) => {
  194. if (event.currentTarget.checked) {
  195. passInputEl.type = 'text';
  196. } else {
  197. passInputEl.type = 'password';
  198. }
  199. this.onOpenChange(event.currentTarget.checked);
  200. });
  201. passInputEl.addEventListener('input', (event) => {
  202. if (this.onChange) {
  203. this.onChange();
  204. }
  205. });
  206. this.setValue = (value) => {
  207. passInputEl.value = value;
  208. }
  209. this.getValue = () => {
  210. return passInputEl.value;
  211. }
  212. this.setOpen = (value) => {
  213. passVisibilityCheckboxEl.checked = value;
  214. }
  215. this.getOpen = () => {
  216. return passVisibilityCheckboxEl.checked;
  217. }
  218. }
  219. function loginPromise(parent) {
  220. function executor(resolve, reject) {
  221. const form = new LoginForm(parent);
  222. form.onSubmitForm = () => resolve({
  223. login: form.getLoginValue(),
  224. password: form.getPasswordValue(),
  225. });
  226. }
  227. return new Promise(executor);
  228. }
  229. loginPromise(document.body).then(({ login, password }) => console.log(`Вы ввели ${login} и ${password}`));
  230. }