Задать вопрос
  • Что не так с кодом js?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Это чё, в setInterval запихнули подключение обработчика keydown? Умно. Не нужен тут никакой setInterval.

    Сам обработчик keydown слишком сложно выглядит - зачем в четырёх разных местах делать один и тот же вызов функции? Сначала меняете координаты, а в самом конце - дёргаете перерисовку.

    Размер картинок - а если решите поменять? Или опечатаетесь где-нибудь? Сделайте константу.

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

    Как это всё может выглядеть:

    const canvas = document.querySelector('#canvas');
    const ctx = canvas.getContext('2d');
    
    const TILE_SIDE = 32;
    
    let pickX = 0;
    let pickY = 0;
    
    const ground = new Image();
    ground.src = 'Ground.png';
    const pick = new Image();
    pick.src = 'Pick.png';
    
    document.addEventListener('keydown', function(e) {
      switch (e.keyCode) {
        case 87: pickY -= TILE_SIDE; break;
        case 65: pickX -= TILE_SIDE; break;
        case 83: pickY += TILE_SIDE; break;
        case 68: pickX += TILE_SIDE; break;
    
        default: return;
      }
    
      draw();
    });
    
    function draw() {
      for (let x = 0; x < canvas.width; x += TILE_SIDE) {
        for (let y = 0; y < canvas.height; y += TILE_SIDE) {
          ctx.drawImage(ground, x, y);
        }
      }
    
      ctx.drawImage(pick, pickX, pickY);
    }
    
    draw();
    Ответ написан
    Комментировать
  • Какой смысл использования node.js и прочего для backend?

    sim3x
    @sim3x
    если все заказчики, в основном, просят натяжку на CMS, где нужно понимание php
    False

    на CMS, где нужно понимание php
    False

    на каком уровне нужно знать backend
    на уровне - я знаю как решить данную проблему за Х часов, я ее уже решал минимум два раза
    Ответ написан
    1 комментарий
  • Как сделать background c с градиентом по границам текста?

    sfi0zy
    @sfi0zy Куратор тега CSS
    Creative frontend developer
    Похоже, что единственный работающий вариант реализовать такой градиент на CSS - это играться со свойством mix-blend-mode и делать фолбек для старых браузеров. Что-то вроде этого:

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

    kawabanga
    @kawabanga
    А зачем вам .htaccess? правильно делает хостер, что запрещает вам с ним работать.

    Я бы на вашем месте проверял бы конфиг (config.php), если конфиг существует то запускаете в работу ваш сайт. А если нет - то запускаете процесс установки/настройки.
    Ответ написан
    Комментировать
  • Как зарабатывать 1000$ на фрилансе верстальщику?

    opium
    @opium
    Просто люблю качественно работать
    Берите заказы посложнее пять заказов по двести и уже 1000
    Ответ написан
    3 комментария
  • Как зарабатывать 1000$ на фрилансе верстальщику?

    Sanes
    @Sanes
    Найти покупателей на $1000. Фриланс это предпринимательская деятельность.
    Ответ написан
    Комментировать
  • Нагружает ли composer сайт на production?

    Zettabyte
    @Zettabyte
    Проф. восстановление данных ▪ Вопрос? См. профиль
    Вам правильно написали, что по-хорошему, с Композером надо работать на локальной машине.

    Но, если будете гонять его на боевой машине, обязательно учтите, что Composer использует совершенно непотребное количество оперативной памяти (и автор отвечает на вопросы об этом, по сути, издёвками).
    К примеру, для установки Drupal 8 или обновления одного установленного модуля вам едва-едва хватит гигабайта. Что-то более серьёзное может потребовать больше.

    Так что я бы закладывал потребление RAM примерно 1-1.5 ГБ в моменты, когда Композер работает. Нагрузка на процессор тоже будет не нулевой, но она всё-таки много более сносная.
    Ответ написан
    6 комментариев
  • Как реализовать display: block по событию onclick одному div и при этом всем раннее открытым из 36 штук - display: none на чистом js?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Разные классы не нужны, достаточно одного общего:

    .ranging {
      display: none;
    }
    
    .ranging.opened {
      display: block;
    }

    При клике смотрим индекс нажатой кнопки, обходим элементы с контентом, выставляем класс в зависимости от равенства текущего индекса индексу кнопки:

    const buttonSelector = '.selector';
    const contentSelector = '.ranging';
    const activeClass = 'opened';
    const toggleContent = (contents, index) =>
      contents.forEach((n, i) => n.classList.toggle(activeClass, i === index));
    
    
    // делегирование, назначаем обработчик клика один раз для всех кнопок
    // наверное, у них есть какой-то общий предок, тогда вместо документа
    // вешать обработчик следует на него:
    // document.querySelector('селектор_контейнера_с_кнопками').addEventListener(...
    document.addEventListener('click', e => {
      const button = e.target.closest(buttonSelector);
      if (button) {
        const buttons = document.querySelectorAll(buttonSelector);
        const index = Array.prototype.indexOf.call(buttons, button);
        toggleContent(document.querySelectorAll(contentSelector), index);
      }
    });
    
    // или, назначаем обработчик клика индивидуально каждой кнопке
    const onClick = function(e) {
      toggleContent(this, +e.currentTarget.dataset.index);
    }.bind(document.querySelectorAll(contentSelector));
    
    document.querySelectorAll(buttonSelector).forEach((n, i) => {
      n.dataset.index = i;
      n.addEventListener('click', onClick);
    });
    Ответ написан
    4 комментария
  • Как сделать фильтрацию по нескольким значениям в VueJS?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Сложно это всё. Четыре селекта - очень похожие, четыре вычисляемых свойства - очень похожие. Многовато копипасты. Надо упростить.

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

    filters: [
      { name: 'calculator.brand_filter', getter: obj => obj.brand.name, value: '' },
      { name: 'calculator.company_filter', getter: obj => obj.company.name, value: '' },
      { name: 'calculator.country_filter', getter: obj => obj.brand.country, value: '' },
      { name: 'calculator.side_filter', getter: obj => obj.sides, value: '' },
    ],

    Затем сделаем собственно фильтрацию, пропустим данные через массив фильтров (если значение фильтра выставлено - производится фильтрация, нет - оставляем данные как есть):

    computed: {
      filteredProfiles() {
        return this.filters.reduce((profiles, { value, getter }) => {
          return value
            ? profiles.filter(n => getter(n) === value)
            : profiles;
        }, this.profiles);
      },

    Далее, надо дать пользователю возможность задавать значения фильтров. Сделаем компонент фильтра:

    Vue.component('filter-select', {
      props: [ 'name', 'options', 'value' ],
      template: `
    <div>
      <p>{{ name }}<p>
      <select :value="value" @change="$emit('input', $event.target.value)">
        <option value="">-</option>
        <option v-for="n in options">{{ n }}</option>
      </select>
    </div>`
    });

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

    computed: {
      filterOptions() {
        return this.filters.map(n => [...new Set(this.profiles.map(n.getter))]);
      },

    Наконец, создадим сами фильтры:

    <filter-select
      v-for="(n, i) in filters"
      v-model="n.value"
      :options="filterOptions[i]"
      :name="trans(n.name)"
    ></filter-select>

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

    methods: {
      resetFilters() {
        this.filters.forEach(n => n.value = '');
      },

    <button @click="resetFilters">{{ trans('calculator.reset_filter') }}</button>

    Демо можно посмотреть здесь (да, тут меньше фильтров, чем у вас - ну так вы свои данные не показали, а у меня воображения на большее не хватило).
    Ответ написан
    1 комментарий
  • Как, используя jquery, выполнить скрипт только для 1 карточки?

    @DanKud
    Во-первых id это уникальный идентификатор. Делать несколько элементов с одним id это в корне неправильно + через JQuery по id вы получите в ответ только один элемент. Используйте классы:
    <div class="aboutfilm">
        .....
    </div>
    
    <script>
    $('.aboutfilm').each(function() {
        $(this).on('click', () => {
            $(this).parent().find('.test').addClass('card-text-change');
            $(this).parent().find('.card-text').css('opacity', '1');
            $(this).css('display','none');
        });
    });
    </script>
    Ответ написан
    4 комментария
  • Есть ли аналог @media запросов только для мобильных устройств?

    @Genexys
    фронтенделье
    Вы не то смотрите. Почитайте спеку media какие они значения принемают
    Ответ написан
    Комментировать
  • Взлом или развод?

    flapflapjack
    @flapflapjack
    на треть я прав
    Может ли злоумышленник, получив данные о списках таблиц так же получить и содержимое этих таблиц?


    В зависимости от степени экранирования символов при фильтре какого-то из параметров.

    По сути, скорее всего инъекция была сделана именно на вашем сайте, следовательно запрос выполнялся от имени вашего пользователя, у которого есть все права на БД - следовательно может и удалять и читать любые записи.

    Нужно как-то отследить место SQL-инъекции.

    Я в этом не спец, но например можно посмотреть лог mysql на наличие строки SHOW DATABASES или SHOW TABLES, а так же по поиску слова UNION, коим часто пользуются при создании инъекций. Найдя в логах время исполнения данного запроса можно глянуть в access.log у апача запрошенный адрес сайта, который был запрошен в то же время, что и инъекция в SQL.

    Имея точное расположение скрипта можно поставить вставки функции для логирования $_SERVER['REQUEST_URI'] и определить что за запрос был сделан, и от этого плясать.
    Ответ написан
    1 комментарий
  • Как трансформировать шаблон для разных CMS???

    Robur
    @Robur
    Знаю больше чем это необходимо
    Программ нет, но есть сервисы:
    upwork.com
    freelansim.ru

    это основные, там можно конвертировать 100%, за некоторую плату конечно.
    Если не подходят по каким-то причинам, есть еще множество других подобных сервисов.
    Ответ написан
    Комментировать
  • Как присвоить значение iframe к input?

    Stalker_RED
    @Stalker_RED
    iframe.contentWindow.body.innerHTML
    https://developer.mozilla.org/en-US/docs/Web/API/H...

    Если iframe с другого домена, то нужно будет настроить CORS.
    Ответ написан
    2 комментария
  • Как вы обновляете vue проекты на проде?

    k12th
    @k12th
    console.log(`You're pulling my leg, right?`);
    CI/CD (Continuous Integration/Continuous Delivery) сервер ответ на ваши проблемы. Например, bitbucket pipelines, circle ci, gitlab pipelines, jenkins и т.д. Работает так:
    • сервер отслеживает пуши в определенные ветки, например, в master.
    • если в master пришли коммиты, то запускается определенный скрипт, который вызывает сборку (обычно еще перед этим запускаются тесты, если есть).
    • если сборка прошла успешно, то результат этой сборки кладется в отдельную папку -- это называется build artifact
    • этот build artifact тем или иным образом загружается на хостинг -- у всяких там AWS/Azure и т.п. облак обычно есть API для этого, можно передавать файлы через scp или sftp.

    Если вся инфраструктура локальная, то и CI/CD сервер обычно ставят локально, например, Jenkins или TeamCity. Но без выделенного админа/девопса проще в облаках настроить, наверное.

    P.S. это, конечно, годится не только для проектов на vue, а вообще для любого веба, включая бэкенд.
    Ответ написан
    Комментировать
  • Как и где хранить техническую документацию?

    DDDsa
    @DDDsa
    Хороший подход — docs as code.
    Мы ведём все документы в git-репозиториях, в формате Markdown. Исходники обёрнуты в Foliant, который может в любой момент из md собрать PDF, docx, сайт, гугл-док или что угодно. Например, многие проекты с документацией автоматически собираются в базу знаний при помощи GitLab-CI. При каждом пуше изменений в репозиторий сайт пересобирается и мы уверены, что там всегда свежие доки. А как только менеджер просит готовый документ — можно тут же собрать PDF, с коропоративным лого и т д.

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

    kawabanga
    @kawabanga
    Это называется слайдер хД
    Ответ написан
    Комментировать
  • Может ли Visual Studio Code неверно интерпретировать код?

    Vlad_IT
    @Vlad_IT Куратор тега CSS
    Front-end разработчик
    Проблема не в VS Code, а в среде выполнения, и в вашей переменной name. т.к. вы выполняете свой код в глобальном контексте (да-да, в цикле переменные определяются не в своей области видимости), то пытаетесь переопределить переменную window.name, которая является не переопределяемой, и равна строке, от чего у вас в коде получается бардак. Измените название переменной, или используйте let вместо var
    Ответ написан
    3 комментария
  • Подтверждение лицензионности ПО в организации?

    @CHolfield
    Согласно ГК РФ, доказательством легитимности используемого ПО являются первичные бухгалтерские документы - товарно-транспортная накоадная и счет-фактура. Все остальные требования насчет наклеек, каких-либо ключей, кодов и активаций - незаконны, отсутствие коробок и прочей шняги ничего не значит, если закупка прошла через бухгалтерию. Если не прошла - никакие коробки не помогут.
    Все остальное что тут пишут - ересь.
    Ответ написан
    3 комментария