Фичи JavaScript. Часть 1

от автора

Доброго времени суток, друзья!

В этой статье я хочу поделиться с Вами некоторыми находками, сделанными мной в процессе изучения JavaScript. Возможно, Вы найдете для себя что-то интересное. Данная часть серии будет посвящена, преимущественно, работе с DOM.

Настоятельно рекомендую применить к body следующие стили:

body {     margin: 0;     min-height: 100vh;     overflow: hidden; } 

Если планируете тестировать примеры, используйте эту функцию для очистки документа для того, чтобы каждый раз не создавать новый:

const clear = () => document.body.innerHTML = '' clear() 

1. Активный элемент

Свойство activeElement позволяет получить элемент, находящийся в фокусе.

const input = document.createElement('input') input.setAttribute('type', 'text') input.setAttribute('placeholder', 'Введите свое имя') input.className = 'username' document.body.append(input)  input.focus()  console.log(document.activeElement) // <input type="text" placeholder="Введите свое имя" class="username"> 

2. Редактирование страницы

Свойство designMode позволяет редактировать страницу, открытую в браузере.

document.designMode = 'on' 


3. Стили элемента

Метод getComputedStyle() позволяет получить стили элемента. Для получения определенного свойства следует использовать getPropertyValue().

// напишем вспомогательную функцию для получения определенного свойства элемента // мы будем использовать ее в нескольких примерах const getStyle = (element, property) => getComputedStyle(element).getPropertyValue(property)  // возьмем инпут из первого примера // и определим его ширину и высоту const inputWidth = getStyle(input, 'width') const inputHeight = getStyle(input, 'height') console.log(`Ширина: ${inputWidth}\nВысота: ${inputHeight}`) // Ширина: 156.8px // Высота: 16px  // позиционируем элемент, используя полученные данные // предположим, что мы собираемся анимировать элемент // поэтому не хотим использовать transform: translate(-50%, -50%) // допустим также, что мы не знаем размеров элемента // поэтому не можем использовать calc(50% - ширина/высота элемента) input.setAttribute('style',     `position: absolute; top: calc(50% - ${inputHeight.replace('px', '') / 2}px); left: calc(50% - ${inputWidth.replace('px', '') / 2}px);` ) 

4. Определение браузера

Объект Navidator, в числе прочего, позволяет получить информацию о браузере пользователя.

let browser const agent = navigator.userAgent  if (agent.indexOf('Google')) {     browser = 'Google Chrome' } else if (agent.indexOf('Safari')) {     browser = 'Apple Safari' } else if (agent.indexOf('Opera')) {     browser = 'Opera' } else if (agent.indexOf('Firefox')) {     browser = 'Mozilla Firefox' } else if (agent.indexOf('MSIE')) {     browser = 'Microsoft Interner Explorer' } console.log(browser) // Google Chrome // вероятно, в данном случае надо было использовать switch  if (browser === 'Google Chrome' || browser === 'Mozilla Firefox') {     console.log('ok') // ok } else if (browser === 'Opera' || browser === 'Apple Safari') {     console.log('50/50') } else if (browser === 'Microsoft Interner Explorer') {     console.log('!ok') } 

5. Получение координат

Объект Navigator также позволяет получить информацию о местонахождении пользователя, т.е. его координаты.

