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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    может, наивно добавить квадратные скобки в строку?
    const line = '1, "221,21", "dssds", 555, "dfgfdgfdg, dd"';
    const row = JSON.parse(`[${line}]`);
    // Array(5) [ 1, "221,21", "dssds", 555, "dfgfdgfdg, dd" ]
    Ответ написан
    2 комментария
  • Как применить стили дочерным классам в зависимости их количества?

    Ankhena
    @Ankhena Куратор тега CSS
    Нежно люблю верстку
    Может, вам поможет обычный css и селектор типа
    :nth-child(3):last-child {
      тут стили, если третий является последним
    }
    Ответ написан
    Комментировать
  • Как правильно такое сверстать?

    hahenty
    @hahenty
    ('•')
    Ограничение в фиксированных ширине и количестве табов.
    Ответ написан
    Комментировать
  • Как проверить передан ли в параметр функции event?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Попробовать так и сяк
    function func(mixedData) {
      const id = mixedData?.target?.id ?? mixedData;
      console.log(id);
    }
    
    func(123) // 123
    func({target: {id: 456}}) // 456

    Что это было?!
    ?.optional chaining
    ??Nullish coalescing operator

    Но это всё не фэн-шуёво, не аккуратненько как-то.
    Лучше бы функции строго принимать один тип параметра — ожидать только id.
    А что-то поменять при вызовах.
    Ответ написан
    6 комментариев
  • Как сделана проекция надписи "Россия мы c табой!" на вирусном видео?

    Сделана в After Effects.

    Помимо озвученной критики, дополню: длина ролика ровно 10 секунд.
    Ответ написан
    5 комментариев
  • Как суммировать целые кратные 3 и 5 до указанного числа?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Повторяющийся момент, вычисление суммы последовательности от 0 до N с шагом — в функцию.

    Сложить ряд с шагом 3, ряд с шагом 5 и вычесть места, где они пересекаются и значения двоятся: в кратных 15 – тоже ряд, с шагом 15.
    const sum = number => {
      if (number < 0) return 0;
    
      // вспомогательная функция считает сумму ряда с шагом step
      const sequenceSum = step => {
        const q = Math.floor(number / step);
        return q * (q + 1) * step / 2;
      }
    
      return sequenceSum(3) + sequenceSum(5) - sequenceSum(3 * 5);
    }
    
    sum(18) // 78
    Ответ написан
    Комментировать
  • От чего могут быть артефакты на тостере в Chrome?

    Поставил в хром расширение, через которое можно налету менять стили сайта - "Stylish"

    Добавил через него:
    .question_short {
         transform-style: inherit;
    }

    и все стало нормально. У разработчиков пока ресурсов нет на исправление этого косяка.
    Ответ написан
    Комментировать
  • Как лучше поступать в такие моменты по bem?

    SeaInside
    @SeaInside
    10 лет пилю все эти штуки
    Эта разметка абсолютно правильная в двух случаях:
    1) Ваши `close` и `card` действительно нигде не переиспользуются;
    2) Объём стилей блока `some-class` остаётся адекватным для восприятия.

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

    Возьмём разметку посложнее (не надо в ней искать какого-то смысла, просто от фонаря что-то набрал для иллюстрации):
    <div class="block">
      <!-- Header -->
      <div class="block__header">
        <h2 class="block__title">Title</h2>
        <div class="block__actions">
          <button type="button" class="block__action block__action--edit">
            <span class="block__action-icon"></span>
          </button>
        </div>
      </div>
      <!-- Content -->
      <div class="block__content">
        <p>...</p>
      </div>
      <!-- Footer -->
      <div class="block__footer">
        <div class="block__about">
          <div class="block__author"></div>
          <div class="block__date"></div>
        </div>
        <div class="block__awards">
          <div class="block__award">
            <div class="block__award-inner"></div>
            <div class="block__award-tooltip">
              <div class="block__award-tooltip-content"></div>
              <button type="button" class="block__award-tooltip-close"></button>
            </div>
          </div>
        </div>
      </div>
    </div>


    Положим, что весь контент этого блока уникальный и никак не переиспользуется.
    Объём стилей `block` при такой структуре неизбежно станет некомфортным для восприятия, строк на 200-300.

    В таком случае хорошо создать внутренний блок (или несколько) просто для того, чтобы размазать сложность.
    `block-header`, `block-footer` или даже `block-footer-award`.

    Самое главное здесь организовать файловую структуру / конфигурационный файл / чем вы там ещё собираете таким образом, чтобы было очевидно, что `block-footer` - это не самостоятельный блок, а внутренний блок `block`, нужный только для упрощения восприятия, и он не может / не должен использоваться в отрыве от него (в этом случае у него не должно быть в названии общего префикса с `block`, чтобы не создавать путаницу)

    * И не забывать о том, что даже для таких внутренних блоков действуют те же самые правила, что и для других - вся внешняя геометрия задаётся через элементы.
    Ответ написан
    8 комментариев
  • Зачем в теге script код обернут в комментарий?

    Stalker_RED
    @Stalker_RED
    В прошлом тысячелетии были браузеры, которые не понимали тег <script> и отображали его содержимое на странице. Потому содержимое тегов <script> было принято комментировать, чтобы не пугать пользователя.
    Зачем это продолжают делать в opencart в 2022 - неведомо, возможно дань традиции.
    Ответ написан
    1 комментарий
  • Как написать функцию которая возвращает класс в зависимости от параметра?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    Ответ написан
    Комментировать
  • Как нарисовать плавные струйки дыма?

    DarkWood
    @DarkWood
    Я опишу вам алгоритм, который позволит создать в Illustrator нечто похожее. Подойдет ли оно вам - смотрите сами. Автоматизировать этап создания кривых - крайне сложно. Думаю, из описания сами поймете почему.

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

    61802664abff2460020473.png

    Создаете между ними бленд (Ctrl+Alt+B) с дистанцией в 1 пиксель. Можно поставить меньше - тогда переходных кривых будет больше. При толщине контура в 1 пиксель меньше 0.4 пикселя ставить уже особого смысла не будет.

    618026a380abc845121510.png

    Не переживайте, что всё слилось в одноцветье. Кстати, желаемый цвет вы можете задать как сейчас, так и на следующем этапе. Рекомендую делать это как раз там.

    На всякий случай скопируйте бленд (Ctrl+C > Ctrl+F), чтобы была возможность что-то исправить, если последующий результат не понравится.

    Выполните команду Object> Blend> Expand.

    Далее Shift+Ctrl+G

    Задаете малую непрозрачность (около 10%). Как раз сейчас лучше всего менять цвет. Можете также поменять режим смешивания.

    618026b345bc8360746368.png

    Ctrl+G.

    Большее свечение на "петлях" можно сделать дубликатом этой группы (Ctrl+C > Ctrl+F). Эту копию тоже надо будет потом разгруппировать (Shift+Ctrl+G) изменить цвет на более светлый, непрозрачность и режим смешивания по вкусу.

    618026de13dcb347638107.png

    Собственно, узор готов.

    При создании бленда вы можете нарисовать еще одну кривую и расположить ее в панели слоев между двух других. Дальше весь фокус в том, что ей нужно задать цвет фона. И в данном случае цвет других кривых нужно задавать сейчас. Потом тоже можно через команду Recolor Artwork, но это лишние действия.

    618026e910192073261890.png

    Продолжение такое же: Shift+Ctrl+G, меняете прозрачность, режим смешивания и т.п.

    618027083db5a504901276.png

    Можно добавить еще одну кривую цвета фона и переплести ее с остальными. Можно переплетать два бленда от основного цвета к цвету фона и т.д. и т.п.

    Все команды, кроме рисования кривых, прекрасно записываются в экшен.
    Ответ написан
    2 комментария
  • Почему у переменной тип unknown?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    Во-первых, infer в самом предикате участвует как any
    Во-вторых, функция с меньшим количеством аргументов является подтипом для функции с большим количеством аргументов (это позволяет, например, отдать в колбэк функцию, которая не использует всех переданных ей аргументов)

    То есть тип () => void является потомком типа (param: any) => void, а значит Ваш предикат в типе A становится истинным и уходит в ветку, где Вы возвращаете R из infer, который выводится к вершине иерархии - типу unknown

    То что Вы задумали, можно сделать так:
    type A<T> = T extends (...param: infer P) => void
      ? P extends [infer R, ...unknown[]]
        ? R
        : string
      : string;
    Ответ написан
    1 комментарий
  • Как реализовать такой блок?

    Ankhena
    @Ankhena Куратор тега CSS
    Нежно люблю верстку
    1 комментарий
  • Как сделать такой элемент при наведений?

    Ankhena
    @Ankhena Куратор тега CSS
    Нежно люблю верстку
    Поскольку у ссылок есть иконки и они, вероятно, будут сделаны с помощью псевдо, то подумала, что нужно придумать решение с помощью только одного псевдоэлемента. Да и вообще, раз можно одним, то зачем писать два..



    код

    <nav>
      <ul>
        <li><a href="">link</a></li>
        <li><a href="">link</a></li>
        <li><a href="">link</a></li>
        <li><a href="">link</a></li>
        <li><a href="">link</a></li>
      </ul>
    </nav>


    nav {
      width: 200px;
      background: #92aef4;
    }
    
    ul {
      --color: white;
      --radius: 30px;
      --smoothing-radius: 29.4px;
      border-right: 10px solid var(--color);
      padding: 0 0 2em 1em;
      list-style-type: none;
    }
    
    a {
      position: relative;
      display: block;
      padding: 0.5em;
      border-radius: var(--radius) 0 0 var(--radius);
      text-decoration: none;
      color: #6704f2;
    }
    
    a::before {
      content: "❄ ";
      color: white;
    }
    
    a:hover::before {
      color: deeppink;
    }
    
    a:hover {
      background: var(--color);
    }
    
    a:hover::after {
      content: "";
      position: absolute;
      right: 0;
      top: 50%;
      transform: translateY(-50%);
      width: var(--radius);
      height: calc(100% + 2 * var(--radius));
    }
    
    li:not(:last-child):not(:first-child) a:hover::after {
      background: radial-gradient(at top left, transparent var(--smoothing-radius), var(--color) var(--radius)) no-repeat top right / var(--radius) var(--radius),
        radial-gradient(at bottom left, transparent var(--smoothing-radius), var(--color) var(--radius)) no-repeat bottom 0 right 0 / var(--radius) var(--radius);
    }
    
    li:first-child a:hover::after {
      background: radial-gradient(at bottom left, transparent var(--smoothing-radius), var(--color) var(--radius)) no-repeat bottom 0 right 0 / var(--radius) var(--radius);
    }
    
    li:last-child a:hover::after {
      background: radial-gradient(at top left, transparent var(--smoothing-radius), var(--color) var(--radius)) no-repeat top right / var(--radius) var(--radius);
    }
    body {
      padding: 50px;
      margin: 0;
      font-size: 20px;
      font-family: 'Neucha', cursive;
      background: #eee;
    }

    Ответ написан
    Комментировать
  • Как сделать такого рода эффект?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    не могу найти в поиске

    SVG-маски, маски с помощью clip-path в CSS, маски на канвасе, маски в шейдерах, и.т.д. В общем гуглите все, что связано со словом "маска". Вариант с шейдерами самый производительный, с SVG - самый простой.

    Пример с SVG:


    Пример с шейдерами (не совсем такой, но для передачи идеи пойдет):
    Ответ написан
    Комментировать
  • Является ли сужение области аргументов родительского класса нарушением LSP?

    bingo347
    @bingo347
    Crazy on performance...
    Добавлю к Василий Банников, что:
    1. хоть и в js/ts override происходит неявно, typescript не даст сделать override метода с другими параметрами (хотя с any и unknown в родителе все ок, так как unknown надтип для любого типа, а any вообще ломает типизацию). К конструктору это не относится, так как это не override.
    2. LSP не про корректное поведение программы, LSP про корректную логику программы, про то что если некто ожидает инстанс Parent, а получит вместо него истанс Child, то поведение для него останется предсказуемым.
    Например, если Parent предоставляет некоторую абстракцию для сохранения данных, Child1 сохраняет данные в MySQL, а Child2 в MongoDB - это соответствует LSP.
    А если некий Child3 вместо сохранения данных шлет их на почту админу, то это нарушает LSP, хотя бы потому, что прочитать их впоследствии будет затруднительно.
    Ответ написан
    Комментировать
  • Как избавиться от утечек памяти при самовызове промисов?

    0xD34F
    @0xD34F Куратор тега JavaScript
    С каждым "неудачным" вызовом функции camel у вас добавляется ещё один промис, ждущий разрешения. 10 "неудачных" вызовов - 10 промисов в режиме ожидания. 1000 попыток - 1000 промисов. И т.д. Каждый съедает немного памяти.

    Не нужно вам тут никакого "самовызова". Вместо рекурсии сделайте цикл:

    function test() {
      return new Promise(async (resolve) => {
        let result = null;
    
        do {
          result = await camel() || await new Promise(r => setTimeout(r, 1000));
        } while (!result);
    
        resolve(result);
      });
    }
    Ответ написан
    3 комментария
  • Как преобразовать имена свойств объекта из kebab-case в camelCase?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    В дополнение к ответу 0xD34F нормальная типизация такой функции (нужен typescript 4.1 или выше):
    type AsCamelCase<S extends string> = S extends `${infer A}_${infer B}` ? `${A}${Capitalize<AsCamelCase<B>>}` : S;
    type CamelCaseKeysRecord<T> = T extends Record<PropertyKey, unknown> ? {
        [K in string & keyof T as AsCamelCase<K>]: CamelCaseKeysRecord<T[K]>;
    } & {
        [K in Exclude<keyof T, string>]: CamelCaseKeysRecord<T[K]>;
    } : T;
    
    function toCamelCaseKeys<T>(val: T): CamelCaseKeysRecord<T> {
        if (Array.isArray(val)) {
            return val.map(toCamelCaseKeys) as unknown as CamelCaseKeysRecord<T>;
        }
        if (typeof val === 'object') {
            return Object.fromEntries(Object
                .entries(val)
                .map(([k, v]) => [
                    k.replace(/_+(.)/g, (_, g) => g.toUpperCase()),
                    toCamelCaseKeys(v as Record<string, unknown>),
                ])) as CamelCaseKeysRecord<T>;
        }
        return val as unknown as CamelCaseKeysRecord<T>;
    }

    https://www.typescriptlang.org/play?target=7&ts=4....
    Ответ написан
    6 комментариев