Мощные усовершенствования, соответствующие стандартам, и идеи, которые сделают нашу жизнь еще проще при работе с веб-технологиями.

[DOM] Распечатать любой элемент

Печатайте любой элемент документа в собственном стиле.

document.querySelector('div').print()

Стандарт поддерживает только window.print(), но было бы действительно интересно, если бы можно было печатать все, что мы хотим, как показано.

[JS] Сглаживание вложенных элементов

Предложение по массивам уже есть в спецификации.

// current proposal solution
[1, 2, 3, [4, 5]].flat() // [1, 2, 3, 4, 5] 


Было бы действительно полезно распространить тот же подход на объекты.

const obj = { 
  name: 'mario',
  work: {type: 'cto', salary: 80000, country: 'es'}
}
obj.flat() // infinite depth and low line separator by default
/*
{ 
  name: 'mario',
  work_type: 'cto',
  work_salary: 80000, 
  work_country: 'es'
}
*/
obj.flat({depth: 2, separator: ''})
{ 
  name: 'mario',
  worktype: 'cto',
  worksalary: 80000, 
  workcountry: 'es'
}

[CSS] Родительский селектор

Было бы действительно неплохо использовать селектор родитель / предок, похожий на селектор потомков в CSS.

:first-ancestor

Если вы хотите выбрать бабушку или дедушку, мы будем использовать nth-ancestor(2)

В этом случае вторым предком будут ваши бабушка или дедушка и так далее. :last-ancestor будет html объектом.

[CSS] Расширить родственные селекторы

- для непосредственного предыдущего селектора родственника (противоположность +)

img - p // paragraphs that come immediately before any image

¬ для любого предыдущего родственного селектора (противоположно ~)

img ¬ p // all paragraphs that come before any image

Если вы хотите выбрать всех братьев и сестер, например, #user, вы можете просто положиться на предыдущий селектор предка, как показано ниже

#user:first-ancestor > *:not(#user)

[HTML] Datalist с поддержкой CSS

Было бы здорово, если бы мы могли полностью изменить стиль элемента HTML ‹datalist›, как мы это делаем с другими элементами.

[JS] Стандартная поддержка местных дат ISO

Внутри стандартной библиотеки, в объекте Date, неплохо было бы увидеть разворот и полезную функцию toLocalISOString()

[JS] Итерации по всему без деструктуризации и преобразования в массив

Все, что может быть представлено в виде списка, не должно преобразовываться при использовании функций высшего порядка, таких как forEach, filter, map и reduce

Струны

'hi'.map(x => console.log(x))
// current standard solution 
[...'hi'].map(x => console.log(x))

Объекты

const obj = {name: 'maria', type: 'person'}
obj.map(x => console.log(x))
// current standard solution
Object.entries(obj).map(x => console.log(x))

Список DOM

document.querySelector('div').classList.map(x => console.log(x))
document.querySelectorAll('div').map(x => console.log(x))
// current standard solution
[...document.querySelectorAll('div')].map(x => console.log(x))

Примечание: некоторые браузеры добавили forEachподдержку для списка DOM

[HTML] Методы моделирования событий

У нас уже есть метод click HTMLElement.click(), который имитирует щелчок мышью по элементу. Было бы неплохо иметь одно и то же для всех событий HTML.

const $select = document.querySelector('select')
$select.mousedown()
// current standard solution
$select.dispatchEvent(new MouseEvent('mousedown'))

[HTML] Используйте везде src вместо href и избегайте ненужных атрибутов и закрывающих тегов.

Чтобы избежать несовместимости, мы будем поддерживать атрибуты src и href, но в будущем второй будет устаревшим. Тот же подход с тегом script, в будущем он будет устаревшим, если внутри ничего нет.

<link src="index.css">
<a src="./page.html">page</a>
<script src="index.js">
// current support
<link rel=”stylesheet” href="index.css">
<a href="./page.html">page</a>
<script src=”index.js”></script>

