Задать вопрос
  • Как выделить все содержимое контейнера div и скопировать в буфер обмена?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    var content = document.querySelector(".entry-content");
    var button = document.querySelector("#button");
    
    function copyToClipboard(el) {
    	var range;
    	if (document.selection) {
    		range = document.body.createTextRange();
    		range.moveToElementText(el);
    		range.select().createTextRange();
    	} else if (window.getSelection) {
    		range = document.createRange();
    		range.selectNode(el);
    		window.getSelection().addRange(range);
    	} else return;
    	
    	document.execCommand("copy");
    	
    }
    
    button.addEventListener('click', () => copyToClipboard(content));


    CodePen
    Ответ написан
    Комментировать
  • Как правильно применить функцию к элементу?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    У элемента нет метода .colorAdd(), чтобы вызывать так, как вы написали. Вместо
    elem.colorAdd();
    можно сделать
    colorAdd.apply(elem);

    Это вызовет функцию colorAdd(), назначив её контекстом (значением this) переданный первым параметром elem и всё сработает так, как вы задумали. Фиддл.
    Ответ написан
    1 комментарий
  • Как последовательно вызвать промисы с минимальной задержкой?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Попытался разобраться с Promise и async/await. Примерно понял, благодаря вашему вопросу, документации и ответу Антон

    Чтобы для самого первого элемента не добавлялась задержка, сделал доп. условие:
    const delay = _ => new Promise(rs => setTimeout(rs, 3e3));
    
    async function notSoFast(promise) {
      result = await Promise.all([ promise, delay()]);
      return result[0];
    }
    
    async function runPromisesInSequence(promises) {
      for (let i=0; i<promises.length; i++) {
        if(i === 0) {
          console.timeEnd( await promises[0]);
        } else {
          console.timeEnd( await notSoFast(promises[i]));
        }
      }
    }
    
    function makePr(label, dur) {
      return new Promise(rs => {
        console.log('%s started', label);
        console.time(label); // начало отсчёта
        setTimeout(_ => {
          console.log('%s timer completed', label);
          rs(label);
        }, dur);
      });
    }
    
    runPromisesInSequence([
      makePr('r1', 1000),
      makePr('r2', 5000),
      makePr('r3', 0000),
    ]);
    /* Выводит:
    r1 started
    r2 started
    r3 started
    r3 timer completed
    r1 timer completed
    r1: 1005ms
    r2 timer completed
    r2: 5007ms
    r3: 8009ms
    */


    Fiddle
    Ответ написан
    Комментировать
  • Как вывести на JS 27 число текущего месяца и года в формате даты?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    var D = new Date();
    D.setDate(27);
    D.toString()
    Ответ написан
    Комментировать
  • Как, имея число, получить близжайшее большее число, состоящее из тех же цифр?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Upd. Алгоритм ниже неверный, т.к. не работает в случае, когда необходимо переставить сразу несколько цифр.

    Рассматриваем пары неодинаковых цифр в числе.
    Взаимной их перестановкой можно увеличить число только когда левая цифра меньше правой. 23 -> 32
    Размер увеличения тем меньше, чем правее обе цифры. Они могут идти и не подряд, а, скажем, через одну.

    Коэффициент, который требуется минимизировать – это десятичное число из нулей с единицами в этих позициях. Скажем, лучше поменять позиции 2 и 3, чем 4 и 1, т.к. 110 < 1001 Т.е. при переборе позиций меньше всего хотим двигать левую позицию, пока не переберем все варианты правой:
    Варианты для 4
    0011
    0101
    0110
    1001
    1010
    1100

    Отсюда алгоритм.
    1. справа налево перебираем пары цифр пока не найдётся первая пара, где
      левая меньше правой
    2. меняем их местами.

    Всё.
    Ответ написан
    9 комментариев
  • Как выделить все символы русского алфавита на странице, при условии, что атрибуты некоторых элементов могут содержать его?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Нужно рекурсивно обойти всё DOM дерево и рассматривать только текстовые узлы. Регуляркой заменять один-или-несколько-подряд символов из кириллического алфавита (+пробелы, пожалуй) на них же, в обёртке из тега форматирования.
    Примерно так
    function replacer(el){
      var i, node, span;
      if(el.hasChildNodes()) {
        for(i=0; i<el.childNodes.length; i++) {
          node = el.childNodes[i];
          if(node.nodeType === Node.ELEMENT_NODE) {
            if( !!~['SCRIPT','NOSCRIPT'].indexOf(node.nodeName)) continue;
            replacer(node);
          } else if( node.nodeType === Node.TEXT_NODE) {
            if(node.nodeValue.match(/^\s+$/)) continue;
            span = document.createElement("span");
            span.innerHTML = node.nodeValue.replace(/([а-яА-Я]+)/ug, '<i>$1</i>');
            el.insertBefore(span, node);
            el.removeChild(node);
          }
        }
      }
    }
    
    replacer(document.body);

    Тут для простосты схалтурил и вообще каждый текстовый узел заменяю на <span>, чтобы просто innerHTML ему заменить.

    Fiddle
    Ответ написан
    Комментировать
  • Как выделить слово с цветом?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вместо клавишных событий можно слушать событие input – когда значение меняется.

    Две строки – образец и введённый текст – бить на слова по пробелам. Если последний введённый символ не пробел, то последнее введенное слово проверять пока рано. Несовпавшее слово заменяется на обёрнутое в тег.

    примерно так
    const dGet = document.getElementById.bind(document);
    const reSpace = /\s+/;
    const div = dGet('text');
    const text = div.innerText;
    const words = text.trim().split(reSpace);
    dGet('text_input').addEventListener('input', function(e){
      var i, myWords = e.target.value.trim().split(reSpace),
      theWords = words.slice();
      var toCheck = e.target.value.substr(-1) === ' ';
      if(!toCheck) myWords.length--;
      for(i=0; i<Math.min(myWords.length, words.length); i++) {
        if(words[i] !== myWords[i]) {
          theWords[i] = '<i>' + words[i] + '</i>';
        } else {
          theWords[i] = '<b>' + words[i] + '</b>';
        }
      }
      div.innerHTML = theWords.join(' ');
    });
    Fiddle
    Ответ написан
    Комментировать
  • Как заблокировать Яндекс советника?

    Удаление Советника Яндекс.Маркета

    Вкратце, на сервере надо отдавать заголовок Content-Security-Policy
    Content-Security-Policy "default-src 'self' *.VASHDOMEN.ru data: 'unsafe-inline' https://www.youtube.com https://yandex.ru https://mc.yandex.ru https://yastatic.net 'unsafe-eval'"
    Ответ написан
    2 комментария
  • Как запретить выполнение функций на определенном этапе?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Создайте переменную, описывающую состояние. Состояния может быть два: Выбор или Проверка.

    В функциях проверяйте, какое нынче состояние.
    1. rrr() может работать только в Выборе;
    2. ggg() – в Выборе;
    3. yyy() – переключает класс в любом состоянии и меняет состояние.

    И кнопка переключает состояния. Если сейчас 1, то в 2; а если 2, то в 1.

    примерно так
    const STATE_SELECT = 1;
    const STATE_CHECK = 2;
    var state = STATE_SELECT;
    
    var rrr = function() {
      if(state === STATE_CHECK) return;
      $(this).toggleClass("red");
    };
    var ggg = function() {
      if(state === STATE_CHECK) return;
      $(this).toggleClass("green");
    };
    var yyy = function() {
      $(".green").toggleClass("yellow");
      if(state === STATE_CHECK) {
        state = STATE_SELECT;
      } else {
        state = STATE_CHECK;  
      }
    };
    
    $("div").hover(rrr);
    $("div").click(ggg);
    $("button").click(yyy);
    Фиддл
    Ответ написан
    2 комментария
  • Как поменять функцию, чтобы не было абракадабр?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Нечитаемые символы появляются из-за мультибайтовости кириллических символов. Обращение к строке по индексу возвращает значение 1 байта. Кириллические буквы занимают по 2 байта.

    Можно разбивать строку в массив по символам, используя разделитель, понимающий Unicode:
    function _replace(&$str, &$trans){
      $arr = preg_split('//u', $str, null, PREG_SPLIT_NO_EMPTY);
      for ($i = 0; $i < count($arr); $i++) {
    	  if( isset($trans[$arr[$i]])  &&  rand(0,1)) {
    	    $arr[$i] = $trans[$arr[$i]];
    	  }
      }
      $str = implode('', $arr);
    }


    Как бить, с учётом Unicode, взял отсюда.
    Ответ написан
    1 комментарий
  • Бегущая линия по лендингу?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Прорисовку линии делают с помощью SVG и анимации длины и положения штриха. Линию делают не сплошной, а пунктирной, и длину этого одного пунктира соразмерной длине всей линии.
    Ответ написан
    Комментировать
  • Как правильно оптимизировать cURL?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Настройки достаточно указать один раз и затем только менять CURLOPT_URL и CURLOPT_POSTFIELDS.

    Тип запроса, GET/POST лучше вместо CURLOPT_CUSTOMREQUEST задавать традиционно:
    CURLOPT_HTTPGET => TRUE, // GET
    // или
    CURLOPT_POST => TRUE,  // POST


    Попробуйте добавить следующие опции. Посмотрите, ускорит ли это работу заметно?
    CURLOPT_SSL_VERIFYPEER => FALSE,
    CURLOPT_SSL_VERIFYHOST => FALSE,
    CURLOPT_SSL_VERIFYSTATUS => FALSE,


    После выполнения любого из запросов сделайте curl_getinfo() и посмотрите, какие этапы занимают больше всего времени, см. параметры заканчивающиеся на *_TIME
    Ответ написан
  • Код не работает, что не хватает?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Просто уберите function start() { и закрывающую } в конце : )

    Сам JS должен располагаться внизу документа прямо перед </body></html>

    fiddle
    Ответ написан
    Комментировать
  • Как сделать плавное перемещение элемента по нажатию клавиш?

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

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

    Вместо этого используйте состояния. Когда клавишу нажали, игра перешла в состояние «едем вверх» например. И по таймеру или requestAnimationFrame() обновлять координаты игрока и дисплей.

    Когда клавишу отпустили, игра перешла в состояние «всё, не едем».
    Примерно так
    var player = {x:200, y:200, el:document.getElementById('player')};
    player.el.style.left = '' + Math.round(player.x) + 'px';
    player.el.style.top  = '' + Math.round(player.y) + 'px';
    
    var delta = {x:0, y:0};
    
    document.addEventListener('keydown', function(e){
      if(     e.key == 'ArrowRight') delta.x = 1;
      else if(e.key == 'ArrowLeft')  delta.x = -1;
      else if(e.key == 'ArrowUp')    delta.y = -1;
      else if(e.key == 'ArrowDown')  delta.y = 1;
    });
    
    document.addEventListener('keyup', function(e){
      if(     e.key == 'ArrowRight') delta.x = 0;
      else if(e.key == 'ArrowLeft')  delta.x = 0;
      else if(e.key == 'ArrowUp')    delta.y = 0;
      else if(e.key == 'ArrowDown')  delta.y = 0;
    });
    
    var ts = null;
    function step(timestamp) {
      if(!ts) ts = timestamp;
      var passed = timestamp - ts;
      //if(passed < 200) return window.requestAnimationFrame(step);
      ts = timestamp;
      if(delta.x || delta.y) {
        player.x += delta.x * passed / 10;
        player.y += delta.y * passed / 10;
        player.el.style.left = '' + Math.round(player.x) + 'px';
        player.el.style.top  = '' + Math.round(player.y) + 'px';
      };
      window.requestAnimationFrame(step);
    }
    
    window.requestAnimationFrame(step);


    При таком подходе можно одновременно зажимать, скажем, стрелку влево и стрелку вверх – точка поедет по диагонали.
    Фиддл.
    Ответ написан
    Комментировать
  • Как отслеживать состояние элемента в JavaScript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Варианты:

    1. Хороший-быстрый-правильный: обойтись правилами CSS.
    2. MutationObserver
    3. Плохой-медленный-костыль: зарядить setInterval() и проверять свойства элемента пару раз в секунду.
    Ответ написан
    Комментировать
  • А есть список фреймворков для создания API на сервере от гигантов?

    sergiks
    @sergiks Куратор тега Веб-разработка
    ♬♬
    Для API не Laravel, а Lumen; не Symfony, а Silex. Из этой же серии, Slim – всё на PHP. Ни один из перечисленных не упоминает «гигантов» в спонсорах.

    В общем, гуглите "micro-frameworks". Например, рейтинг.
    Ответ написан
  • Как парсить массив json в 2 разных массива?

    При парсинге приведённого JSON получится не массив, а объект. Пары ключ: значение.

    Если нужны только ключи, есть метод Object.keys(), который вернёт массив из ключей:
    var s = '{"United Arab Emirates":"AED","Afghanistan":"AFN","Albania":"ALL","Armenia":"AMD","Netherlands Antilles":"ANG","Angola":"AOA","Argentina":"ARS","Australia":"AUD"}';
    var data = JSON.parse(s);
    var countries = Object.keys(data); 
    
    // United Arab Emirates,Afghanistan,Albania,Armenia,Netherlands Antilles,Angola,Argentina,Australia


    «Тяжёлой» считается операция парсинга, поэтому даже, если хочется в итоге получить не один а два объекта, лучше один раз распарсить, и потом из полученного объекта вынимать нужные данные.

    Но есть вариант прямо при парсинге обрабатывать данные, передав вторым параметром функцию.
    var data = JSON.parse(s, function(k,v){
      return typeof v === "object" ? Object.keys(v) : v;
    });
    Ответ написан
    Комментировать
  • Яндекс Советник чем убить?

    sergiks
    @sergiks Куратор тега Веб-разработка
    ♬♬
    говорят, он идёт в комплекте с другими расширениями браузера, напр. FriGate.

    Удаляете основной плагин – удаляется и довесок Советник.
    Ответ написан
  • Как отменить изменения в DOM сделанные на js?

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

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

    Ещё можно держать исходную разметку в невидимом теге <script type="template" id="sourceCode">. Скриптом копировать её оттуда, применять изменения и вставлять в DOM. При изменении размера, снова доставать нетронутую исходную разметку и переделывать под другую ширину.
    Ответ написан
    1 комментарий
  • Как организовать много параллельных запросов к разным серверам/API?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    В маленьком масштабе можно использовать параллельные curl запросы через curl_multi_init() – их выполнение займёт сколько длится самый тормозной из запросов.

    В бОльшем масштабе нужно поднимать очередь задач, параллельные машины/процессы «рабочие».
    Ответ написан
    Комментировать