Задать вопрос
  • Скролл с остановкой для анимации на нативном JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Как вариант, прокручивать невидимый пустой высоченный div.
    Контент держать в другом div, position: fixed;, положение его менять программно по событию "scroll".

    Когда скролл доходит до высоты, где должна быть анимация, движение контента приостанавливается.
    Когда вышли из зоны анимации, движение продолжается, с поправкой на пропущенную высоту:
    document.addEventListener('scroll', () => {
      let offset = window.scrollY;
      const start = 685; // начало стоп-зоны в px
      const stop = 1000; // конеч стоп-зоны
    	if (offset >= start && offset < stop) {
        offset = start; // стоим на месте
      } else if (offset >= stop) {
        offset -= (stop - start); // продолжаем движение
      }
      content.style.top = `-${offset}px`; // позиционируем контент
    });


    Ответ написан
    3 комментария
  • Вопрос с собеседования. Вывести сумму транзакций за период, используя один цикл?

    WblCHA
    @WblCHA
    Раз никто так и не смог ничего толком предложить, то пришлось самому писать. Писал тяп-ляп, так что есть куда улучшать.

    Мой вариант
    {
      const transactions = [
        {
          date: '25.01.2015',
          price: '28',
        },
        {
          date: '22.02.2015',
          price: '23',
        },
        {
          date: '24.02.2015',
          price: '12',
        },
        {
          date: '02.03.2015',
          price: '55',
        },
        {
          date: '10.03.2015',
          price: '56',
        },
        {
          date: '15.03.2015',
          price: '8',
        },
        {
          date: '24.03.2015',
          price: '19',
        },
        {
          date: '26.03.2015',
          price: '12',
        },
        {
          date: '27.03.2015',
          price: '11',
        },
      ];
    
      const firstMonthDate = 25;
      const firstTransaction = transactions[0].date.split('.').map((n) => +n);
    
      const increaseMonth = (date) => {
        date.month = ((date.month + 12) % 12) + 1;
    
        if (date.month === 1) {
          date.year++;
        }
      };
    
      const startDate =
        firstTransaction[0] < firstMonthDate
          ? {
              day: firstMonthDate,
              month: ((firstTransaction[1] + 10) % 12) + 1,
              year: firstTransaction[2] - (firstTransaction[1] === 1 ? 1 : 0),
            }
          : {
              day: firstMonthDate,
              month: firstTransaction[1],
              year: firstTransaction[2],
            };
      const endDate = { ...startDate };
      increaseMonth(endDate);
      endDate.day--;
    
      const sumByMonths = [
        {
          from: { ...startDate },
          to: { ...endDate },
          sum: 0,
        },
      ];
      let sumByMonthIndex = 0;
    
      transactions.forEach((transaction) => {
        const [day, month] = transaction.date.split('.').map((n) => +n);
    
        if (
          !(month === startDate.month && day >= startDate.day) &&
          !(month === endDate.month && day <= endDate.day)
        ) {
          increaseMonth(startDate);
          increaseMonth(endDate);
    
          sumByMonths.push({
            from: { ...startDate },
            to: { ...endDate },
            sum: 0,
          });
          sumByMonthIndex++;
        }
    
        sumByMonths[sumByMonthIndex].sum += +transaction.price;
      });
    
      console.log('>>> sumByMonths', sumByMonths);
    }


    Надим Закиров,
    Вариант, основанный на предложении @zkrvndm
    {
      const transactions = [
        {
          date: '25.01.2015',
          price: '28',
        },
        {
          date: '22.02.2015',
          price: '23',
        },
        {
          date: '24.02.2015',
          price: '12',
        },
        {
          date: '02.03.2015',
          price: '55',
        },
        {
          date: '10.03.2015',
          price: '56',
        },
        {
          date: '15.03.2015',
          price: '8',
        },
        {
          date: '24.03.2015',
          price: '19',
        },
        {
          date: '26.03.2015',
          price: '12',
        },
        {
          date: '27.03.2015',
          price: '11',
        },
      ];
    
      const firstMonthDate = 25;
      const firstTransaction = transactions[0].date.split('.').map((n) => +n);
    
      const increaseMonth = (date) => {
        date.month = ((date.month + 12) % 12) + 1;
    
        if (date.month === 1) {
          date.year++;
        }
      };
    
      const dateToString = (date) => `${date.year}-${date.month}-${date.day}`;
    
      const startDate =
        firstTransaction[0] < firstMonthDate
          ? {
              day: firstMonthDate,
              month: ((firstTransaction[1] + 10) % 12) + 1,
              year: firstTransaction[2] - (firstTransaction[1] === 1 ? 1 : 0),
              unix: 0,
            }
          : {
              day: firstMonthDate,
              month: firstTransaction[1],
              year: firstTransaction[2],
              unix: 0,
            };
      startDate.unix = +new Date(dateToString(startDate));
    
      const endDate = { ...startDate };
      increaseMonth(endDate);
      endDate.unix = +new Date(dateToString(endDate)) - 1;
    
      const sumByMonths = [
        {
          from: {
            day: startDate.day,
            month: startDate.month,
            year: startDate.year,
          },
          to: { day: endDate.day - 1, month: endDate.month, year: endDate.year },
          sum: 0,
        },
      ];
      let sumByMonthIndex = 0;
    
      transactions.forEach((transaction) => {
        const date = +new Date(transaction.date.split('.').reverse().join('-'));
    
        if (!(date >= startDate.unix && date <= endDate.unix)) {
          increaseMonth(startDate);
          startDate.unix = +new Date(dateToString(startDate));
          increaseMonth(endDate);
          endDate.unix = +new Date(dateToString(endDate)) - 1;
    
          sumByMonths.push({
            from: {
              day: startDate.day,
              month: startDate.month,
              year: startDate.year,
            },
            to: { day: endDate.day - 1, month: endDate.month, year: endDate.year },
            sum: 0,
          });
          sumByMonthIndex++;
        }
    
        sumByMonths[sumByMonthIndex].sum += +transaction.price;
      });
    
      console.log('>>> sumByMonths', sumByMonths);
    }


    Лично мне мой вариант для конкретно этого таска симпатичнее, как минимум нет постоянных преобразований дат.
    Ответ написан
    4 комментария
  • Вопрос с собеседования. Вывести сумму транзакций за период, используя один цикл?

    @mexvod
    const filteredArray = transactions.filter((item) => {
            const dataTokens = item.date.split('.');
            const date = new Date(+dataTokens[2], +dataTokens[1] - 1, +dataTokens[0]);
            return date.getDate() >= 24 && date.getDate() <= 25;
    });
    console.log(filteredArray);

    Остальное, я думаю, уже поймете как доделать =)
    советую почитать про https://learn.javascript.ru/array-methods

    Второй вариант, максимально упрощенный, сумма по месяцам, конкретным:

    let currentMonth = 0;
        let isFirstRun = true;
        let bufferSumInMonth = 0;
        const pricesArray = [];
    
        for (let i = 0; i < transactions.length; i++) {
            const currentItem = transactions[i];
            const dataTokens = currentItem.date.split('.');
            const date = new Date(+dataTokens[2], +dataTokens[1] - 1, +dataTokens[0]);
            if (isFirstRun) { currentMonth = date.getMonth(); isFirstRun = false; }
            if (currentMonth === date.getMonth() && (date.getDate() >= 24 && date.getDate() <= 25)) {
                bufferSumInMonth += parseInt(currentItem.price, 10);
            } else if (currentMonth !== date.getMonth() || i === transactions.length - 1) {
                console.log(bufferSumInMonth);
                pricesArray.push({ sum: bufferSumInMonth, month: date.getMonth() });
                bufferSumInMonth = 0;
            }
            currentMonth = date.getMonth();
        }
    
        console.log(pricesArray);
    Ответ написан
    5 комментариев
  • Как это решается?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    С фигурной скобкой задана функция x(z), по разному определённая на разных интервалах z.
    Константа c и функция φ(x) должны быть где-то заданы, чтобы можно было посчитать функцию y(x).
    Ответ написан
    4 комментария
  • "localstorage" или cookie?

    Apathetic
    @Apathetic
    Frontend
    На самом деле всё просто. Куки - для сервера, локалсторадж - для клиента. Если информация, которую вы собираетесь хранить, нужна только на клиенте - нет никакого смысла в том, чтобы гонять куки туда-сюда при каждом запросе к серверу. Если какая-то информация нужна постоянно серверу - используйте куки.
    Кроме того, а куки 4кб выделяется, на localStorage - 5 мб.
    Подводных камней нет никаких, если нет необходимости поддерживать старые ие - используйте смело. caniuse.com/#search=localstorage

    Что касается отключения: пользователь может превентивно запретить использование localStorage. На практике с таким не сталкивался, думаю, что целенаправленно этим занимаются еще реже, чем отключением cookies.
    Ответ написан
    5 комментариев
  • "localstorage" или cookie?

    @triton
    К уже написанному выше дополню:

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

    Еще учтите, что в safari есть специальный режим при котором любая попытка записать что-либо в localStorage будет приводить к скриптовой ошибке. Этим режимом не часто но пользуются, так что лучше добавить обработку этой ошибки.

    А так, пользуйтесь тем, что лучше подходит.
    Ответ написан
    Комментировать
  • Куда деваются 17px в chrome в ширине body?

    JRK_DV
    @JRK_DV
    Рецепты https://codepen.io/jrkdv/full/LKLXdq
    попробуйте задействовать overflow: overlay для html или body это заставит скролл быть поверх страницы (не занимать место), работает не во всех браузерах.

    Раньше решал эту проблему выставляя body width: 100vw; Но при таком подходе если высота страницы больше чем высота окна - появляется горизонтальный скролл в хроме, так и не понял откуда он появляется.

    100vw = 100% размер окна не учитывая размер скролла, вот и получается, что скролл не вмещается в размеры окна, поэтому появляется горизонтальная прокрутка.

    Ещё вы можете узнать размер скролла с помощью calc(100vw - 100%)
    Пригодиться, если отнимать или суммировать с другими значениями, чтобы вычесть размер скролла когда он есть и отнимает место на странице
    Ответ написан
    1 комментарий
  • Как добавлять класс при скролле?

    ZloDeeV
    @ZloDeeV
    Верстаю в своё удовольствие
    Чувак в комментарии под постом прав. toggle меняет класс, тут нужен addClass вместо него
    Ответ написан
    1 комментарий
  • Как добавлять класс при скролле?

    Можно еще так указать.
    $(window).scroll(function(){
        $('.main-nav-wrap').toggleClass('header-has-background', $(this).scrollTop() > 0);
    });
    Ответ написан
    2 комментария
  • Не работает Gulp, выдает ошибку?

    potapchino
    @potapchino
    var gulp = require('gulp');
    var browserSync = require('browser-sync').create();
    var sass = require('gulp-sass');
    
    gulp.task('sass', function(done) {
        gulp.src("scr/scss/*.scss")
            .pipe(sass())
            .pipe(gulp.dest("scr/css"))
            .pipe(browserSync.stream());
    
    
        done();
    });
    
    gulp.task('serve', function(done) {
    
        browserSync.init({
            server: "src/"
        });
    
        gulp.watch("scr/sass/*.sass", gulp.series('sass'));
        gulp.watch("scr/*.html").on('change', () => {
          browserSync.reload();
          done();
        });
      
    
        done();
    });
    
    gulp.task('default', gulp.series('sass', 'serve'));
    Ответ написан
    5 комментариев