Будни разработчика
14.6K subscribers
1.18K photos
337 videos
7 files
2.02K links
Блог Lead JS-разработчика из Хельсинки
Автор: @bekharsky

По рекламе: https://telega.in/channels/htmlshit/card?r=GLOiHluU или https://t.iss.one/it_adv

Чат: https://t.iss.one/htmlshitchat

№5001017849, https://www.gosuslugi.ru/snet/679b74f8dad2d930d2eaa978
Download Telegram
#фишка дня

Есть псевдокласс :disabled, который выберет отключенные поля. Есть псевдокласс :read-only, который выберет недоступные для ввода поля (только для чтения).

Вот только есть нюанс.

Отключенные поля они так-то тоже для ввода недоступны. Как же тогда быть?

Использовать селектор атрибута: [readonly].

Пример: https://codepen.io/elad2412/pen/wvpmjGR

Отличие disabled-полей от readonly: первые не отправятся с формой вообще, а значение вторых просто нельзя изменить.

Скелетон вернётся с новыми подробностями о фронтенде завтра.

#css #html #input #бородач
👍17🔥2
#заметка дня

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

А что, это же так естественно и удобно, пространство имён не засоряется...

Нет! Нет и ещё раз нет. Каждый раз, когда происходит ререндер родителя, будет происходит и ререндер дочернего компонента.

Чем это чревато? Ну, например, объявленный вами инпут будет, как минимум, терять фокус.

Вообще, у Алекса Сидоренко, на чей твит выше я сослался, огромное количество полезных советов о внутрянке React. Крайне рекомендую, котаны. От души.

#react #rerender #antipattern
👍25
#перевод дня

Я тут не так давно постил шикарную статью о том, как рисовать веревку (канат) на основе любого SVG-контура:
https://t.iss.one/htmlshit/1819

Оказывается, на Хабре есть её перевод, который я почему-то пропустил!

Вот он: https://habr.com/ru/company/nmg/blog/719822/

Что статья, что перевод отличные и достойны пристального внимания. Даже если ты никогда в жизни веревку не применишь (ну не каждый же человек делает сайты браслетам с якорями, правда?), сам подход к расстановке приоритетов и отрисовке геометрии — очень полезен.

Я сам очень часто сначала рисую анимацию или схему, а потом уже верстаю.

#svg #geometry
👍9🔥1
#фишка дня

В Safari Technology Preview наконец-то стал поддерживаться @counter-style!

MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/@counter-style

Что это значит?

Что наконец-то можно адекватно использовать все возможности стилизации списков, а не выдумывать псевдо- и обычные элементы просто чтобы добавить иконки к элементам списка. Да и не только иконки: больше не надо долбиться в ручной counter-increment.

От простых букв и цифр до эмодзи и картинок. Например, захотелось вам изобразить первое, второе и третье место с помощью эмодзи, нет ничего проще: https://codepen.io/alinaki/pen/WNgmeLg

К сожалению, картинки пока не поддерживаются нигде... но это вопрос времени. Эмодзи-то можно 🙂

#css #feature
🔥152👍2🤣2
#заметка дня

Плоские интерфейсы вошли в нашу жизнь лет 10 назад и уходить не собираются.

Набора из linear-gradient, box-shadow, drop-shadow, border-radius хватает практически на всё. Вот такое сверстать не проблема: https://codepen.io/joshnh/pen/DmdxLY

Но так было не всегда и до сих пор в игроподобных интерфейсах можно заметить весьма сложно оформленные элементы. Например, кнопки с орнаментом. Как же их верстать?

На помощь приходят таблицы и т. н. техника сдвижных дверей (sliding doors).

Другое название таблиц — 9-slice scaling. Есть плагины для Figma, позволяющие легко резать картинки. В итоге остаётся сверстать, используя background-repeat, псевдоэлементы или border-image.

Суть же дверей в том, что у вас есть один неподвижный элемент с достаточно длинным нужным паттерном и второй — это его завершение. Раньше решалось двумя тегами, а нынче — псевдоэлементы решают: https://codepen.io/chriscoyier/pen/rZPPOd

Если интересно — следующим постом могу дать больше примеров. Голосуем 🙂

#css #button #9slice
👍212
#фишка дня

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

Вот сказал я, берёте картинку, режете на 9 кусочков — и долбитесь в псевдоэлементы... А подписчик, мол, дядя, на дворе 2023 год, пора бы научиться в border-image. И я такой: «А, чо? В смысле?».

Короче, это я к тому, что свиток на картинке из поста выше верстается в один элемент и одну строку CSS!

Ну вот, посмотрите: https://codepen.io/mdss/pen/KKxEJWQ

Развиваемся, котаны. Развиваемся.

#css #border #9slice
👍43😱7🔥4
#такое дня

