Ответы пользователя по тегу JavaScript
  • Как сделать тайм-аут для функции jQuery?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Примерно так:
    $('.class').hover(
      function() {
        var $el = $(this);
        $el.addClass('active');
        setTimeout(function() {
          $el.removeClass('active')
        }, 500);
      }
    );

    fiddle

    jQuery.delay() здесь не подойдёт, т.к. он предназначен для анимаций вроде fade(), а с мгновенными методами не работает.
    Ответ написан
    4 комментария
  • Как показать отсчет таймера одинаковым для всех?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Нужно, чтобы клиент максимально точно «знал», сколько сейчас времени на сервере. Для этого можно несколько раз послать запрос на сервер, и предположить, что время ответа сервера лежит точно посередине между отправкой запроса и получением ответа. Примерно так работает NTP – протокол сетевого времени.

    Второе предположение, что ход собственных часов точен: 1 секунда на клиенте и на сервере точно равны.

    На сервере разместить простейший скрипт, который возвращает время с миллисекундами до События:
    // getTimeTill.php
    $deadline = strtotime("2017-07-01 03:00:00");
    echo round( 1000 * $deadline - 1000 * microtime(true)); // в миллисекундах

    На клиенте в JS надо засечь время, выполнить ajax запрос, получить ответ, и считать, что полученное число микросекунд оставалось до события половину разницы назад:
    var start = (new Date).getTime();
    $.get("getTimeTill.php", function( ms ){
      var bias = Math.round(((new Date).getTime() - start) / 2);
      var remains = ms + bias; // сколько остаётся микросекунд до события на данный момент
      var deadline = (new Date).getTime() + remains; // локальное время События
      // можно запускать таймер, который раз в 200 ms будет обновлять время до События
      var el = document.getElementById("timer");
      window.setInterval( function(){
        var remains = Math.floor((deadline - (new Date).getTime())/1000);
        var H = Math.floor( remains / 3600);
        remains -= 3600 * H;
        H = ( '0' + H ).substr(-2);
        var M = Math.floor( remains / 60);
        remains -= 60 * M;
        M = ( '0' + M ).substr(-2);
        var S = ( '0' + remains ).substr(-2);
        timer.innerText = "" + H + ":" + M + ":" + S;
      }, 200);
    });

    Такие запросы можно выполнять неоднократно, каждый раз уточняя таймер отсчёта на клиенте.
    Ответ написан
    1 комментарий
  • Хватит ли firebase для такого сайта?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сделайте и с firebase и backend собственный залепите, прогоните оба варианта нагрузочным тестированием а результаты опубликуйте на Хабре. С нетерпением буду ждать.
    Ответ написан
    Комментировать
  • Почему "#" + text.innerHTML != "#php"?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Потому, что внутренний текстовый узел содержит пробелы
    Ответ написан
    Комментировать
  • Как в Javascript/jQuery получить число с двумя нулями после точки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    "10.50 EUR" переделать в "10.50":
    var eur = "10.50 EUR";
    var price = parseFloat( s.substr( 0, s.length - 4)).toFixed(2); // "10.50"

    Умножить на число:
    var q = "55"; // jQuery возвращает строку
    var total = parseFloat( price) * parseInt(q);
    total = total.toFixed(2); // строка, точно два знака после запятой


    Текст перевести в число – parseFloat() или parseInt().
    Число перевести в текст с определённым числом цифр после запятой – .toFixed()
    Ответ написан
    Комментировать
  • Как узнать место в массиве выбранного элемента?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Без jQuery:
    var i, collection = document.getElementsByClassName('hello');
    for( i = 0; i < collection.length; i++) {
      collection[i].addEventListener('click', onClick);
    }
    
    function onClick() {
      var i, index = -1;
    	for(var i=0; i < collection.length; i++) {
    		if( this === collection[i]) {
    			index = i;
    			break;
    		}
    	}
    	if( !!~index) alert(index);
    }


    fiddle
    Ответ написан
    8 комментариев
  • Сокращенная запись условного оператора if, нельзя использовать без else?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Условный тернарный оператор в JavaScript обязательно требует все три операнда.

    В отличие от, например, PHP, где можно опустить средний операнд: $uslovie ?: $esli_false вернёт само $uslovie, если то соответствует true.

    В вашем случае, когда интересует только положительный исход условия, стоит использовать ещё более краткую форму, как и посоветовал Антон:
    condition && do_it();
    
    var test = true;
    test && console.log("it was true!");
    // или назначение
    var Boo = test && "если тру"; // иначе Boo === test (что он там возвращает, 0, NaN, false?)
    Ответ написан
    Комментировать
  • Как вывести день недели на JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Метод объекта Date getDay() возвращает день недели. 0 – воскресенье, 1 – понедельник, и т.д.
    Ответ написан
    Комментировать
  • Как понять циклы?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Неплохое описание цикла for на Mozilla Developers Network (на русском).

    Попробую своими словами. Внутри for( ... ) находится три выражения:
    1. начальное состояние
    2. проверяемое условие
    3. действие на каждом цикле

    Для сравнения, в цикле while() из этого зоопарка присутствует только условие.

    Простой пример:
    for( i = 0; i < 2; i = i + 1) {
      console.log( i ); // выводит значение i в консоль
    }

    Один раз в начале выполняется первая часть, «начальное состояние» i = 0.
    Проверяется условие i < 2.
    Всё в порядке? – «ныряем» внутрь. Выполняется console.log() и выводится 0.

    Теперь выполняется третье выражение: i = i + 1.
    Снова проверяется условие i < 2 и если всё ок, снова ныряем.
    Выводится 1.

    Опять выполняется третье выражение i = i + 1, но условие уже не проходит проверку, т.к. i стало равно 2.
    Всё, цикл закончен.

    Такой же цикл с while() выглядел бы так:
    i = 0;
    while( i < 2 ) {
      console.log( i );
      i = i + 1;
    }

    Т.е. for() это просто более компактная запись довольно типичного цикла.
    Ответ написан
    1 комментарий
  • Как сделать автоматическую смену даты js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    var dt = new Date();
    var date = dt.getDate();
    if( date < 15) dt.setDate(1); // до 15-го числа будет 1-е
    else dt.setDate(15); // после 15-го – 15-е
    
    // Display the month, day, and year. getMonth() returns a 0-based number.
    var day = dt.getDate();
    var month = dt.getMonth()+1;
    var year = dt.getFullYear();
    document.write(day + '-' + month + '-' + year);
    Ответ написан
    Комментировать
  • Как Frontend разработчику реализовать Backend для своего проекта?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Взять лёгкий хорошо документированный микро-фреймворк и по примерам построить свой backend.

    Например, на php: Slim или Lumen.
    Ответ написан
    Комментировать
  • Как найти сумму на обратной дагонали двухмерного массива?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    «Обратные диагонали» характерны тем, что сумма координат X и Y в рамках одной диагонали постоянна. Алгоритм:
    1. подготовить массив сумм из (5 * 2 - 1) элемента, заполненный нулями.
    2. пройтись по всем элементам массива. Сложив координаты получаем id диагонали – он же индекс в массиве сумм.
    3. прибавляем текущий элемент к нужной сумме.
    // суммы – где сумма координат X + Y = N, для каждой диагонали N постоянно
    var side = 5,
      sum = Array.apply(null, Array(side * 2 - 1)).map(Number.prototype.valueOf,0),
    	row, col
    ;
    
    for( row = 0; row < side; row++) {
      for( col = 0; col < side; col++) {
    	  sum[row + col] += arr[row][col];
    	}
    }
    
    result.innerHTML += '<pre>' + JSON.stringify(sum) + '</pre>';

    fiddle
    Ответ написан
    1 комментарий
  • Как вывести случайный тэг img?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    // выборка всех под-элементов в блоке:
    var $el = $('#block_id').children();
    
    // какой-то один случайный из них:
    var $random = $el[ Math.floor( Math.random() * $el.length)]; 
    
    // вставить его куда-то ещё
    $("#suda").append( $random);


    fiddle
    Ответ написан
    Комментировать
  • Как вывести сумму чисел в промежутке через ф-цию?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    upd. самый лаконичный вариант без переборов:
    function rangeSum(a,b) {return (b*b-a*a+a+b)/2}
    
    console.log( rangeSum( 1, 3)); // 6
    console.log( rangeSum( 20, 220)); // 24120


    (старый ответ) Перебором всех значений подряд:
    function rangeSum( from, to) {
      var i, sum = 0;
      for( i = from; i <= to; i++) {
        sum = sum + i;
      }
      return sum;
    }
    
    console.log( rangeSum( 1, 3)); // 6
    console.log( rangeSum( 20, 220)); // 24120


    Но если подумать, сумму можно вычислять без перебора:
    function rangeSum2( from, to) {
      var m = to - from + 1;
      return from * m + ( m * m - m) / 2;
    }
    console.log( rangeSum2( 1, 3)); // 6
    console.log( rangeSum2( 20, 220)); // 24120
    Ответ написан
    1 комментарий
  • Как узнать индекс элемента с большим значением?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    var arr = [ 1, 3, 2, 3, 6, 2 ];
    var maxIndex = arr.indexOf( Math.max.apply(null, arr)); // 4, считается от 0


    1. Math.max() возвращает наибольшее значение из аргументов.
    2. чтобы передать массив вместо списка, используется apply()
    3. получив само наибольшее значение, остаётся найти его индекс в массиве через метод массива indexOf().


    Не очень эффективно, т.к. фактически массив перебирается дважды: в поиске максимума и в поиске индекса. Можно сделать за один проход, запоминая вместе с найденным максимальным значением его позицию:
    var arr = [ 1, 3, 2, 3, 6, 2 ];
    
    function index_max(arr) {
      var i, maxV, maxP;
      for( i = 0; i < arr.length; i++) {
        if( typeof maxV === "undefined" || arr[i] > maxV ) {
          maxV = arr[i];
          maxP = i;
        }
      }
      
      return maxP;
    }
    
    index_max(arr) // 4
    Ответ написан
    1 комментарий
  • Как взять элементы по парам?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Последовательно разбить в пары можно, например, так:
    var data = [{x:0,y:1}, {x:1,y:1}, {x:4,y:1}, {x:5, y:7}]
      , pairs = []
      , i
    ;
    
    for( i = 0; i < data.length; i++) { // перебираем входные элементы
      if( i % 2 === 0) pairs.push([]); // четный – добавляем новую пустую «пару»
      pairs[ pairs.length - 1].push( data[i]); // в последнюю пару добавляем элемент
    }
    
    JSON.stringify( pairs ) // [[{"x":0,"y":1},{"x":1,"y":1}],[{"x":4,"y":1},{"x":5,"y":7}]]


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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    var, где бы вы его ни написали, «поднимается» наверх при интерпретации кода – это называется var hoisting. Поэтому ваши варианты 1) и 2) не имеют разницы. Возможно, во 2-м варианте вы имели в виду let вместо var?

    Проверять перформанс можете и сами console.time(), и приглашать других на jsPerf. Тысячи итераций недостаточно, пробуйте миллион, миллиард.
    Ответ написан
    Комментировать
  • Высчитать сколько произошло действий за определённый участок времени?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Задача напоминает построение гистограммы. Весь интервал бьётся на отрезки по 15 минут, и считается, сколько событий «упадёт» в каждое из ведёрок.

    Я бы сделал так. На вход функции передаются данные отсчётов, время начала и время конца.

    Сначала подготовить ответ – объект, где ключи это время начала 15-минуток, а значения пока нули. Будут числа событий, попадающие в эти интервалы.

    Перебирать каждое событие. Брать его время начала. Смотреть, попадает ли вообще в исследуемый диапазон. Высчитывать начало его 15-минутки, округлив деление времени до ближайшего начала 15-минутки в меньшую сторону. Прибавлять 1 нужному «ведёрку».

    /**
     * @param array hits - массив данных об ударах. 
     * @param int start - начало интервала (включён), число миллисекунд с 1 января 1970 UTC
     * @param int finish - конец интервала (исключён), число миллисекунд с 1 января 1970 UTC
     *
     * @return возвращает объект, где ключи – моменты начала 15-минуток, а значения – число событий
     */
    function bins( hits, start, finish) {
    	var i
    		,step = 15 * 60 * 1000 // 15 минут в миллисекундах
    		,bins = {}
    	;
    	
    	// заполнить ячейки нулями
    	i = start;
    	do { bins[i] = 0 } while( i += step < finish);
    	
    	// перебрать все сэмплы
    	for(i = 0; i < hits.length; i++) {
    		hitTime = hits[i].ts; // считаем, что значение времени лежит в свойстве "ts"
    		if( hitTime < start || hitTime >= finish) continue; // вне диапазона
    		binTime = start + Math.floor( (hitTime - start) / step) * step; // в какое ведёрко попадает
    		bins[ binTime]++;
    	}
    	
    	return bins;
    }
    Ответ написан
    1 комментарий
  • Как добавить/убрать класс по местному времени?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Нужно раз в сколько-то секунд проверять текущее время браузера и ставить классы, в зависимости от часа.

    По-хорошему, не нужно при каждой проверке убирать-ставить классы, когда они и так стоят, поэтому код чуть усложняется добавлением текущего состояния state:
    (function($el) {
        
        var state, timer;
        
        function checkTime() {
            var h = (new Date).getHours(), state_prev = state;
            state = ( h >= 9 && h < 22) ? 'DAY' : 'NIGHT';
            
            if( state_prev !== state) { // только что изменился статус
                if( state === 'DAY') $el.removeClass('disable').addClass('visible');
                else if( state === 'NIGHT') $el.addClass('disable').removeClass('visible');
            }
        }
    
        checkTime(); // вызвать один раз сразу же
        
        timer = window.setInterval(checkTime, 10000); // раз в 10 секунд перепроверять
    })(
    
        $('.opened') // jQuery-выборка элементов, которым переключать класс
    
    );


    Неоптимальная плохая версия, но покороче:
    var $el = $('.opened'); // jQuery-выборка элементов, которым переключать класс
    window.setInterval( function() {
        var h = (new Date).getHours(); // текущий час по локальному времени
        if( h >= 9 && h < 22) $el.removeClass('disable').addClass('visible'); // кабак открыт
        else $el.addClass('disable').removeClass('visible'); // кабак закрыт
    }, 10000); // раз в 10 секунд перепроверять
    Ответ написан
    3 комментария
  • Как отформатировать числа в js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Замените точку на пробел
    function changeSize(){
      option = $("#size option:selected");
      $('.price strike').text(option.attr('compare-price')
        .replace('.',' '));   
      $('.price').text(option.attr('price')
        .replace('.',' '));   
    }
    Ответ написан