JAVASCRIPT » История » Версия 5
Александр Александров, 25.04.2019 00:29
1 | 1 | Александр Александров | h1. JAVASCRIPT |
---|---|---|---|
2 | |||
3 | h2. Вопросы |
||
4 | |||
5 | # Как переадресовать страницу в JavaScript? |
||
6 | # Сколько параметров можно передать функции? |
||
7 | # Нужно алертом вывести какое-то сообщение, спустя 3 секунды после запуска скрипта. Как это сделать? |
||
8 | # Чем отличается наследование в JavaScript от наследования в PHP? |
||
9 | # Приведи пример наследования в JavaScript. |
||
10 | # Пара слов об объектах в JavaScript? |
||
11 | # Что представляет из себя метод объекта в JavaScript? |
||
12 | # Зачем в JavaScript перед переменной писать var? |
||
13 | 3 | Александр Александров | # Есть две функции: function f(a,b) { return a+b } и var f = function(a,b) { return a+b } Есть ли между ними разница? Если есть то какая? |
14 | 1 | Александр Александров | # Как создать массив в JavaScript? |
15 | # Можно ли в JavaScript использовать функцию в качестве конструктора? |
||
16 | 3 | Александр Александров | # Сколько и какие конструкции для циклов есть в JAVASCRIPT? |
17 | # Что cделает код: break mark; ? |
||
18 | 1 | Александр Александров | # Можно ли задать массив таким образом: var a = “a,b”.split(‘,’)? |
19 | # Что выведет alert(typeof null); ? |
||
20 | # Что выведет alert(null instanceof Object); ? |
||
21 | # 0.1+ 0.2 == 0.3 ? |
||
22 | # Что выведет alert(typeof NaN); ? |
||
23 | # Что выведет alert(NaN === NaN); ? |
||
24 | # В чём различие свойств innerHTML и outerHTML? |
||
25 | # Какая разница между операторами == и ===? |
||
26 | # В чем разница между Object.getOwnPropertyNames() и Object.keys()? |
||
27 | # С помощью какой конструкции языка можно управлять потоком выполнения скрипта и отслеживать ошибки? |
||
28 | # Почему вызов a(); происходит успешно, а вызов b(); выдает ошибку? |
||
29 | # Что такое глобальные переменные ? Как они создаются ? Какие проблемы связаны с использованием глобальных переменных? |
||
30 | # Что такое замыкания (closure) в JavaScript? |
||
31 | # Напишите функцию принимающую строку с именем файла и возвращающую расширение (фрагмент после последней точки). |
||
32 | # Что вернет выражение +new Date()? Чем отличается от Date.now(). |
||
33 | # Какое значение возвращает данное предложение ~~3.14? |
||
34 | # Какое значение возвращает данное предложение? |
||
35 | # Что покажут эти два alert? |
||
36 | # Чему равно foo.length? |
||
37 | # Что такое prototype в javascript? |
||
38 | # Какие способы навешивания обработчиков событий вы знаете? |
||
39 | # Eсть ли разница между window и document? |
||
40 | # Вызываются ли document.onload и window.onload одновременно? |
||
41 | # Как остановить дальнейшее распространение события? |
||
42 | # Назовите различные пути для получения элемента из DOM дерева? |
||
43 | # Какой наибыстрейший метод для получения элемента через css селектор? |
||
44 | # Могу ли я удалить удалить обработчик события с элемента? |
||
45 | # Почему querySelectorAll(‘.my-class’) медленнее, чем getElementsByClassName(‘myclass’)? |
||
46 | # Почему я не могу использовать forEach или похожий метод массива для NodeList? |
||
47 | # Если вам необходимо реализовать getElementByAttribute, как вы будете это делать? |
||
48 | # Как бы вы добавили класс к элементу через селектор? |
||
49 | # Как я могу запустить обработчик в фазе захвата, а не в фазе всплытия? |
||
50 | # Как проверить, что один элемент является дочерним другому? |
||
51 | # Какой метод больше всего подходит для создания DOM элемента? Что лучше innerHTML или createElement? |
||
52 | # Каким образом можно предотвратить множественный вызов обработчика для одного события? |
||
53 | 5 | Александр Александров | # Что делает createDocumentFragment и для чего можно его использовать? |
54 | 1 | Александр Александров | # Что такое reflow? |
55 | # Как я могу проверить были событие отменено или нет? |
||
56 | # Какие причины reflow? Как можно уменьшить reflow? |
||
57 | # Что такое repaint и когда оно происходит? |
||
58 | # Есть ли что-то такое о чём нужно позаботится при использовании node.cloneNode()? |
||
59 | # Что такое всплытие? |
||
60 | # Как можно уничтожить несколько элементов с одним вызовом click? |
||
61 | # Создайте кнопку, которая удаляется при нажатии на неё, и создаются две новые кнопки в этом же месте. |
||
62 | # Как отлавливать все нажатия на странице? |
||
63 | # Как получить весь текст на странице? |
||
64 | # Что такое defer и async? |
||
65 | # Какие существуют типы нод? |
||
66 | |||
67 | h2. Ответы |
||
68 | |||
69 | h3. Как переадресовать страницу в JavaScript? |
||
70 | |||
71 | 2 | Александр Александров | {{dmsf_image(323)}} |
72 | |||
73 | 1 | Александр Александров | h3. Сколько параметров можно передать функции? |
74 | |||
75 | 2 | Александр Александров | Сколько угодно. |
76 | |||
77 | 1 | Александр Александров | h3. Нужно алертом вывести какое-то сообщение, спустя 3 секунды после запуска скрипта. Как это сделать? |
78 | |||
79 | 2 | Александр Александров | Так: |
80 | |||
81 | <pre><code class="javascript"> |
||
82 | setTimeout(alert("Hello", 3000)); |
||
83 | </code></pre> |
||
84 | |||
85 | или так: |
||
86 | |||
87 | <pre><code class="javascript"> |
||
88 | setTimeout(functiom() {alert("Hello")}, 3000); |
||
89 | </code></pre> |
||
90 | |||
91 | 1 | Александр Александров | h3. Чем отличается наследование в JavaScript от наследования в PHP? |
92 | |||
93 | 2 | Александр Александров | В отличие от PHP, где наследование можно делать одним способом, в JavaScript таких способов много. На уровне языка реализовано наследование на прототипах. В JavaScript каждый объект может иметь ассоциацию с другим объектом - так называемый "прототип" (prototype). В случае, если поиск некоторого свойства (или метода) в исходном объекте заканчивается неудачно, интерпретатор пытается найти одноименное свойство (метод) в его прототипе, затем - в прототипе прототипа и т. д. К примеру, если мы затребовали обращение к obj.prop (или, что абсолютно то же самое, obj['prop']), JavaScript начнет искать свойство prop в самом объекте obj, затем – в прототипе obj, прототипе прототипа obj, и так до конца. |
94 | |||
95 | 1 | Александр Александров | h3. Приведи пример наследования в JavaScript. |
96 | |||
97 | 2 | Александр Александров | Например, пусть объект "cat" наследуется от объекта "animal". В наследовании на прототипах это реализуется как ссылка |
98 | |||
99 | <pre><code class="javascript"> |
||
100 | cat.prototype = animal; |
||
101 | </code></pre> |
||
102 | |||
103 | Или вот чуть более развернутый пример. MyType наследуется от Obj: |
||
104 | |||
105 | {{dmsf_image(323)}} |
||
106 | |||
107 | 1 | Александр Александров | h3. Пара слов об объектах в JavaScript? |
108 | |||
109 | 2 | Александр Александров | Объекты (они же - ассоциативные массивы, хэши) и работа с ними в JavaScript реализованы не так, как в большинстве языков. Объект в JavaScript представляет собой обычный ассоциативный массив или, иначе говоря, "хэш". Он хранит любые соответствия "ключ => значение" и имеет несколько стандартных методов. |
110 | |||
111 | 1 | Александр Александров | h3. Что представляет из себя метод объекта в JavaScript? |
112 | |||
113 | 2 | Александр Александров | Метод объекта в JavaScript - это просто функция, которая добавлена в ассоциативный массив. |
114 | |||
115 | 1 | Александр Александров | h3. Зачем в JavaScript перед переменной писать var? |
116 | |||
117 | 2 | Александр Александров | Если создавать переменную через обычное присваивание - будет создана "глобальная переменная". Пример: |
118 | |||
119 | <pre> |
||
120 | max = 100; |
||
121 | </pre> |
||
122 | |||
123 | Если создавать переменную с использованием слова var, тогда будет создана "локальная переменная", которая перестаёт существовать после завершения работы функции. Пример: |
||
124 | |||
125 | <pre> |
||
126 | var max = 100; |
||
127 | </pre> |
||
128 | |||
129 | 3 | Александр Александров | h3. Есть две функции: function f(a,b) { return a+b } и var f = function(a,b) { return a+b } Есть ли между ними разница? Если есть то какая? |
130 | 1 | Александр Александров | |
131 | Есть, разница в видимости функции. Вариант функции без var виден везде в текущей области видимости. В том числе и до самого определения функции. Вариант с var присваивает функцию переменной, поэтому такая функция видна только после определения. |
||
132 | |||
133 | h3. Как создать массив в JavaScript? |
||
134 | |||
135 | 3 | Александр Александров | Вот несколько способов. |
136 | |||
137 | {{dmsf_image(325)}} |
||
138 | |||
139 | 1 | Александр Александров | h3. Можно ли в JavaScript использовать функцию в качестве конструктора? |
140 | |||
141 | 3 | Александр Александров | Вот так: |
142 | 1 | Александр Александров | |
143 | 3 | Александр Александров | {{dmsf_image(326)}} |
144 | |||
145 | h3. Сколько и какие конструкции для циклов есть в JAVASCRIPT? |
||
146 | |||
147 | Три: for, while и do...while. |
||
148 | |||
149 | h3. Что cделает код: break mark; ? |
||
150 | |||
151 | Выйдет из текущего блока цикла или switch на метку "mark". |
||
152 | |||
153 | 1 | Александр Александров | h3. Можно ли задать массив таким образом: var a = “a,b”.split(‘,’)? |
154 | |||
155 | 3 | Александр Александров | Да, можно. |
156 | |||
157 | 1 | Александр Александров | h3. Что выведет alert(typeof null); ? |
158 | |||
159 | 3 | Александр Александров | Выведет сообщение "object". |
160 | |||
161 | 1 | Александр Александров | h3. Что выведет alert(null instanceof Object); ? |
162 | |||
163 | 3 | Александр Александров | Выведет сообщение "false". |
164 | |||
165 | 1 | Александр Александров | h3. 0.1+ 0.2 == 0.3 ? |
166 | |||
167 | 3 | Александр Александров | Нет, т.к. вычисленное значение будет равно 0.30000000000000004. Это действие точности вычислений и проявляется она не только в JavaScript |
168 | |||
169 | 1 | Александр Александров | h3. Что выведет alert(typeof NaN); ? |
170 | |||
171 | 3 | Александр Александров | "Number" |
172 | |||
173 | 1 | Александр Александров | h3. Что выведет alert(NaN === NaN); ? |
174 | |||
175 | 3 | Александр Александров | "false" |
176 | |||
177 | 1 | Александр Александров | h3. В чём различие свойств innerHTML и outerHTML? |
178 | |||
179 | 3 | Александр Александров | Свойство любого DOM элемента innerHTML содержит HTML код, который находится внутри этого элемента. При установке нового значения этого свойства, внутренний HTML код рендерится браузером заново. outerHTML почти аналогичен innerHTML, разница в том, что он возвращает полный HTML элемента. Также, важно отметить, что innerHTML поддерживается всеми современными браузерами, а outerHTML поддерживается в IE (с некоторыми отличиями от остальных браузеров), в последних версиях Opera, и в браузерах на основе последних WebKit (Safari, Chrome), но не поддерживается в Firefox. |
180 | |||
181 | Для кода: |
||
182 | |||
183 | {{dmsf_image(327)}} |
||
184 | |||
185 | innerHTML возвратит: |
||
186 | |||
187 | <pre><code class="javascript"> |
||
188 | <p class="inner"></p> |
||
189 | </code></pre> |
||
190 | |||
191 | outerHTML возвратит: |
||
192 | |||
193 | <div class="outer"><p class="inner"></p></div> |
||
194 | |||
195 | 1 | Александр Александров | h3. Какая разница между операторами == и ===? |
196 | |||
197 | 3 | Александр Александров | Оператор == сравнивает на равенство, а вот === сравнивает на идентичность. Плюс оператора === состоит в том, что он не приводит два значения к одному типу. Именно из-за этого он обычно и используется. |
198 | |||
199 | 1 | Александр Александров | h3. В чем разница между Object.getOwnPropertyNames() и Object.keys()? |
200 | |||
201 | 3 | Александр Александров | Object.getOwnPropertyNames() возвращает перечислимые и не перечислимые свойства из объекта или массива. |
202 | |||
203 | {{dmsf_image(328)}} |
||
204 | |||
205 | Object.keys() возвращает перечислимые свойства из объекта или массива |
||
206 | |||
207 | {{dmsf_image(329)}} |
||
208 | |||
209 | 1 | Александр Александров | h3. С помощью какой конструкции языка можно управлять потоком выполнения скрипта и отслеживать ошибки? |
210 | |||
211 | 3 | Александр Александров | Это возможно с помощью конструкции try{}... catch{} |
212 | |||
213 | {{dmsf_image(330)}} |
||
214 | |||
215 | 1 | Александр Александров | h3. Почему вызов a(); происходит успешно, а вызов b(); выдает ошибку? |
216 | 3 | Александр Александров | |
217 | {{dmsf_image(331)}} |
||
218 | |||
219 | Функция а() инициализируется на этапе загрузки скрипта, как бы "всплывает вверх" а функция б инициализируется, когда объявляется переменная b |
||
220 | 1 | Александр Александров | |
221 | h3. Что такое глобальные переменные ? Как они создаются ? Какие проблемы связаны с использованием глобальных переменных? |
||
222 | |||
223 | 4 | Александр Александров | Глобальная переменная - переменная, которая доступна (видима) во всем документе, в отличии от локальной (ограничена рамками блока программного кода, внутри которого она определена) |
224 | |||
225 | <pre><code class="javascript"> |
||
226 | var = 5; |
||
227 | function myFunction() { |
||
228 | alert(myvar); |
||
229 | } |
||
230 | </code></pre> |
||
231 | |||
232 | Большинство JavaScript разработчиков избегает использования глобальных переменных. Одна из причин - возможный конфликт имен глобальных и локальных переменных. Так же код использующий глобальные переменные может быть тяжелее сопровождать и тестировать. |
||
233 | |||
234 | 1 | Александр Александров | h3. Что такое замыкания (closure) в JavaScript? |
235 | |||
236 | 4 | Александр Александров | Простыми словами это внутренняя функция, т.е. функция в функции. Замыканием (closure) называют потому, что после выполнения родительской или внешней функции, код внутренней все еще "живет" в интерпретаторе, и его можно выполнить. Ошибок не возникнет даже если внутренняя функция (замыкание) будет использовать переменные из внешней функции. Например, эту особенность можно использовать для создания функций обработчиков событий: |
237 | |||
238 | {{dmsf_image(332)}} |
||
239 | |||
240 | 1 | Александр Александров | h3. Напишите функцию принимающую строку с именем файла и возвращающую расширение (фрагмент после последней точки). |
241 | |||
242 | 4 | Александр Александров | <pre><code class="javascript"> |
243 | function getExtension(filename) { |
||
244 | var fragments = filename.split("."); |
||
245 | return fragments[fragments.length - 1]; |
||
246 | } |
||
247 | </code></pre> |
||
248 | |||
249 | 1 | Александр Александров | h3. Что вернет выражение +new Date()? Чем отличается от Date.now(). |
250 | |||
251 | 4 | Александр Александров | Ответ в том, что +new Date(); создаст экземпляр объекта Date и благодаря + переведет его в числовой формат. Во втором случае вызовется статический метод конструктора, который является более приоритетным, т.к. во-первых он не требует создания экземпляра, а во-вторых является более понятным. |
252 | |||
253 | 1 | Александр Александров | h3. Какое значение возвращает данное предложение ~~3.14? |
254 | |||
255 | 4 | Александр Александров | Ответ: 3 |
256 | |||
257 | 1 | Александр Александров | h3. Какое значение возвращает данное предложение? |
258 | |||
259 | 4 | Александр Александров | "i'm a lasagna hog".split("").reverse().join(""); |
260 | |||
261 | Ответ: "goh angasal a m’i" |
||
262 | |||
263 | 1 | Александр Александров | h3. Что покажут эти два alert? |
264 | |||
265 | 4 | Александр Александров | {{dmsf_image(333)}} |
266 | |||
267 | Ответ: "Hello World" и ReferenceError: bar is not deÙned |
||
268 | |||
269 | 1 | Александр Александров | h3. Чему равно foo.length? |
270 | |||
271 | 4 | Александр Александров | <pre><code class="javascript"> |
272 | var foo = []; |
||
273 | foo.push(1); |
||
274 | foo.push(2); |
||
275 | </code></pre> |
||
276 | |||
277 | Ответ: 2 |
||
278 | |||
279 | 1 | Александр Александров | h3. Что такое prototype в javascript? |
280 | |||
281 | 4 | Александр Александров | В общих чертах prototype - это свойство позволяющее добавлять уже существующим объектам свойства, также используется для эмуляции наследования классов в JavaScript. Подробный ответ написан здесь . Еще как вариант, можно упомянуть о Prototype.js. Это популярная библиотека добавляющая удобные ООП возможности в программы на JavaScript-е. |
282 | |||
283 | 1 | Александр Александров | h3. Какие способы навешивания обработчиков событий вы знаете? |
284 | 4 | Александр Александров | |
285 | События можно добавлять тремя способами: |
||
286 | |||
287 | * htmlElement.onclick = function(event) { .... } - так можно добавить только один обработчик |
||
288 | * htmlElement.addEventListener( "click", ... ) - так можно навесить несколько обработчиков, сохраняет порядок обработчиков |
||
289 | * htmlElement.attachEvent( "on"+имя_события, обработчик) - тоже можно навесить несколько, не сохраняет порядок обработчиков, нет доступа к элементу на котором сработало событие. |
||
290 | 1 | Александр Александров | |
291 | h3. Eсть ли разница между window и document? |
||
292 | |||
293 | 5 | Александр Александров | Да. У JavaScript есть глобальный объект и всё происходит через него. window - тот самый объект, который хранит глобальные переменные, функции, местоположение, историю. Всё находится внутри него, setTimeout, XMLHttpRequest, console и localStorage также являются частью window. Аналогично дело обстоит и с document, который является свойством объекта window и представляет DOM. Все ноды - это часть document, следовательно, вы можете использовать getElementById или addEventListener для document. Но обратите внимание, что этих методов нет в объекте window. |
294 | |||
295 | {{dmsf_image(334)}} |
||
296 | |||
297 | 1 | Александр Александров | h3. Вызываются ли document.onload и window.onload одновременно? |
298 | |||
299 | 5 | Александр Александров | window.onload вызывается, когда DOM готов и весь контент, включая картинки, стили, фреймы и т.д. загружен. document.onload вызывается когда дерево DOM выстроено, но до момента, как подгружаются картинки, стили и пр. |
300 | 1 | Александр Александров | |
301 | 5 | Александр Александров | document.readyState возвращает "loading" пока документ грузится, "interactive" - когда завершился парсинг, но продолжается загрузка дополнительных ресурсов, и "complete" когда всё загружено. Событие readystatechange вызывается для объекта document когда это значение изменяется. |
302 | |||
303 | 1 | Александр Александров | h3. Как остановить дальнейшее распространение события? |
304 | |||
305 | 5 | Александр Александров | Вызвать event.stopPropagation(); |
306 | |||
307 | 1 | Александр Александров | h3. Назовите различные пути для получения элемента из DOM дерева? |
308 | |||
309 | 5 | Александр Александров | Вы можете использовать следующие методы document: |
310 | |||
311 | * getElementById для получения одного элемента, которому соответствует указанный ID. |
||
312 | * getElementsByClassName для получения nodeList (nodeList это не массив, это скорее массиво-подобный объект) по названию класса. |
||
313 | * getElementsByTagName для получения nodeList по имени тэга. |
||
314 | * querySelector вы можете указывать селекторы в виде css стилей (аля jquery) и данный метод вернёт первый элемент из DOM соответствующий запросу. querySelectorAll вернёт список не "живых" nodeList. Не "живые" значит, что любые изменения (добавление, удаления в DOM) после выборки элементов не будут отражены в результатах поиска. |
||
315 | * getElementsByName возвращает список элементов returns the list of elements by the |
||
316 | * provided name of the html tag |
||
317 | * getElementsByTagNameNS возвращает элементы с определённым названием тэга в пространстве имён. |
||
318 | |||
319 | 1 | Александр Александров | h3. Какой наибыстрейший метод для получения элемента через css селектор? |
320 | |||
321 | 5 | Александр Александров | Это зависит от того, что вам нужно найти. Если у вас есть ID элемента, то getElementById - это самый быстрый путь для получения элемента. Однако, вам не следует содержать много ID в вашем документе, чтобы избежать заучивания стилей. getElementsByClassName - это второй по скорости метод для получения элемента. Вот список упорядоченный по скорости выборки элементов, начиная с наибыстрейшего: |
322 | |||
323 | * ID (#myID) |
||
324 | * Класс (.myClass) |
||
325 | * Тэг (div, p) |
||
326 | * Элемент, находящийся рядом (sibling) (div+p, div~p) |
||
327 | * Прямой потомок (div > p) |
||
328 | * Универсальный (*) |
||
329 | * Атрибут (input[type="checkbox"]) |
||
330 | * Псевдо-элемент (p:first-child) |
||
331 | |||
332 | Если у вас невероятно длинный селектор для получения элемента, подумайте, быть может, лучше использовать вместо него класс? |
||
333 | |||
334 | 1 | Александр Александров | h3. Могу ли я удалить удалить обработчик события с элемента? |
335 | |||
336 | 5 | Александр Александров | Да. target.removeEventListener('click', handler) |
337 | |||
338 | 1 | Александр Александров | h3. Почему querySelectorAll(‘.my-class’) медленнее, чем getElementsByClassName(‘myclass’)? |
339 | |||
340 | 5 | Александр Александров | querySelectorAll является универсальным методом. Он оптимизирован под различные типы селекторов. Если вы просто укажите имя класса с ".", внутри он будет использовать getElementsByClassName (может меняться в зависимости от браузера). В то же время, если вы будете напрямую использовать getElementsByClassName, то понятно, что этому методу не нужно проходить через все внутренние процессы, в отличии от querySelectorAll. Следовательно, для поиска элемента с конкретным именем класса, getElementsByClassName будет быстрее, чем querySelectorAll. |
341 | |||
342 | 1 | Александр Александров | h3. Почему я не могу использовать forEach или похожий метод массива для NodeList? |
343 | |||
344 | 5 | Александр Александров | Да, и массив и nodeList имеет параметр length и вы можете использовать цикл для прохода по элементам, но не всё так просто. Оба они унаследованы от Object. Однако, массив имеет иной прототип нежели, чем nodeList. forEach, map, и пр. включены в array.prototype, которого не существуют для NodeList.prototype объекта. Следовательно, вы не можете использовать forEach для nodeList. |
345 | |||
346 | myArray --> Array.prototype --> Object.prototype --> null |
||
347 | myNodeList --> NodeList.prototype --> Object.prototype --> null |
||
348 | |||
349 | Для решения этой проблемы можно пропустить nodeList через цикл и делать всё, что пожелаете внутри цикла. Или вызвать метод для конвертации nodeList в массив. После этого у вас будет доступ ко всем методам из array.prototype. |
||
350 | |||
351 | {{dmsf_image(335)}} |
||
352 | |||
353 | 1 | Александр Александров | h3. Если вам необходимо реализовать getElementByAttribute, как вы будете это делать? |
354 | |||
355 | 5 | Александр Александров | Во-первых, получить все элементы из DOM. Это можно сделать используя getElementsByTagName с параметром '*' и затем проверить имеют ли они нужные атрибуты. В этом случае, даже если атрибут равен null, он будет захвачен. Если вам нужно проверить значение, вам следует добавить один дополнительный параметр и сравнивать с ним в блоке с IF. |
356 | |||
357 | {{dmsf_image(336)}} |
||
358 | |||
359 | 1 | Александр Александров | h3. Как бы вы добавили класс к элементу через селектор? |
360 | |||
361 | 5 | Александр Александров | Очень просто. Просто получите элемент и добавьте имя класса в classlist. |
362 | |||
363 | {{dmsf_image(337)}} |
||
364 | |||
365 | Кроме того, вы можете реализовать методы removeClass, toggleClass и hasClass: |
||
366 | |||
367 | {{dmsf_image(338)}} |
||
368 | |||
369 | 1 | Александр Александров | h3. Как я могу запустить обработчик в фазе захвата, а не в фазе всплытия? |
370 | |||
371 | 5 | Александр Александров | В методах addEventListener и removeEventLister есть третий опциональный параметр. Вы можете установить его в true или false в зависимости от того хотите или нет использовать фазу захвата. |
372 | |||
373 | 1 | Александр Александров | h3. Как проверить, что один элемент является дочерним другому? |
374 | |||
375 | 5 | Александр Александров | Первое, проверьте является ли указанный родитель прямым для ребенка. Если нет, продолжайте двигаться вверх по дереву. |
376 | |||
377 | {{dmsf_image(339)}} |
||
378 | |||
379 | 1 | Александр Александров | h3. Какой метод больше всего подходит для создания DOM элемента? Что лучше innerHTML или createElement? |
380 | |||
381 | 5 | Александр Александров | Когда вы устанавливаете свойство innerHTML, браузер удаляет всех "детей" из элемента. Затем парсит строку и вставляет её в элемент как потомка. Например, если вы хотите добавить элемент списка к несортированному списку, вы можете получить элемент и задать ему innerHTML: |
382 | |||
383 | {{dmsf_image(340)}} |
||
384 | |||
385 | innerHTML может быть медленным при парсинге строки. Браузер вынужден иметь дело со строкой даже если вы задали ему невалидный html. С другой стороны, пока вы используете appendChild, вы создаёте новый элемент. С момента его создания, браузеру не нужно парсить строку и иметь дело с невалидным html. И вы можете указать потомка для родителя, который будет добавлен к элементу родителя. |
||
386 | |||
387 | {{dmsf_image(341)}} |
||
388 | |||
389 | Все-таки, лучше написать пару дополнительных строк на JavaScript - это упростит жизнь браузеру и сделает вашу страницу быстрее. |
||
390 | |||
391 | 1 | Александр Александров | h3. Каким образом можно предотвратить множественный вызов обработчика для одного события? |
392 | |||
393 | 5 | Александр Александров | Если слушатель события прикреплён к одному и тому же типу (click, keydown, и т.д.) элемента, вы можете вызвать event.stopImmediatePropagation() в первом обработчике и другие не будут выполнены. |
394 | |||
395 | h3. Что делает createDocumentFragment и для чего можно его использовать? |
||
396 | |||
397 | documentFragment - очень легковесная и маленькая штука. Этот метод помогает в тех случаях, когда вы производите множество манипуляции с DOM. "Дерганье" DOM сотни раз - это дорогое удовольствие, которое может привести к вызову reflow. Избегайте частого reflow. Вы можете избежать этого, используя documentFragment, что уберегает от использования лишней памяти. |
||
398 | |||
399 | {{dmsf_image(342)}} |
||
400 | |||
401 | 1 | Александр Александров | h3. Что такое reflow? |
402 | |||
403 | 5 | Александр Александров | reflow: когда вы меняете размер или позицию элемента на странице, все элементы после этого вынуждены изменять свои позиции в соответствии с изменениями, сделанными вами. Для примера, если вы меняете высоту элемента, то все элементы под ним вынуждены сдвинуться вниз. Следовательно, поток элементов на странице изменился и это вызывает reflow. |
404 | |||
405 | Почему reflow это плохо: перекомпоновка может быть очень дорогой и это может вызвать свистопляску на телефонах и планшетах |
||
406 | |||
407 | 1 | Александр Александров | h3. Как я могу проверить были событие отменено или нет? |
408 | |||
409 | 5 | Александр Александров | Используйте event.cancelable для получения true или false. Однако, вам обязательно нужно вызвать preventDefault() для предотвращения события. |
410 | |||
411 | 1 | Александр Александров | h3. Какие причины reflow? Как можно уменьшить reflow? |
412 | |||
413 | 5 | Александр Александров | Причины reflow: |
414 | |||
415 | * изменение шаблона (геометрия страницы) |
||
416 | * изменения размера окна |
||
417 | * изменения высоты\ширины любого элемента |
||
418 | * перемещение элемента (анимация) |
||
419 | * удаление или добавление стиля |
||
420 | * калькуляции смещения по высоте или по ширине |
||
421 | * display: none |
||
422 | |||
423 | Как этого избежать: |
||
424 | |||
425 | * не устанавливайте стили внутри элементов |
||
426 | * применяйте анимацию к элементам, которые отпозиционированы fixed или absolute |
||
427 | * избегайте таблиц |
||
428 | |||
429 | 1 | Александр Александров | h3. Что такое repaint и когда оно происходит? |
430 | |||
431 | 5 | Александр Александров | repaint происходит когда вы изменяете вид элемента без изменения размеров. |
432 | |||
433 | Причины repaint: |
||
434 | |||
435 | * изменения цвета фона |
||
436 | * изменения цвета шрифта |
||
437 | * visibility: hidden |
||
438 | |||
439 | Предпочтительней repaint вместо reflow. |
||
440 | |||
441 | 1 | Александр Александров | h3. Есть ли что-то такое о чём нужно позаботится при использовании node.cloneNode()? |
442 | |||
443 | 5 | Александр Александров | При клонировании убедитесь, что вы не дублируете ID. Как быть уверенным в том, что DOM подготовлен и можно выполнять JavaScript, как реализовать $(document).ready? |
444 | 1 | Александр Александров | |
445 | 5 | Александр Александров | Существует четыре различных метода: |
446 | |||
447 | * вставьте ваш скрипт в конце body элемента. Когда DOM будет готов браузер вызовет ваш script внутри тэга. |
||
448 | * вставьте ваш код внутрь события DOMContentLoaded. Это событие будет вызываться, когда DOM полностью загружен. |
||
449 | |||
450 | <pre><code class="javascript"> |
||
451 | document.addEventListener('DOMCintentLoaded', function () { |
||
452 | // add your code here |
||
453 | }); |
||
454 | </code></pre> |
||
455 | |||
456 | * Наблюдайте событие в readyState для document. Состояние "complete" будет означать полную загрузку: |
||
457 | |||
458 | {{dmsf_image(343)}} |
||
459 | |||
460 | * Найдите исходники jQuery и скопируйте функцию dom.ready. В этом случае вы будете иметь функцию, которая работает во всех браузерах. |
||
461 | |||
462 | 1 | Александр Александров | h3. Что такое всплытие? |
463 | |||
464 | 5 | Александр Александров | Для понимания "всплытия", вам нужно понять что происходит когда вы кликаете где-либо на странице. Предположим, у вас есть таблица с множеством колонок и столбцов и вы кликаете в одну из ячеек. Вы возможно думаете, что когда вы кликните на ячейку, то браузер будет знать что у вас есть обработчик на нажатии на ячейку и он будет вызван незамедлительно. Это абсолютно не верно. На самом деле, браузер не знает куда вы кликнули. |
465 | |||
466 | Браузер будет определять местоположение клика следующими путями: |
||
467 | |||
468 | * Захват: когда вы кликаете, браузер знает, что событие клика произошло. Он начинает с window (самый низкий уровень), затем идёт в document, затем html тэг, затем body, затем table... Он пытается достичь самого высокого уровня элемента, который только возможен. Это зовётся фазой "захвата" (первая фаза). |
||
469 | * Цель: когда браузер достигнет самого элемента на котором был произведен клик, то браузер отметит если ли у этого элемента какие-либо прикрепленные обработчики. Если ничего нет, то браузер выполнил обработчик клика. Это называет фаза цели (вторая фаза). |
||
470 | * Всплытие: после вызова обработчика, прикрепленного к "td", браузер начнёт своё путешествие обратно с window. Уровень за уровнем он будет проверять если ли на элементе обработчик на "click" и если обнаружит таковой - выполнит. Это и есть стадия всплытия (третья фаза). Заметьте, когда вы кликните на ячейку, будут исполнены все обработчики событий на click для всех родительских элементов. |
||
471 | |||
472 | 1 | Александр Александров | h3. Как можно уничтожить несколько элементов с одним вызовом click? |
473 | |||
474 | 5 | Александр Александров | Если у вас есть список из сотни элементов, которые имеют различные обработчики, вы можете написать одну сотню обработчиков событий (аля копипаст) с одинаковым кодом в сотне места. Это работает, но если понадобится что-то изменить в обработчике, вы будете вынуждены поменять это везде. |
475 | 1 | Александр Александров | |
476 | 5 | Александр Александров | Вторая проблема заключается в том, что вы хотите динамически добавлять новые элементы и, следовательно, вам нужно быть уверенным в том, что к новому элементу был добавлен свой обработчик. Много JavaScript кода! |
477 | Ответ: В данном случае, как нельзя кстати, нам подойдет всплытие. Вы можете навесить только один обработчик на родительский элемент. В нашем примере это будет "ul" тэг. После клика по элементу списка (заметьте, элемент не имеет обработчика), событие будет всплывать и достигнет элемента "ul", который имеет обработчик и об будет исполнен. |
||
478 | |||
479 | {{dmsf_image(344)}} |
||
480 | |||
481 | Можно return false, можно и event.preventDefault() внутри обработчика события. Однако, это не остановит дальнейшее распространение. |
||
482 | |||
483 | 1 | Александр Александров | h3. Создайте кнопку, которая удаляется при нажатии на неё, и создаются две новые кнопки в этом же месте. |
484 | |||
485 | 5 | Александр Александров | Можно решить это добавив обработчик события вместе с кнопкой для удаления и добавить новые. Однако, мы можем снизить количество навешиваний событий. Если мы добавим обработчик к родительскому элементу вместо кнопки, то у нас не будет необходимости добавлять обработчик при каждом создании кнопки. Итак, мы будем пользоваться преимуществами всплытия. |
486 | |||
487 | {{dmsf_image(345)}} |
||
488 | |||
489 | 1 | Александр Александров | h3. Как отлавливать все нажатия на странице? |
490 | |||
491 | 5 | Александр Александров | Вы можете достичь цели при помощи фазы всплытия, т.к. все события click будут всплывать до элемента body. |
492 | |||
493 | {{dmsf_image(346)}} |
||
494 | |||
495 | Однако, если "всплытие" было отменено через stopPropagation() этот код не будет работать. |
||
496 | |||
497 | 1 | Александр Александров | h3. Как получить весь текст на странице? |
498 | |||
499 | 5 | Александр Александров | Самый простой путь получить весь текст - через свойство innerText у body. |
500 | |||
501 | 1 | Александр Александров | h3. Что такое defer и async? |
502 | |||
503 | 5 | Александр Александров | обычное состояние: когда вы вставляете стандартный тэг script (без defer и async), парсер приостанавливает парсинг до того момента, как скрипт будет скачан и выполнен. |
504 | |||
505 | * defer: defer в тэге script отложит выполнение скрипта. Следовательно скрипт будет выполнен когда DOM будет доступен. Важный момент, defer не поддерживается всеми современными браузерами. |
||
506 | * async: скачивание и выполнение скрипта асинхронно. Если это возможно, устанавливайте выполнение скрипта в асинхронном режиме, но обратите внимание, что async не имеет эффекта на инлайновые скрипты. |
||
507 | |||
508 | 1 | Александр Александров | h3. Какие существуют типы нод? |
509 | 5 | Александр Александров | |
510 | ELEMENT_NODE (1), TEXT_NODE (3), COMMENT_NODE(8), DOCUMENT_NODE(9), DOCUMENT_TYPE_NODE(10), DOCUMENT_FRAGMENT_NODE(11), и т.д. |