[ОБЪЕКТЫ] Единое удаление хранилища, свойств объекта и элементов DOM.

Хранилище, свойства объекта JS и элементы DOM имеют разные способы удаления, однако все они являются объектами с некоторыми особенностями. Мы могли бы поддержать все разные методы и отстаивать использование delete.

delete localStorage.name ✓
delete obj.property ✓
delete document.querySelector(‘datalist’) ✕
// equal to
localStorage.name.remove() ✕
obj.property.remove() ✕
document.querySelector(‘datalist’).remove() ✓
//equal to
localStorage.removeItem(‘name’) ✓
obj.removeItem(property) ✕
document.querySelector(‘datalist’).removeItem() ✕

[JS] Избегайте проверки при поиске глубоких значений объекта

Уже есть предложение достичь глубокого значения свойства, не заставляя нас проверять, существуют ли промежуточные узлы.

// current standard support
const street = user.address && user.address.street
// current proposal solution
street = user.address?.street


[BROWSER] Асинхронные свойства console.log без использования JSON.parse (JSON.stringify (obj))

Асинхронный анализ объектов через console.loghappens. Консоль получает ссылку на объект синхронно, но не отображает свойства объекта до тех пор, пока он не будет развернут (в некоторых случаях, в зависимости от браузера и того, открыты ли DevTools при возникновении журнала). Если объект был изменен до изучения его в консоли, отображаемые данные будут иметь обновленные значения.

console.show(obj) // we can propose this to be always synchronous
// current standard solution
console.log(JSON.parse(JSON.stringify(obj)))

[JS] Неизменяемые методы

Новые методы JS никогда не изменяют существующий объект, однако есть много старых, где вам придется проверить документацию, чтобы избежать путаницы (slice vs splice)

Итак, чтобы исправить это, если у нас есть сомнения относительно того, какой метод что использовать, мы можем добавить объект в качестве второго параметра с изменяемым свойством.

array1.concat(array2, { mutable: false })

Один из моих коллег предложил еще лучшее решение. Его идея заключается в добавлении 'use immutable' строки в начале кода для выполнения JavaScript в неизменяемом режиме, так же, как мы делаем, когда хотим выполнить JavaScript в строгом режиме 'use strict'

Примечание: использование объекта в качестве второго параметра позволяет нам расширить его дополнительными свойствами, если это потребуется в будущем.

[JS] Конвейер с несколькими переменными

Предложение по конвейеру уже есть в спецификации.

// current proposal solution
5 |> double |> double |> increment |> double; // 42


Было бы действительно полезно расширить тот же подход с несколькими переменными с помощью деструктуризации.

…[1, 2, 3] |> Math.min

[JS] Расширение битов для номера типа

Увеличьте Number.MAX_SAFE_INTEGER. Прямо сейчас мы можем использовать библиотеки как bignum.js для достижения лучшей арифметической точности, потому что с vanilla JS вы можете безопасно представлять только числа между - (2⁵³ - 1) и (2⁵³ - 1).

Числа JavaScript всегда хранятся как числа с плавающей запятой двойной точности в соответствии с международным стандартом IEEE 754. В этом формате числа хранятся в 64-битном формате, где число (дробь) хранится в битах от 0 до 51, показатель степени - в битах с 52 по 62, а знак - в битах 63.

Мы можем дождаться поддержки 128 бит новыми микропроцессорами или создать новый тип для целых чисел.

Number.MAX_SAFE_INTEGER = Math.pow(2, 64) - 1
// current standard support
Number.MAX_SAFE_INTEGER = Math.pow(2, 53) - 1

В спецификации уже есть предложение о целых числах произвольной точности.

// current proposal solution
BigInt(Number.MAX_SAFE_INTEGER) + 5n // 9007199254740996n


[HTML] Расширять типы во входных данных

Как работает ‹input›, значительно различается в зависимости от значения его атрибута type. Было бы действительно полезно расширить эти типы.