TFW тебе даже отвечать не надо, настолько ты крутой.
👍14😁6🤡2🥱21
#til дня

Уж не знаю, сколько из вас использует MySQL в работе (кстати, сколько?), но вот чего сегодня я узнал.

Надо вам что-то отсортировать так, чтобы какие-то конкретные элементы должны были идти первыми. Что же делать?

Очень просто, давайте троешников вперёд:
select * from students order by grade = 3;

Ну и пример (классная песочница, кстати): https://www.mycompiler.io/view/Da4iNcAg2Vy

В примере чуть сложнее: остальное тоже отсортировано через case 🙂

#mysql
👍12
#новость дня

Года три назад с большой помпой было объявлено о создании набора инструментов для JavaScript: транспайлер, сборщик (бандлер), среда для тестирования, линтер, форматтер. Такой себе швейцарский нож с названием Rome Tools. Шум стоял неимоверный.

В 21 году основатели подняли 4.5 ляма на создание open source-ориентированной компании. И вот что-то пилили вплоть до декабря 22 года, когда стало известно о том, что денежки — всё и сотрудники разбегаются.

Но открытый проект никуда не делся и Эмануэль Стоппа сотоварищи как обещал так и продолжил работу. И вот выпустили два дня назад 12 релиз: https://rome.tools/blog/2023/03/28/rome12/

Я Rome не пробовал, но звучало многообещающе. История о том, как замахнулись изменить мир, но забыли про пиар и общение с сообществом.

Rome wasn't built in a day. Наблюдать за ситуацией интересно. Но, думаю, наработки давно расползлись по более шустрым и менее амбициозным проектам.

Ну а если кому нужно всё в одном — Bun отличный выбор.

#js #bundler
👍111
#цитата дня

Каждая операционная система для чего-то нужна. OSX — разрабатывать веб-приложения, Linux — запускать веб-приложения, Windows — тестировать в IE.

P. S. Цитата аж 2012 года 🤡
😁23💩8🤡8👎1
#заметка дня

Как часто вы используете отладчик браузера для поиска проблемных мест в своих скриптах?

А надо чаще!

Но одна из проблем отладки современных веб-приложений — огромное количество сторонних скриптов. Начиная от пакетов node_modules, заканчивая средствами аналитики и журналирования.

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

Очень просто! Смотрим иллюстрацию. У вас есть три варианта:
• Add directory to ignore list: для пропуска node_modules, если у вас, конечно, карта кода подключена.
• Add script to ignore list: для пропуска конкретного скрипта
• Add all third-party scripts to ignore list: игнорировать все сторонние скрипты разом (Chrome 112).

Подробнее, как обычно, нужно читать в блоге разработчиков Chrome.

Рекомендую туда почаще заглядывать, котаны.

#devtools #ignore #sourcemaps
🔥10👍3💩2
#такое дня

Дежурное напоминание о том, что перфекционизм убивает мотивацию и не боги горшки обжигают.

Откуда скриншот? Да из типов для React: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L1194

Не то чтобы я вам предлагал везде писать any, но уж тормозить разработку и быть party pooper-ом TypeScript не должен.

P. S. обновил ссылку до React 18.

#ts #react
😁5👍3
#заметка дня

Вы что, реально думали, что я забросил свой проект пульта для телевизора Samsung на Flutter?

Ну, так-то, да... забросил. Но вернулся на днях!

Напомню, что тогда дочка грызла основной пульт и я захотел сделать альтернативу, заодно изучив Flutter. Кинул клич в канале в поиске дизайнеров, быстренько сверстал получившееся на Dart.

Итак, я остановился на том, что научился посылать широковещательное сообщение в локальную сеть и собирать отклики. Следующим шагом стало бы получение информации о телевизоре: IP-адрес, название модели и телевизора, уникальный id на всякий случай. И здесь имеются два варианта:

1. Широковещательный поиск по SSDP-запросу (если у вас дома есть телевизор Samsung, можете попробовать код из этого поста) urn:samsung.com:device:RemoteControlReceiver:1 отдаёт некий интересный адрес https://192.168.3.6:7676/rcr/. Несложно догадаться, что rcr это receiver, приёмник. И там имеется XML со всей необходимой информацией, включая поддердживаемые протоколы. Но, честно, покажите мне человека, который любит разгребать XML? Да и пакет отдельный надо ставить, давно уже формат не в фаворе... Но если интересно, как это делают на Dart — могу рассказать.

Но за этим API толком больше ничего не стоит, документация Samsung прям скудная, надо искать по крупицам. Но есть второй вариант!

2. На телевизорах с 2016 года имеется web-API! https://192.168.3.6:8001/api/v2/ (не спрашивайте, куда делся v1).

У меня ушёл час чтобы понять, что в конце слэш обязателен. Впрочем, ничего нового.

И вот GET-запрос на этот адрес отдаёт, кто бы мог подумать, JSON. А поддержка JSON в Dart нативная.

Запихиваем ответ в ChatGPT, просим создать класс и фабрику из JSON. Вы серьёзно думали, что я определения типов в 2023 году буду сам писать? Нейронка отлично справилась, создав на каждый вложенный объект по классу, адекватно их назвала, преобразовала булевы строки в нормальные значения и вообще умница.

Но, как я уже сказал, документация Samsung на всю эту тему максимально ужасная. Нет ни слова насчёт того, как же запустить, например, приложение или получить их список.

Благо, на Reddit есть целые сообщества, которые ищут такую информацию. Вот, например, один такой пост: https://www.reddit.com/r/homeassistant/comments/fxddeh/controlling_a_samsung_tv/

Итого, чтобы запустить, например, Netflix мне нужно или совершить пустой POST-запрос на https://192.168.1.145:8001/ws/apps/Netflix или пустой POST-запрос на https://192.168.3.6:8001/api/v2/applications/11101200001

А GET-запросы просто выдадут состояния этих приложений. Их перебором можно узнать, что на телевизоре установлено. Самое смешное, опять же, то XML, то JSON соответственно. А ответ на POST в первом случае — 200 и URL, а во втором — 200 и true 🤡 Так что ваши API не настолько и плохи, как вы думаете.

Как ищутся все эти ID типа 11101200001? Удивительное дело, но в вашем аккаунте в Samsung есть страничка с устройствами, которая больше напоминает домашнюю страницу роутера. И там показано, какой вид активности сейчас на телевизоре происходит. Ну а конкретно адреса API ищутся внутри скачиваемого SDK. Документации (хором) нет.

Кажется, я и так уже достаточно много написал. Можем с вами договориться, например, что я буду писать по одному посту про Flutter в неделю. Таким образом у меня будет мотивация что-то делать и посты могут стать более приземлёнными. Отпишитесь в комментариях.

Вариантов постов много: как работает навигация во Flutter-приложениях, как сделать аналог BottomSheet из iOS, как совершить запрос и разобрать XML/JSON, как верстать UI... Задавайте ваши ответы.

#flutter #remote
🔥235💩2👍1
#статья дня

Видите, подписчик проблему обвёл синей линией?

Оказалось, он просто был не в курсе, что пару лет назад я писал статью с прекрасным названием «Загадка дыры».

По-моему, пришло время её репостнуть, раз проблема всё ещё встречается: https://telegra.ph/Zagadka-dyry-07-18

Не дырите, котаны.

#img #inline #block #flex #бородач
👍194
#фишка дня

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

Достаточно проделать следующий трюк:

@keyframes appear {
from {
…whatever
}
}

Это анимирует объект в момент его появления из положения, заданного в анимации, в то, что указано в стилях.

Пример на CodePen: https://codepen.io/alinaki/pen/XWXORzM

Попробуйте обновить страницу и поиграться со значениями.

Спасибо Twitter-банде https://twitter.com/keyframers за эту находку.

#css #keyframes #animation #бородач
🔥183👍31
#заметка дня

Как разместить иконки на странице или в web-приложении?

Очевидно — картинкой. Шрифтом ещё. CSS-спрайтом. SVG... Но один из наиболее удобных и универсальных способов — это SVG-спрайты.

По сути всё просто: работаем с элементом symbol. Символ — это буквально что угодно в SVG, что не отобразится сразу, но на что можно будет сослаться.

SVG-файл становится контейнером таких символов:

<svg xmlns="https://www.w3.org/2000/svg">
<symbol id="icon-circle" viewBox="0 0 32 32">
<circle cx="16" cy="16" r="16" />
</symbol>
<symbol id="icon-square" viewBox="0 0 32 32">
<rect x="0" y="0" width="32" height="32" />
</symbol>
</svg>

И кладём этот контейнер куда угодно. Например, в файл или сразу в HTML (об этом ниже). А дальше всё очень просто:

<svg xmlns="https://www.w3.org/2000/svg" width="32" height="32">
<use href="icons.svg#icon-circle" />
</svg>

Удобно отлаживать, меньше запросов. Сплошные плюсы. Понятно, что так можно не только иконки хранить.

Но как этим пользоваться, например, в React?

Как-как, компонент сделать, как всегда. Объявили компонент Icon и передаём в него id нужного спрайта. Смотрим в песочницу и запоминаем: https://codesandbox.io/s/condescending-bas-1beiol?file=/src/App.js

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

Вообще, моя любимая часть в песочнице это даже не спрайты, а ...props. Если интересно — потом расскажу, почему :)

Всем спрайт, котаны!

#svg #symbol #sprite #react
🔥253
#фишка дня

Давайте сегодня продолжим тему SVG.

Не знаю, скольким из вас вообще известно, как создаются простейшие SVG-анимации заполнения кривой (кстати, скольким?), но, зная длину кривой (контура, path), её заполнение легко можно анимировать.

Примерно вот таким образом: https://codepen.io/alinaki/pen/oNXjEzz?editors=1111

Как узнать длину кривой? Ну это можно посмотеть всё в том же кодпене: circle.getTotalLength().

Но я сегодня не про анимации хочу рассказать, а про более интересный случай использования полученной информации.

Например, как разместить что-либо по контуру кривой? Для простоты, сделаем бусы.

1. Нарисуем окружность.
2. Получим её длину
3. Найдём на окружности 15 равномерно распределённых точек используя getTotalLength getPointAtLength
4. Разместим 15 бусин-кругов по контуру.

Вуаля: https://codepen.io/alinaki/pen/eYPmayO

Такое можно и с текстом провернуть, кто первый? :)

#svg #path #length
15👍4
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня

А знали ли вы, что в Chrome DevTools есть возможность эмулировать различные доступные на устройствах сенсоры?

Ну из очевидного: гироскоп, компас, освещённость.

Джей, деврел в Google, замапил сенсоры на 3D-кубик и запилил для нас демо на побаловаться: https://codepen.io/jh3y/pen/KKQZQNj

Открывайте пример, врубайте DevTools, вызывайте сочетанием Ctrl(Cmd)-Shift-P панель команд и ищите там Sensors. Как найдёте — сообщите 😉

#codepen #devtools #sensors #бородач
👍9
#заметка дня

Продолжаем эпопею про написание пульта для телевизора на Flutter.

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

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

А делается это довольно просто.
1. Постучались на WebSocket API, передав название приложения. Почему-то в моём случае стучаться пришлось на secure-вариант (ws vs wss, это как http vs https), разрешив использование самоподписанных сертификатов (потом расскажу, что не так).
2. Телевизор спросит разрешение на удалённое управление. И вот тут придётся подтверждать с пульта или джойстика на телевизоре, других вариантов нет. В ответ будет прислан токен. Чтобы больше не спрашивал — все дальнейшие запросы должны содержать в себе идентификатор приложения и токен, собственно. Как параметры запроса: ?name=xxx&token=yyy.
3. Формируем команду, на которую, естественно, опять нет никакой документации. Но когда это нам мешало? Копаемся в issues легендарной (в узком кругу) библиотеки Samsungctl, находим нужный формат.
4. Отправляем.
5. ...
6. Пищим от восторга.

На этом месте будет небольшая ода Джаваскрипту: нет на свете языка, который бы позволил быстрее настряпать всякие тестовые куски кода, вне зависимости от того, нужен вам UI, или нет. Ну, может, Python что-то способен противопоставить. Тяп-ляп и готов код, чтобы быстро проверить теорию или соответствие стандарта вашему телевизору: https://gist.github.com/bekharsky/80fce4263304eedcec7a46045b1a0ebd

Представьте, как было бы обидно, написать это всё на Dart и обнаружить, что мой телевизор старее, чем нужно. Впрочем, там не сильно сложнее, сделаю сегодня.

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

К слову, если у кого-нибудь есть телевизоры Samsung и кому не лень, проверьте код выше (он просто выключает звук) и напишите модель в комментарии, пожалуйста (как узнать модель — смотрите ссылку в первых словах поста, там про API телевизора). Это мне потом очень поможет :)

Удачи в ваших пет-проектах, котаны.

P. S. если кому интересно, вот тут человек на Go автоматизирует браузер телевизора, чтобы дашборды Grafana запустить. Целый кладезь команд и подсказок. Красивое: https://gist.github.com/freman/8d98742de09d476c4d3d9e5d55f9db63

#flutter #dart #websockets
11👍2
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня

Я писал как-то о том, что одной из одновременно полезных и раздражающих вещей в CSS-препроцессорах является возможность создавать вложенность, nesting.

Склеивать селекторы, классы в БЭМ и не только, вкладывать теги... Удобно? Писать — да, поддерживать — не очень. Вот тут: https://t.iss.one/htmlshit/1643

К чему это я?

К тому, что Chrome 112 начал поддерживать CSS Nesting! Официальный! Который теперь часть спецификации: https://www.w3.org/TR/css-nesting-1/

.nesting {
color: hotpink;

> .is {
color: rebeccapurple;

> .awesome {
color: deeppink;
}
}
}


Ну и на видео показан процесс отладки этого дела в DevTools.

Статья в блоге разработчиков Chrome: https://developer.chrome.com/articles/css-nesting/, хороший способ вспомнить, что к чему.

Моё мнение остаётся прежним: для псевдоклассов, псевдоэлементов или влияния на соседей (+, ~) — очень хорошо. Для формирования БЭМ (склеивания классов) — нет.

Всем nesting, котаны!

#css #nesting
14👍4