const success = position => {     // деструктурируем объект     const {         latitude,         longitude,         altitude,         speed     } = position.coords     console.log(`${latitude.toFixed(2)}\n${longitude.toFixed(2)}\n${altitude}\n${speed}`)      // об этом ниже     getCityAndWeather(latitude, longitude) }  navigator.geolocation.getCurrentPosition(success) /*     56.90     60.63     null     null */  // вот как мы можем использовать полученные данные // определим город пользователя и погоду const getCityAndWeather = (latitude, longitude) => {     // прокси для преодоления CORS     const proxy = 'https://cors-anywhere.herokuapp.com/'     // данный сервис был куплен Facebook и станет платным в 2021 году     const api = `${proxy}https://api.darksky.net/forecast/fd9d9c6418c23d94745b836767721ad1/${latitude}, ${longitude}`      fetch(api)         .then(response => response.json())         .then(data => {             console.log(data) // много всего              // получаем город             const city = data.timezone              // получаем температуру             const { temperature, summary } = data.currently              // переводим фаренгейт в цельсий             const celsius = Math.floor((temperature - 32) * (5 / 9)).toFixed()              // выводим результат             console.log(                 `${city}\n${celsius}°C\n${summary}`             )             /*                 Asia/Yekaterinburg                 15°C                 Overcast             */         }) } 

6. Получение элементов

Как нам получить все элементы DOM? Использовать рекурсию.

const template =  `<div>     <p> Lorem ispum         <span>dolor sit amet</span>     </p> </div> <a href="#">link</a>`  document.body.innerHTML = template  const getElements = element => {     for (const i of element.children) {         console.log(i.tagName)          // 0 -> ! -> false -> ! -> true         if (!!i.children.length) {             console.log('дочерний элемент')             getElements(i)         }     } } getElements(document.body) /*     DIV     дочерний элемент     P       дочерний элемент     SPAN     A */ 

7. Разбор URL

Как нам получить отдельные части URL? Это можно сделать двумя способами.

// с помощью регулярки const regex = /(\w+):\/\/([\w.]+)\/(\S*)/ const url = 'https://example.com/index.html' const result = url.match(regex) // полный адрес (абсолютный путь), протокол, хост, страница console.log(result[0], result[1], result[2], result[3]) // https://example.com/index.html https example.com index.html  // с помощью конструктора URL const url2 = new URL('https://example.com/search?query=fetch&page=2#awesome-page') console.log(url2) // много всего  const {     origin,     protocol,     host,     pathname } = url2 console.log(     `${origin} ${protocol} ${host} ${pathname}` ) // https://example.com https: example.com /search  // рекомендую почитать про свойство searchParams // searchParams.get(), searchParams.append(), searchParams.has(), searchParams.delete() и т.д. 

8. Позиционирование одного элемента относительно другого

const toCenter = (element, parent) => {     element.style.position = 'relative'      element.style.left = (parent.clientWidth - element.offsetWidth) / 2 + 'px'     element.style.top = (parent.clientHeight - element.offsetHeight) / 2 + 'px' } const div = document.createElement('div') div.setAttribute('style', 'width: 150px; height: 150px; background: red;') document.body.append(div)  const div2 = document.createElement('div') div2.setAttribute('style', 'width: 100px; height: 100px; background: green;') div.append(div2)  const div3 = document.createElement('div') div3.setAttribute('style', 'width: 50px; height: 50px; background: blue;') div2.append(div3)  toCenter(div, document.body) toCenter(div2, div) toCenter(div3, div2) 

9. Ширина и высота документа

Как нам получить полную ширину и высоту документа?

const pageWidth = Math.max(     document.body.scrollWidth, document.documentElement.scrollWidth,     document.body.offsetWidth, document.documentElement.offsetWidth,     document.body.clientWidth, document.documentElement.clientWidth ) const pageHeight = Math.max(     document.body.scrollHeight, document.documentElement.scrollHeight,     document.body.offsetHeight, document.documentElement.offsetHeight,     document.body.clientHeight, document.documentElement.clientHeight )  // один из вариантов использования // определяем центр страницы const pageCenter = [pageWidth / 2, pageHeight / 2] console.log(pageCenter)  // создаем элемент для позиционирования const p = document.createElement('p') p.textContent = 'Lorem ipsum dolor sit amet' document.body.append(p) p.style.position = 'absolute'  // получаем ширину и высоту элемента, используя getStyle const elementWidth = getStyle(p, 'width').replace('px', '') const elementHeight = getStyle(p, 'height').replace('px', '')  // определяем центр элемента const elementCenter = [elementWidth / 2, elementHeight / 2] console.log(elementCenter)  // позиционируем элемент p.style.top = pageCenter[1] - elementCenter[1] + 'px' p.style.left = pageCenter[0] - elementCenter[0] + 'px' 

10. Координаты элемента в контексте документа

Метод getBoundingClientRect() возвращает размер элемента и его позицию относительно области просмотра.

// возьмем p из предыдущего примера console.log(p.getBoundingClientRect()) // много всего console.log(     `Отступ сверху => ${p.getBoundingClientRect().top.toFixed()}\nОтступ слева => ${p.getBoundingClientRect().left.toFixed()}` ) /*     Отступ сверху => 352     Отступ слева => 288 */  // создадим два элемента // и определим, в какой части страницы находится каждый из них const div = document.createElement('div') div.setAttribute('style', 'width: 100px; height: 100px; background: #222; position: absolute; top: calc(50% - 50px); left: calc(25% - 50px);') document.body.append(div)  const div2 = document.createElement('div') div2.setAttribute('style', 'width: 100px; height: 100px; background: #222; position: absolute; top: calc(50% - 50px); left: calc(75% - 50px);') document.body.append(div2)  document.querySelectorAll('div').forEach(div => div.addEventListener('click', event => {     const x = event.target.getBoundingClientRect().x     const width = event.target.getBoundingClientRect().width      // расчеты приблизительные     x + width < innerWidth / 2     ? console.log('Элемент находится в левой части страницы.')     : console.log('Элемент находится в правой части страницы.') }))  div.click() // Элемент находится в левой части страницы. div2.click() // Элемент находится в правой части страницы.  // определим расстояние между ними const distanceBetweenDivs = (div, div2) => console.log((div2.getBoundingClientRect().x - div.getBoundingClientRect().x + div.getBoundingClientRect().width).toFixed())  distanceBetweenDivs(div, div2) // 477 

11. Координаты курсора

Как нам получить координаты курсора? Очень просто.

// document.addEventListener('click', ev => console.log(`X => ${ev.clientX}\nY => ${ev.clientY}`)) /*     X => 348     Y => 304 */  // вот как мы можем это использовать // создаем холст и получаем его контекст const canvas = document.createElement('canvas') document.body.append(canvas) const $ = canvas.getContext('2d')  // размер холста - область просмотра canvas.width = innerWidth canvas.height = innerHeight  // создаем вспомогательную функцию для получения случайного целого числа в заданном диапазоне const randomInt = (min, max) => Math.floor(min + Math.random() * (max + 1 - min))  // создаем вспомогательную функцию для получения случайного цвета const randomColor = () => `#${((Math.random()*0xfff)<<0).toString(16)}`  // давайте порисуем // рисование фигур осуществляется по клику // центр фигуры - место клика // форма фигуры - круг или квадрат let i = 0  canvas.addEventListener('click', ev => {     $.beginPath()     // если i - четное число, то рисуем круг     // если нечетное - квадрат     if (i % 2 === 0) {         // $.arc(x, y, радиус, угол)         $.arc(ev.clientX, ev.clientY, randomInt(10, 30), 0, 2 * Math.PI)         $.fillStyle = randomColor()         $.fill()     } else {         let randomSize = randomInt(20, 60)          $.fillStyle = randomColor()         // $.fillRect(x, y, ширина, высота)         $.fillRect(ev.clientX - randomSize / 2, ev.clientY - randomSize / 2, randomSize, randomSize)     }     $.closePath()      i++ }) 

Напоследок реализуем функцию рисования определенного количества фигур.

const manyShapes = number => {     // очищаем холст     $.clearRect(0, 0, canvas.width, canvas.height)      for (let i = 0; i < number; i++) {         let randomX = randomInt(0, innerWidth)         let randomY = randomInt(0, innerHeight)         if (i % 2 === 0) {             $.beginPath()             $.arc(randomX, randomY, randomInt(10, 30), 0, 2 * Math.PI)             $.fillStyle = randomColor()             $.fill()         } else {             let randomSize = randomInt(20, 60)             $.beginPath()             $.rect(randomX, randomY, randomSize, randomSize)             $.fillStyle = randomColor()             $.fill()         }     } } manyShapes(100) 

Благодарю за потраченное время. Надеюсь, оно было потрачено не зря.

Продолжение следует…

ссылка на оригинал статьи https://habr.com/ru/post/507298/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *