Ответы пользователя по тегу Фронтенд
  • Как двигать блок по квадрату?

    0xD34F
    @0xD34F
    Как сделать, чтобы третье условие работало?

    Усилить первое условие так, чтобы оно не становилось истинным после того, как перестаёт быть истинным второе.

    Только вам это мало чем поможет - кривое условие не только первое, но и третье.
    А всего их должно быть четыре.

    const rectLeftTop = [ 50, 50 ];
    const rectSize = 450;
    const step = 15;
    let [ x, y ] = rectLeftTop;
    
    setInterval(() => {
      if (rectLeftTop[1] <= y && x === rectLeftTop[0]) {
        y = Math.min(y + step, rectLeftTop[1] + rectSize);
      }
    
      if (rectLeftTop[0] <= x && y === rectLeftTop[1] + rectSize) {
        x = Math.min(x + step, rectLeftTop[0] + rectSize);
      }
    
      if (rectLeftTop[1] < y && x === rectLeftTop[0] + rectSize) {
        y = Math.max(y - step, rectLeftTop[1]);
      }
    
      if (rectLeftTop[0] < x && y === rectLeftTop[1]) {
        x = Math.max(x - step, rectLeftTop[0]);
      }
    
      block.style.left = `${x}px`;
      block.style.top = `${y}px`;
    }, rectSize / step);

    https://jsfiddle.net/efzcpda7/

    Хотя есть вариант обойтись одним.

    const directions = [
      [  0, -1 ],
      [ -1,  0 ],
      [  0,  1 ],
      [  1,  0 ],
    ];
    let iDirection = 0;
    
    const coords = [ 50, 50 ];
    const step = 15;
    const rectSize = 450;
    const rect = [ [...coords], coords.map(n => n + rectSize) ];
    
    (function move() {
      const d = directions[iDirection].map(n => n * step);
      coords.forEach((n, i, a) => a[i] = Math.max(rect[0][i], Math.min(rect[1][i], n + d[i])));
    
      if (coords.every((n, i) => rect.some(m => m[i] === n))) {
        iDirection = (iDirection + 1) % directions.length;
      }
    
      block.style.left = `${coords[0]}px`;
      block.style.top = `${coords[1]}px`;
    
      requestAnimationFrame(move);
    })();

    https://jsfiddle.net/efzcpda7/1/

    Но вообще - никакие условия не нужны.

    Можно задать блоку transition, определить массив конечных координат и устанавливать следующие после достижения предыдущих (событие transitionend):

    .block {
      transition: all 750ms linear;
    }

    const positions = [
      [  50,  50 ],
      [  50, 500 ],
      [ 500, 500 ],
      [ 500,  50 ],
    ];
    let iPosition = -1;
    
    move();
    block.addEventListener('transitionend', move);
    setTimeout(move, 0);
    
    function move() {
      iPosition = (iPosition + 1) % positions.length;
      const [ x, y ] = positions[iPosition].map(n => `${n}px`);
      block.style.left = x;
      block.style.top = y;
    }

    https://jsfiddle.net/efzcpda7/2/

    Да и в целом, JS не нужен - перемещения блока можно описать в CSS.

    .block {
      animation: move 3s infinite linear;
    }
    
    @keyframes move {
      0%, 100% {
        left: 50px;
        top: 50px;
      }
      25% {
        left: 50px;
        top: 500px;
      }
      50% {
        left: 500px;
        top: 500px;
      }
      75% {
        left: 500px;
        top: 50px;
      }
    }

    https://jsfiddle.net/efzcpda7/3/

    Если подумать, то и стили тоже лишние - с задачей отлично справляется SVG.

    <svg viewBox="0 0 550 550" xmlns="http://www.w3.org/2000/svg" width="550" height="550">
      <rect width="50" height="50" fill="red">
        <animateMotion
          dur="3s"
          repeatCount="indefinite"
          path="M50,50 L50,500 L500,500 L500,50 L50,50 z"
        />
      </rect>
    </svg>

    https://jsfiddle.net/efzcpda7/4/
    Ответ написан
    Комментировать
  • Как построить лепестковую диаграмму в браузере?

    0xD34F
    @0xD34F
    Ответ написан
    Комментировать
  • Как организовать показ изображений различных категорий при клике на кнопки?

    0xD34F
    @0xD34F
    Добавляете изображениям классы, которые будут обозначать категории, к которым изображения относятся. Кнопкам добавляете атрибут, значение которого будет совпадать с именем одного из классов (кроме кнопки, которая должна показать всё - там будет класс, общий для всех изображений). При клике на кнопку получаете значение атрибута и обходите изображения - у кого соответствующий класс есть, тех показываете, иначе прячете. Например.

    Или, можно переключаться между изображениями без js. Опять же, добавляете изображениям классы, обозначающие категории. Делаете скрытые радиокнопки, id которых соответствуют категориям. После них располагаете связанные с ними лейблы (будут выступать в роли кнопок) и изображения. С помощью :checked, subsequent-sibling combinator и :not стилизуете лейблы и прячете изображения, у которых отсутствует класс выбранной категории. Вот как-то так.
    Ответ написан
    Комментировать
  • Как реализовать проверку корректности заполнения формы?

    0xD34F
    @0xD34F
    Элементам формы добавляем data-атрибут, указывающий, значения каких типов они содержат, и, соответственно, как надо проверять их корректность:

    <div class="players">
      <div class="player">
        <input placeholder="*Введите псевдоним" data-type="name">
        <br>
        <input placeholder="*Введите рейтинг" data-type="rating">
      </div>
      <div class="player">
        <input placeholder="*Введите псевдоним" data-type="name">
        <br>
        <input placeholder="*Введите рейтинг" data-type="rating">
      </div>
    </div>
    <h1 class="message hidden">HELLO, WORLD!!</h1>

    Какие вообще есть способы проверки корректности значений - объект, ключами являются имена типов данных, значениями функции, принимающие значения из элементов формы и возвращающие true или false:

    const validations = {
      name: val => /\D/.test(val),
      rating: val => /^\d+$/.test(val),
    };

    Собственно проверка - на форму вешается обработчик события input, внутри которого перебираются элементы формы, из них извлекается имя типа данных, по имени типа данных из объекта с валидаторами извлекается функция проверки, ей передаётся значение элемента, введённое пользователем. Чтобы форма в целом была признана корректно заполненной, каждая из проверок должна оказаться успешной, в зависимости от полученного результата показываем или прячем дополнительный контент. Ну и ещё тот элемент, который пользователь только что редактировал, обрабатывается в особом порядке - в зависимости от результата его проверки у него добавляется или снимается класс, предназначенный для выделения некорректно заполненного элемента:

    document.querySelector('.players').addEventListener('input', function(e) {
      const error = Array.from(this.querySelectorAll('[data-type]'), n => {
        const error = !validations[n.dataset.type](n.value);
    
        if (n === e.target) {
          n.classList.toggle('error', error);
        }
    
        return error;
      }).some(Boolean);
    
      document.querySelector('.message').classList.toggle('hidden', error);
    });

    Остаётся определить стили - для выделения криво заполненных элементов формы и управления видимостью дополнительного контента, который должен стать доступен после корректного заполнения всей формы:

    .error {
      color: white;
      background: red;
    }
    
    .hidden {
      display: none;
    }
    Ответ написан
    Комментировать
  • Как сделать "вертушку" загрузки?

    0xD34F
    @0xD34F
    Можно сделать через CSS.

    <div class="spinner"><div>

    .spinner {
      color: black;
      font-size: 5rem;
    }
    .spinner::before {
      display: inline-block;
      text-align: center;
      font-family: monospace;
      width: 5rem;
      content: "";
      animation: spinner .8s infinite steps(4);
    }
    @keyframes spinner {
      0%, 100% { content: "\2014"; }
           25% { content:    "\\"; }
           50% { content:     "|"; }
           75% { content:     "/"; }
    }


    Или через JS.

    <div class="spinner"><div>

    .spinner {
      color: black;
      font-size: 5rem;
      font-family: monospace;
    }

    const block = document.querySelector('.spinner');
    const text = [ '\u2014', '\\', '|', '/' ];
    let index = -1;
    
    setInterval(() => {
      index = (index + 1) % text.length;
      block.textContent = text[index];
    }, 200);


    SVG - тоже вариант.
    <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
      <g font-size="60" font-family="monospace" fill="black" visibility="hidden">
        <text x="30" y="60">
          —
          <animate attributeName="visibility" from="hidden" to="visible" begin="0.2s; hide4.begin" dur="0.2s" id="show1" />
          <animate attributeName="visibility" from="visible" to="hidden" begin="show1.begin + 0.2s" dur="0.2s" id="hide1" />
        </text>
        <text x="30" y="60">
          \
          <animate attributeName="visibility" from="hidden" to="visible" begin="hide1.begin" dur="0.2s" id="show2" />
          <animate attributeName="visibility" from="visible" to="hidden" begin="hide1.begin + 0.2s" dur="0.2s" id="hide2" />
        </text>
        <text x="30" y="60">
          |
          <animate attributeName="visibility" from="hidden" to="visible" begin="hide2.begin" dur="0.2s"  id="show3" />
          <animate attributeName="visibility" from="visible" to="hidden" begin="hide2.begin + 0.2s" dur="0.2s" id="hide3" />
        </text>
        <text x="30" y="60">
          /
          <animate attributeName="visibility" from="hidden" to="visible" begin="hide3.begin" dur="0.2s"  id="show4" />
          <animate attributeName="visibility" from="visible" to="hidden" begin="hide3.begin + 0.2s" dur="0.2s" id="hide4" />
        </text>
      </g>
    </svg>
    Ответ написан
    Комментировать
  • Как отрендерить много записей?

    0xD34F
    @0xD34F
    есть 30 000 строк в массиве, нужно показать их в DOM

    Не нужно. Кому показывать-то? - пользователь столько информации не воспримет за один раз.
    Есть такое слово - "пагинация". Погуглите, что это.
    Ответ написан
    Комментировать
  • Какой есть красивый график для сайта?

    0xD34F
    @0xD34F
    Ответ написан
    Комментировать
  • Как сделать так, чтобы при нажатии на миниатюру изображения, открывалась картинка в полном размере?

    0xD34F
    @0xD34F
    В js не разбираюсь

    И не надо.

    Так что берите готовые решения. Например. Или.
    Ответ написан
    Комментировать
  • Как сделать так, чтобы блок переместился при нажатии на ссылку?

    0xD34F
    @0xD34F
    Определяем класс, который будет сдвигать .wrap:

    .wrap-active {
      transform: translateY(-100%);
    }

    Переключаем этот класс при кликах по ссылкам:

    $('.wrap').on('click', 'a', function(e) {
      e.preventDefault();
      $(e.delegateTarget).toggleClass('wrap-active');
    });

    https://jsfiddle.net/uvoqfn82/

    Или, без js.

    Перед .wrap добавляем скрытый чекбокс:

    <input type="checkbox" id="toggle" hidden>

    Ссылки заменяем на label'ы, переключающие чекбокс:

    <a href="#">Day</a> ---> <label for="toggle">Day</label>

    <a href="#">Night</a> ---> <label for="toggle">Night</label>

    Сдвигаем .wrap не при наличии дополнительного класса, а если чекбокс перед ним выставлен:

    .wrap-active { ---> #toggle:checked + .wrap {

    https://jsfiddle.net/uvoqfn82/1/
    Ответ написан
    Комментировать
  • Как быстро отрисовывать таблицу с 10.000-ми строк?

    0xD34F
    @0xD34F
    Очевидно, что пользователь не сможет одномоментно воспринять 10000 строк данных. То есть, сама задача - идиотская, её решать НЕ НАДО. Делайте разбиение по страницам, 30-50-100 строк будут отображаться с приемлемой скоростью.
    Ответ написан
    Комментировать