• Как сделать такую анимацию?

    mizutsune
    @mizutsune
    Frontend Developer
    На самом деле не совсем понятно, когда запускается анимация? Если после нажатия на кнопку или после события сhange, тогда можно сделать например так:

    .is-active {
         animation-name: shake;
         animation-direction: alternate;
         animation-duration: 1s;
         animation-iteration-count: 4;
    }
    
    @keyframes shake {
         from {
              transform: translateX(0px);
         }
         to {
              transform: translateX(150px);
         }
    }


    const button = document.querySelector(".button");
    
    button.classList.add("is-active");
    
    button.addEventListener("animationend", (event) => {
         event.stopPropagation();
         button.classList.remove("is-active");
    }, { once: true });


    То есть добавить активный класс кнопке, а после окончания анимации удалить добавленный класс.

    Или кнопка "убегает" от курсора в каком-то определенном направлении?

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

    mizutsune
    @mizutsune
    Frontend Developer
    Есть ли возможность как то подгрузить или считать url-адрес картинок (не объявленных в дом-дереве) из определенной папки лежащей в корне сайта?


    Средствами одного только CSS такое не сделать.
    Ответ написан
    Комментировать
  • Почему при добавлении новых элементов в массив, цикл их не видит?

    mizutsune
    @mizutsune
    Frontend Developer
    Создаю с нуля инпуты и кнопку для добавления новых элементов массива, добавляю, но цикл их не видит и не выводит в окно.


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

    let li = document.createElement("li");
    let content = `${elem.item}, цена ${elem.price}, номер ${elem.index}`;
    li.textContent = content;
    ul.appendChild(li);


    Но указав новые данные для: item, price, index.

    Первый вариант

    but.addEventListener("click", () => {
        goods.push({
            item: input1.value,
            price: input2.value,
            index: input3.value,
        });
    
        ul.innerHTML = goods.map(({ item, price, index }) => {
            return `<li>${item}, цена ${price}, номер ${index}</li>`
        }).join("");
    });



    Или:

    Второй вариант

    but.addEventListener("click", () => {
        goods.push({
            item: input1.value,
            price: input2.value,
            index: input3.value,
        });
    
        const { item, price, index } = goods[goods.length - 1];
    
        let li = document.createElement("li");
        let content = `${item}, цена ${price}, номер ${index}`;
        li.textContent = content;
        ul.append(li);
    });

    Ответ написан
    3 комментария
  • Как уместить анимацию на мобильных устройствах?

    mizutsune
    @mizutsune
    Frontend Developer
    Для начала у элементов curley, web, dev, уберите свойства: left, right, bottom. Далее можно немного подправить остальные стили у элементов + немного изменить разметку и ситуация улучшится.

    <div class="container text-uppercase">
        <p class="text curley">Hello</p>
        <div class="group">
          <p class="text web">Hello</p>
          <p class="text dev">Hello</p>
        </div>
        <div class="hide-text"></div>
      </div>


    .container {
         width: 100%;
         max-width: 600px;
         margin: 0 auto;
    }
    
    .text {
         --sw-1: drop-shadow(0 0 1px black);
         --sw-2: drop-shadow(0 0 2px red);
         font-family: "Orbitron", sans-serif;
         background: linear-gradient(darkred 30%, cyan, white, cyan, darkred 70%);
         -webkit-text-stroke: 3px cyan;
         -webkit-background-clip: text;
         -webkit-text-fill-color: transparent;
         font-weight: 900;
         font-size: 4.1em;
         text-align: center;
         text-transform: uppercase;
         filter: var(--sw-1) var(--sw-1) var(--sw-2) var(--sw-2);
         opacity: 0;
         margin: 0;
    }
    
    .group {
         display: flex;
         gap: 10px;
         justify-content: center;
    }
    
    .curley {
         animation: bg-shift 1s infinite linear alternate, 
                    scale 750ms ease-in forwards 3.5s, 
                    jump 500ms ease-out forwards 5.7s, 
                    blur-in 300ms linear 3.5s,
                    zoom 4s ease-in-out 6.25s, 
                    flip 500ms linear forwards 8s;
    }
    
    .web {
         animation: bg-shift 1s infinite linear alternate, 
                    scale-angle1 3s ease-in-out forwards 2s, 
                    blur-in 500ms linear 2s, 
                    rotate-up1 250ms ease-out forwards 5.7s,
                    zoom 1.5s ease-in-out 6.25s, 
                    flip 500ms linear forwards 8.5s;
    }
    
    .dev {
         animation: bg-shift 1s infinite linear alternate, 
                    scale-angle2 3s ease-in-out forwards 2s, 
                    blur-in 500ms linear 2s, 
                    rotate-up2 250ms ease-out forwards 5.7s,
                    zoom 1.5s ease-in-out 6.25s, 
                    flip 500ms linear forwards 8.5s;
    }
    
    /*  Код анимаций без изменений */


    Размер шрифта скорее всего придётся уменьшать через @media запросы, чтобы на мобильниках всё нормально отображалось. Но в целом ваши анимации и стили можно и нужно улучшить.
    Ответ написан
    Комментировать
  • Почему не работает for внутри append?

    mizutsune
    @mizutsune
    Frontend Developer
    Почему не работает for внутри append?


    Потому что это синтаксическая ошибка. Цикл for не будет возвращать подобным образом массив с шестью элементами, которые вы пытаетесь вставить как набор HTML тегов в элемент с классом second.

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

    const getSetOfElements = () => {
         let arr = [];
    
         for (let i = 1; i <= 6; i++) {
              arr.push(`<div class="test">${i}</div>`);
         }
    
         return arr;
    }
    
    const setOfElements = getSetOfElements();
    
    $('.second').append(`<p>hello</p> ${setOfElements.join("")}`);


    Или:

    const setOfElements = [...Array(6)].map((_, i) => (`<div class="test">${i + 1}</div>`)).join("");
    
    $('.second').append(`<p>hello</p> ${setOfElements}`);


    Чтобы более корректно описать суть вашей ошибки, понадобиться много букв и возможно вам будет не интересно читать, а мне жалко тратить своё время. Поэтому можете пройтись по документации, ознакомиться с синтаксисом языка. Многое сразу встанет на свои места.
    Ответ написан
    2 комментария
  • Почему при наведении на один элемент не делает видимым другой?

    mizutsune
    @mizutsune
    Frontend Developer
    С помощью CSS, при такой структуре разметки, желаемого результата добиться не выйдет.

    Однако можно сделать вот так:

    .ava:hover ~ #profiles_show .block {
       display:block;
    }


    Ну, а ещё в html у вас class="ava", а в css - .avatar. С этим нужно бы определиться... либо одно, либо другое.

    Кстати использовать ID атрибуты для стилизации элементов - моветон.
    Ответ написан
    2 комментария
  • Как переделать double range slider, чтобы использовать несколько на странице?

    mizutsune
    @mizutsune
    Frontend Developer
    Как вариант, можно обернуть элементы управления, инпуты и сам слайдер в родительский контейнер, с определенным id атрибутом или классом. Далее нужно обернуть код слайдера в функцию и передавать в эту функцию в качестве аргумента селектор родительского контейнера. Таким образом можно будет привязать функцию к элементу разными способами.

    Например так:

    slider("#target-element-id-1");
    slider("#target-element-id-2");


    Или если слайдеров много и у них одинаковый класс, тогда можно так:

    document.querySelectorAll(".element").forEach(n => slider(n));


    Пример:

    Ответ написан
  • Как проверить, что класс существует и выполнить действие alert?

    mizutsune
    @mizutsune
    Frontend Developer
    Например с помощью Mutation Observer API.

    const targetElement = document.querySelector(".player-selector");
    
    const observer = new MutationObserver((mutations) => {
         mutations.forEach(({ target: t }) => {
              t.classList.contains("is-finished") ?
                   alert("element contains class") :
                   alert("element does not contain a class");
         })
    });
    
    observer.observe(targetElement, {
         attributes: true,
         attributeFilter: ['class']
    });
    Ответ написан
    Комментировать
  • Почему при наполнении текста ломается верстка?

    mizutsune
    @mizutsune
    Frontend Developer
    .programs__name {
       min-width: 0;
    }
    
    .programs__name p {
       white-space: nowrap;
       text-overflow: ellipsis;
       overflow: hidden;
    }


    Обрезать текст можно с помощью набора свойств: text-overflow, overflow и white-space(хотя возможно оно здесь лишнее). А вот min-width: 0 используется для того чтобы дочерние элементы во flex контейнере, могли сжиматься при уменьшении ширины родительского элемента.
    Ответ написан
    1 комментарий
  • У e.target из KeyboardEvent нет метода classList.contains()?

    mizutsune
    @mizutsune
    Frontend Developer
    Вы используете квадратные скобки, вместо круглых.

    - console.log(e.target.parentElement.classList.contains["valide"]);
    + console.log(e.target.parentElement.classList.contains("valide"));


    - if (e.target.parentElement.classList.contains["valide"]);
    + if (e.target.parentElement.classList.contains("valide"));
    Ответ написан
  • Как убрать лишние линии у текста и под изображениями?

    mizutsune
    @mizutsune
    Frontend Developer
    Немного информации по поводу верстки

    1. Обычно элементам даются осмысленные имена классов, а не всякие a01, a02, a03. Да. есть исключения, когда можно использовать префиксы и суффиксы, в стиле: Datacard-DGX3-VS2, но тут хотя бы видно что в целом в имени класса используется дополнительная сущность, в виде Datacard, что упрощает понимание.

    2. Для создания адекватной структуры страницы, многие блоки объединяются в родительские блоки, группы или контейнеры или секции. Это позволяет выстроить иерархию и логически связать элементы в группы.

    3. При верстке стандартной страницы, обычно используются базовые теги HTML - header, main, nav, footer и другие, внутрь которых можно вложить остальные элементы страницы. Такой подход к верстке, имеет достаточно плюсов, однако в вашей верстке я этого не вижу. У вас просто винегрет.

    4. Не стоит использовать вендорные префиксы, там где это не нужно. Речь идёт об этом - display: -webkit-inline-box. Плюс минус, но значения некоторых свойств конечно можно подправить, например убрать проценты у марджинов. Свойство transition обычно устанавливается в статичном состоянии, а не при :hover эффекте.

    5. Тег body и так по дефолту блочный... Зачем вы задаёте ему display: block? А ещё непонятно зачем для ссылок и некоторых других элементов прописаны повторы стилей. Зачем дублировать, когда можно для набора одинаковых элементов - создать единый селектор с набором необходимых стилей?

    6. Ещё у вас закрывающие теги </html> и </head> поменялись местами. Забавно.

    7. Я думаю что тег <div> абсолютно не подходит для использования в качестве кнопки, ведь для кнопок имеется вполне подходящий тег </button>.


    Ну, а теперь отвечу на основной вопрос:

    Как убрать лишние линии у текста и под изображениями?


    Эти полосы являются обычным пробелом. Он обычно стоит между inline или inline-block и соседними элементами. Для того чтобы избавиться от этих полос, оберните элементы в родительский блок и установите для него свойство display со значением flex/grid.

    Конечно есть множество других способов избавиться от этих пробелов, но вряд ли их использование будет полезно или удобно, ведь есть нормальные пути решения проблемы.
    Ответ написан
    Комментировать
  • Как флексами разделить блоки 2 на 2?

    mizutsune
    @mizutsune
    Frontend Developer
    .flex {
       --gap: 20px;
       display: flex;
       flex-wrap: wrap;
       gap: var(--gap);
    }
    
    .item {
       width: calc(50% - var(--gap) / 2);
       height: 100px;
       background-color: red;
    }
    Ответ написан
    Комментировать
  • Как убрать закрытие вкладки аккордеона при нажатии на кнопку?

    mizutsune
    @mizutsune
    Frontend Developer
    Если немного подправить ваш скрипт, то можно сделать так:

    const accordions = document.querySelectorAll('.accordion');
    const accordionsButtons = document.querySelectorAll(".accordion__tittle")
    const accordionsDataboxes =  document.querySelectorAll(".accordion__content");
    
    accordions.forEach(n => {
         const currentButton = n.querySelector(".accordion__tittle");
         const currentDatabox = n.querySelector(".accordion__content");
    
         const toggleActiveElements = () => {
              accordionsButtons.forEach(v => {
                   if (v !== currentButton) {
                        v.classList.remove("open");
                   }
              });
    
              accordionsDataboxes.forEach(v => {
                   if (v !== currentDatabox) {
                        v.classList.remove("open");
                        v.style.setProperty("--height", "0px");
                   }
              });
    
              currentButton.classList.toggle("open");
              currentDatabox.classList.toggle("open");
    
              currentDatabox.classList.contains("open")
                   ? currentDatabox.style.setProperty("--height", `${currentDatabox.scrollHeight}px`)
                   : currentDatabox.style.setProperty("--height", "0px");
         };
    
         currentButton.addEventListener("click", toggleActiveElements);
    });


    И добавить строчку в CSS:

    .accordion__content.open {
        max-height: var(--height, 0);
      }
    Ответ написан
    1 комментарий
  • Возможно ли дать картинкам такую форму в css?

    mizutsune
    @mizutsune
    Frontend Developer
    Например с помощью CSS масок или Clip Path.
    Ответ написан
    Комментировать
  • Можно добавить внутреннюю валюту?

    mizutsune
    @mizutsune
    Frontend Developer
    В phpBB, увы, нет встроенной системы поинтов/репутации или внутренней валюты, а количество расширений можно пересчитать на пальцах одной руки. Поэтому если вам нужно расширение внутренней валюты, тогда будет проще и лучше написать его самостоятельно. Открываем документацию по созданию расширений, читаем и вперёд. Основу такого расширения написать не сложно, но скорее всего будет сложнее добавлять функционал + защиту от накрутки поинтов.

    Однако есть такое расширение Ultimate Points Extension, возможно подойдёт, хотя у него как и многих других расширений для phpBB имеются свои подводные камни, недостатки и отсутствие нужного функционала. Но, для старта думаю подойдёт.

    Ещё есть такое расширение phpBB Reputation System.
    Ответ написан
    Комментировать
  • Надо ли создавать отдельную базу данных для форума phpbb?

    mizutsune
    @mizutsune
    Frontend Developer
    Вообще в данном случае отдельная база данных для форума хорошее решение, потому что будет разделение: основной сайт и форум. Ну и в будущем при необходимости вам не придётся отделять данные основного сайта от форумных, если вдруг захотите разделить основной сайт и форум. Но в целом нужно смотреть по ситуации и по уровню возможностей.
    Ответ написан
    Комментировать
  • Как добавить класс в зависимости от ширины экрана?

    mizutsune
    @mizutsune
    Frontend Developer
    Вам не класс нужно переключать на элементе, а включать и выключать слайдер, при достижении определенного брейкпоинта. Всё это дело можно легко решить с помощью matchMedia.

    Вот небольшой пример:

    const slider = $(".slider").slick({
         centerMode: true,
         slidesToShow: 4
    });
    
    const breakpoint = window.matchMedia("(max-width: 992px)");
    
    const breakpointChecker = () => {
       if (breakpoint.matches) {
          slider.slick('init');
       } else {
          slider.slick('destroy');
       }
    };
    
    breakpoint.addEventListener("change", breakpointChecker);
    breakpointChecker();


    А вот для дополнительной стилизации контейнера, уже можно использовать медиа запросы в CSS.
    Ответ написан
    2 комментария
  • Как сделать такой выдвигающийся блок?

    mizutsune
    @mizutsune
    Frontend Developer
    Это самое обычное модальное окно, без центрирования по центру экрана и с оверлей элементом. Можно написать с нуля, или воспользоваться какой-нибудь библиотекой.



    Добавить нужных стилей и всё будет как нужно.
    Ответ написан
    Комментировать
  • Как копировать в буфер обмена строки по отдельности по клику?

    mizutsune
    @mizutsune
    Frontend Developer
    <button class="trigger" data-text="Hello">Скопировать</button>


    const button = document.querySelector(".trigger");
    const dataText = button.dataset.text.trim();
    
    button.addEventListener('click', e => {
    
      if(!dataText.length) return;
      
      navigator.clipboard.writeText(dataText)
        .then(() => console.log("Done!"))
        .catch(err => console.error(err))
    })


    Clipboard API
    Ответ написан
    Комментировать