// controls for entering different types of numbers
<input type="hexadecimal">
<input type="octal">
<input type="binary">
// and a new one that is growing rapidly especially in phones
<input type="footprint">

[BROWSER] Web SQL

База данных Web SQL - это API веб-страницы для хранения данных в базах данных, которые можно запрашивать с помощью варианта SQL. API поддерживается Google Chrome, Opera, Safari и браузером Android.

Поскольку Firefox и Edge не имеют собственных реализаций, они устарели, и людям следует подумать о замене своей базы данных Web SQL на современную альтернативу, такую ​​как IndexedDB. Однако IndexedDB действительно прост, я бы хотел вариант SQL, как и Web SQL, со всеми его мощными структурированными запросами и обработкой ошибок.

[JS] Исключить NULL, оставить только неопределенным

В Javascript есть две ошибки в миллиард долларов, одна для null, а другая для undefined, по крайней мере, мы должны стремиться к устранению опасности одной из них из кода.



undefined означает переменную, объявленную, но не имеющую значения.

null означает, что значение не имеет, и его нужно настраивать программно.

Оба используют разные типы и почти представляют одно и то же (отсутствие значения), и вы также можете настроить переменную на undefined. Я не вижу никакого преимущества перед всеми ошибками, возникающими при использовании другого частного случая, не имеющего значения.

if (value) // do stuff

так как

undefined || null || '' || false // false

[HTML] Движение мыши

Говорят, что люди иногда немного раздражают, Интернет полон троллей, и мы не все уважаемые программисты, поэтому нам не разрешается программно перемещать мышь.

Я вижу много преимуществ, от видеоигр до руководств, но лично я хотел бы иметь эти ходы для автоматического бета-тестирования моих приложений, мне бы хотелось имитировать различных случайных пользователей, взаимодействующих с мышью и сенсорными экранами.

И чтобы избежать потери управления мышью, мы можем добавить клавишу выхода или что-то, что невозможно заблокировать.

[JS] Получение с локальной поддержкой

Существует множество сценариев, в которых вам нужно будет получить доступ к своим локальным файлам и прочитать их. С XMLHttpRequest(XHR) вы можете получать данные любого типа, а не только XML, и он поддерживает протоколы, отличные от HTTP (включая файлы и FTP). То же самое можно сделать с библиотекой Axios, однако, целью которой было облегчить XHRне поддерживать базовые протоколы, такие как файл, по соображениям безопасности, что смешно, потому что у нас уже есть предыдущие методы.

fetch('language.en.json').then(r => console.log(r))
// current standard solution (axios is based on XHR)
axios.get('language.en.json').then(r => console.log(r))

Я бы также добавил по умолчанию определение типа файла.

[DOM] Эффективное отображение больших наборов данных

Основная идея - не загрязнять DOM, как это делает Clusterize.js.



В наших приложениях, когда мы работаем с большими наборами данных, мы просто запрашиваем видимую область в нашем локальном хранилище (IndexedDB). Представьте себе свиток, который движется вверх и вниз, и вы видите то, что мы на самом деле больше не представляем.

Было бы так удобно связать представления больших данных напрямую с нашим хранилищем, используя собственный HTML, средний путь между indexedDB и DOM, способный отображать то, что нужно, в зависимости от взаимодействия с пользователем.

<ol render="visible-area">
  <li>first item</li>
  <li>second item</li>
  <li>third item</li>
  ...
</ol>

[DOM] Цепочка

Если вы когда-либо использовали jQuery (в прошлом), вы знаете, что такое техника цепочки. Это позволяет нам запускать несколько команд одну за другой для одного и того же элемента.

// jQuery
$('div')
  .removeClass('box')
  .addClass('pen')
  .toggleClass('active')

Было бы весьма полезно иметь такое поведение при работе с элементами DOM.

document.querySelector('div').classList
  .remove('box')
  .add('pen')
  .toggle('active')
// current standard solution
const $div = document.querySelector('div')
  $div.classList.remove('box')
  $div.classList.add('pen')
  $div.classList.toggle('active')

К счастью, по крайней мере, мы можем использовать цепочки с функциями высокого порядка, такими как map, filter и reduce JavaScript.

['40', '5', '9', '10']
  .map(Number)
  .filter(n => n > 9)

[JS] Избегайте странных деталей

Если мы хотим избежать непредсказуемого поведения, мы можем установить'use strict';tag в начале кода.



Однако это не устранит многие основные странные части, как показано ниже:

[015, 016, 017, 018] // [13, 14, 15, 18] (018 should throw an error)
0 <= null // true
0 < null // false
0 == null // false (it should be true)
{a: 1} <= {b: 2} // true
{a: 1} >= {b: 2} // true
{a: 1} == {b: 2} // false
let a= new Int32Array(10)
a['1'] = 5
a['1'] // 5
a['1.1'] = 5
a['1.1'] // undefined
a['1.0'] // 5
let x = 0 / 0 // NaN (it should throw an error)
x === x // false
var a = [x] // undefined
a.includes(x) // true
a.indexOf(x) // -1
let a = [0]
a == a // true
a != a // true
a == 0 // true
0 == [] // true
a == [] // false
[101, 920, 4].sort() // [101, 4, 920]
['10', '10', '10', '10'].map(parseInt) // [10, NaN, 2, 3]

(Большинство приведенных выше примеров были представлены в забавной речи Бенедикта Муре на You Gotta Love Frontend 2018)

Восьмеричное неправильное поведение можно решить, просто используя 0o18 вместо 018. Кроме того, это легче запомнить, например, в шестнадцатеричном и двоичном формате: 0xAA и 0b10 соответственно.

Сопоставления двойного равенства (равенства) могут быть решены с использованием сопоставлений тройного равенства (равенства и типа).

Преобразование строк в числа можно решить с помощью Number вместо parseInt.

Сортировка чисел может быть решена путем определения правильной функции внутри.



Что касается остальных неопределенностей, мы обычно не сталкиваемся с ними, но было бы неплохо иметь режим, в котором не допускается странное поведение.

Ранее мы упоминали immutabletag в начале кода для выполнения JavaScript в этом режиме, так что, если мы просто будем использовать один тег для всего, чтобы сделать JS еще более привлекательным, use awesometag: используйте строгий, неизменяемый, просто дважды согласованный, равный, лучше числовая точность, отсутствие нулей и типов вывода, таких как Elm. После 2020 года это будет режим по умолчанию, поэтому вам не нужно будет добавлять его, если код более старый и не был добавлен тег, он будет выполняться в старом режиме.

[BROWSER] Не используйте внешние транспилеры, полагайтесь на браузер.

Иногда мы хотим начать использовать новые вещи, которые станут частью стандарта. Благодаря Babel, Webpack, Parcel и многим другим инструментам мы можем решить перенести на конкретную версию JavaScript. Однако вы будете бороться с совершенно другим JavaScript в своем браузере, поэтому в конце вам нужно будет использовать еще больше инструментов для отладки.

Было бы замечательно, если бы браузер мог справиться с этим, проверяя свою текущую поддержку реализации и используя внутренние инструменты, такие как Babel, позволяя пользователю всегда иметь дело со своим кодом.

Хотели бы вы изменить будущее Интернета и внести свой вклад в этот стандарт?

Чтобы внести свой вклад в спецификацию HTML и CSS, см. Https://www.w3.org/wiki/How_To_Contribute

Чтобы внести свой вклад в спецификацию ECMAScript, см. Https://github.com/tc39/ecma262/blob/master/CONTRIBUTING.md

Поддерживать связь

Что вам не хватает в HTML, CSS или JavaScript? Есть предложения? Дайте нам знать в комментариях ниже!

И если вы захотите снова заснуть в следующий раз, когда я что-то опубликую, вы также можете подписаться на меня на Medium.

Наклейки

★ Теперь у вас могут быть одни из моих самых крутых наклеек для ноутбуков и одежды о веб-разработке, зацените!