Задать вопрос
Ответы пользователя по тегу JavaScript
  • Слишком быстрая программа,всё так?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Добро пожаловать в асинхронность.
    request() выполняется асинхронно. Вот вы его вызвали, он внутри себя запомнил, по какой ссылке нужно (будет) обратиться и куда вернуть результат. И внешний вызов request() всё, отыграл.

    Веб-запрос ещё не пошёл выполняться, а уже работает следующая итерация вашего цикла for().

    Все запросы пойдут выполняться почти параллельно. Поэтому и длительность десяти запросов примерно равна длительности одного.

    Хинт не по теме вопроса, а
    про число записей на стене ВК

    ВКонтакте есть хороший API. В том числе, есть метод wall.get() для получения записей со стены и общего числа записей.

    Чтобы выполнить запрос к АПИ ВК, понадобится сначала получить токен. Для метода wall.get() годится сервисный токен или токен пользователя.
    Ответ написан
    2 комментария
  • Как решить данную задачу?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В нынешней версии
    вашего кода
    // Функция получения случайного числа
    const getRandomNumber = (() => {
      return Math.floor(Math.random() * 1000);
    });
    
    // Функция получения случайного имени
    const getRandomName = (() => {
    	const arr = ['Alex', 'Bob', 'Mark', 'Peter'];
      let randomNumber = Math.floor(Math.random() * arr.length);
      return arr[randomNumber];
    });
    
    // Начальный объект
    const obj = {
      name: getRandomName(),
      id: getRandomNumber()
    };
    
    // 1.2 Добавление нового поля в объект
    obj.number = getRandomNumber();
    
    const randomArray = () => Array(6).fill().map(() => obj);
    console.log(randomArray());
    не исключён повтор значения: запросто может выпасть одно и то же «случайное» число из диапазона 0..999 Чтобы значения не повторялись, можно создать массив с возможными значениями, и вынимать из него Array.splice(i, 1) – так гарантируется отсутствие повторов.

    Объект сейчас создаётся лишь один раз, и один и тот же вкладывается в массив. Может, проще сделать Array.push() в цикле?
    Ответ написан
  • Как случайным образом добавлять элементы?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    1. :nth-child() Selector
    2. .after()

    Выбрать 30-й, вставить после него. Аналогично с остальными.

    Чтобы порядок был случайным, положить имеющиеся в массив const arr = ['banner-0', 'banner-1', 'banner-2']
    При вставке из массива вынимать arr.splice() из случайного индекса Math.floor( Math.random( arr.length)))
    Ответ написан
  • Как решить следующую задачу?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Когда строки длинные, и хочется писать как в вопросе, каждую строку отдельно, можно сделать их элементами массива и соединить через join():
    alert([
    "Красный цвет задаётся HEX-кодом "
    ,"#"
    ,"FF"
    ,"00"
    ,"00"
    ].join(''));
    Ответ написан
  • Как удалить обрабочик события?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно сделать функцию-создающую-функцию с параметром:
    function cbMaker(param) {
      const cb = function(event) {
        console.log(param, event);
        document.removeEventListener('keydown', cb);
      }
      return cb;
    }
    
    document.addEventListener('keydown', cbMaker(1));
    Ответ написан
    7 комментариев
  • Правильно ли я понимаю callback функции?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Не совсем удачное название аргумента callback-функции в вызове (последняя строчка).

    Вместоf(true, 500, callback => console.log(callback));
    может, лучше
    const myCallback = arg => console.log(arg);
    f(true, 500, myCallback);
    Ответ написан
    Комментировать
  • Можно ли использовать поисковые методы внутри друг друга?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    1. Не «внутри» друг друга. Метод вызывается у объекта.

    document.getElementById() – это метод getElementById() у объекта document. Вызов возвращает Element. Или null, если нет элемента с таким ID.

    Второй вызов – пытаетесь вызвать метод getElementById() уже у объекта Element. А у него такого метода нет.

    2. Не «поисковые» методы. document.getElementById() не ищет, а просто берёт, если есть такой.
    Ответ написан
    Комментировать
  • Почему не удаляется обработчик события клика?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Метод bind() создаёт каждый раз новую копию функции.

    Для отмены слушателя нужно передать именно действующий обработчик, а не похожий.
    Запишите его в переменную и далее действуйте с переменной:
    const listener = this.onclickWindowHandler.bind(this);
    window.addEventListener('click', listener);
    // ...
    window.removeEventListener('click', listener);
    Ответ написан
    Комментировать
  • Приоритет выполнения операндов и операторов. Почему так происходит?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Разница в примерах – в возвращаемом значении:
    • alert(value) возвращает undefined
    • myalert(value) возвращает value


    Выражение A || B && C разбирается как A || (B && C)

    Сначала оценивается A. Если оно приводится к false, требуется проверить второй аргумент ||, т.е. (B && C)
    Сначала проверяется B. Если оно приводится к false, то проверять C уже не нужно.
    Ответ написан
    5 комментариев
  • Сортировка html блоков JS?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Собрать все блоки в словарь, где ключ - слово, значение - этот блок.
    Ключи отсортировать.
    Расставить блоки назад в родителя первого из них.
    код JavaScript
    function resort(selector) {
    	const nodeList = document.querySelectorAll(selector);
      const dict = {};
      const parent = nodeList[0].parentNode;
      nodeList.forEach(node => {
      	const key = node.querySelector('p').innerText;
        dict[key] = node;
        node.parentNode.removeChild(node);
      });
      const keys = Object.keys(dict);
      keys.sort().forEach(k => parent.appendChild(dict[k]));
    }
    
    resort('.slide');


    Работающий пример:
    Ответ написан
    1 комментарий
  • Как быстро найти подстроку в строке?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Решил топорно, по времени проходит. Но там такие крутые решения короткие в топе!

    Обходить массив слов достаточно один раз.
    Очередное слово может найтись в target в нулевой позиции - тогда оно "первое", или в другой, тогда надо проверить что та позиция + длина слова точно достают до конца target.
    Складывать в массивы позицию подходящего слова и длину искомого другого слова.
    Нашли очереденое Начальное слово - смотрим, есть ли ему соотв. искомая длина среди найденных Конечных.
    Нашли очередное Конечное слово - смотрим, есть ли соответствующее ему по искомой длине Начальное среди уже найденных.
    Как только нашлась пара - возвращаем ответ.

    мое так-себе решение
    function fn(words, target) {
      
      const length = words.length, targetLength = target.length;
      
      const aWord = [];   // индексы слов в aWords
      const aWant = [];   // какой длины не хватает до целого
      
      const bWord = [];
      const bWant = [];
    
    
      for (let i = 0; i < length; i++) {
    
        const word = words[i];
    
        const x = target.indexOf(word);
        if (-1 === x) continue;
        
        const wordLength = word.length;
        const want = targetLength - wordLength;
    
        if (x === 0) { // в начале составного, первое подслово
          
          aWord.push(i);
          aWant.push(want);
          
          const bIndex = bWant.indexOf(wordLength);
          if (-1 === bIndex) continue;
          
          const bWordIndex = bWord[bIndex];
          return [words[bWordIndex], word, [i, bWordIndex]];
          
        } else { // не в начале слова встретилось - второе слово, в конце цели
          
          if (x + wordLength !== targetLength) continue; // не попадает в конец
          
          bWord.push(i);
          bWant.push(want);
          
          const aIndex = aWant.indexOf(wordLength);
          
          if (-1 === aIndex) continue;
          const aWordIndex = aWord[aIndex];
          return [words[aWordIndex], word, [aWordIndex, i]];
    
        }
      }
      
      return null;
    }
    крутая идея в топе

    Бить целевое слово во всех возможных вариантах пар - а их даже меньше, чем длина целевого слова!
    Искать каждые два слова в данном массиве. Если оба нашлись, вот оно, решение.
    В 8 строк. Если поджать форматирование, то в 6.
    Ответ написан
    2 комментария
  • Как отследить момент столкновения?

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

    Запоминайте где-то "текущее" состояние
    var isCollided = false; // изначально нет столкновения
    На каждой итерации – будь то по setInterval() или requestAnimationFrame() – проверяйте, есть ли столкновение сейчас. И сравнивайте с предыдущим.
    const isNowCollided = checkIfCollided(); // как-то проверяем, есть ли сейчас наложение
    if (isNowCollided && !isCollided) { // впервые столкнулись!
      // alert! alert!
    } else if (!isNowCollided && isCollided) { // выехали из зоны
      // всем неинтересно
    } else {
      // вообще без новостей
    }
    
    isCollided = isNowCollided;
    Ответ написан
    Комментировать
  • Срабатывание строки кода не более раза в n секунд?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Запоминать где-то время создания "объекта".
    При очередном клике смотреть, прошло ли достаточное время (или время ещё не записано), иначе игнорировать.
    Ответ написан
    Комментировать
  • Как по клику найти индекс элемента среди его соседей?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    document.querySelectorAll('.slide').forEach(
    	(el, i) => el.addEventListener('click', () => console.log(1+i))
    )


    Ответ написан
    Комментировать
  • Как в разные div'ы вставлять разные рандомные картинки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    В этой задаче хорошо бы генерить случайные числа без повтора максимально долго. Исчерпывать последовательность 0..n, в случайном порядке выдёргивая из этой «колоды» очередную карту. Когда колода пустеет, открываем новую.

    Можно примерно так сделать функцию, которая будет выдёргивать из колоды случайную карту, и другой функцией генерить для неё картинку:
    // Итератор случайных уникальных - Random Unique
    function getRUIterator(max) {
      let buffer = [];
      
      const ruIterator = {
        next: function() {
          if (buffer.length === 0) { // если колода пуста
            for (let i = 0; i < max; i++) buffer.push(i); // открываем новую 0..max
          }
    
          const index = Math.floor(Math.random() * buffer.length);
          return buffer.splice(index, 1)[0]; // вынимаем из колоды случайную карту
        }
      }
      
      return ruIterator;
    }
    
    /**
     * генерим в каждый див по случайной картинке
     * как можно дольше без повторов
     * @param int iTotal число доступных картинок
     * @param Array массив строк - айдишки div'ов, куда вставлять
     */
    function placeRandomImages(iTotal, aDivs) {  
      function placeImage(n, id) {
        const img = new Image();
        img.src = `img/${n}.png`;
        img.border = '0';
        document.getElementById(id).appendChild(img);
      }
      
      // будет генерить случайные неповторяющиеся
      const RUI = getRUIterator(iTotal);
      
      for (let i = 0; i < aDivs.length) {
        placeImage( RUI(), aDivs[i]);
      }
    }
    
    placeRandomImages(2, ["imaaaga", "imaaaga2"]);
    Ответ написан
    Комментировать
  • Можете пояснить логику вызова функции по завершению асинхронной загрузки внешнего скрипта?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Не нашёл, как называется такой паттерн. Попробую объяснить, как я понимаю этот код.

    Во время выполнения кода неизвестно, определён ли уже глобальный объект. У глобального должен быть метод push(), принимающий пачку новых параметров. Но мы готовы к обоим вариантам: пушим или в крутой объект, или в пустой массив.

    После загрузки внешнего скрипта, тот смотрит, пусто ли глобальное свойство, на которое он претендует. Если не пусто - там накопились данные для него и он их себе записывает куда надо при инициализации. Примерно так:
    (function(w, n) {
      w[n] = w[n] || [];
      w[n].push({a: "A", b: "B"});
    })(window, 'tosterQuery');
    
    
    
    // в скрипте подгружаемом позже
    (function(w, n) {
      // не перезаписать объкт. Только если пустой или массив.
      if (w[n] && !Array.isArray(w[n])) return;
        
      function f() {
        const data = w[n] || [];
        // определяем свой push с блекджеком
        this.push = function(x) {return data.push(x);}
        this.getData = function() {return data;}
      }
     
      w[n] = new f(); // занимаем глобальное свойство
    })(window, 'tosterQuery');
    
    tosterQuery.getData(); //  [{"a":"A","b":"B"}]
    tosterQuery.push({z:"Z"});
    tosterQuery.getData(); //  [{"a":"A","b":"B"}, {"z":"Z"}]
    Ответ написан
    1 комментарий
  • Какие сайты с тестами по JS вы знаете?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    CodeWars

    Там не только JS, есть и многие другие языки.
    Ответ написан
    Комментировать
  • Как лучше оптимизировать и сделать мой код на JavaScript красивее и короче?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Если это практическая задача, а не собеседование с глубоко зарытыми подвохами, то так:
    if (!roofpt) Price2 = 5500; // null, 0, undefined, false, пустая строка
    else if (roofmat == 1) Price2 = 7900; // и так известно, что не пустое
    else if (roofmat == 2) Price2 = 8900; // и так известно, что не пустое
    else Price2 = 0; // по умолчанию

    Если же это из собеседования

    В исходном коде есть такая деталь. Приоритет операторов в JS ставит && выше, чем ||. Эти два условия выглядят похоже, имелась в виду, наверное, лишняя перепроверка на null/ноль:
    (roofpt  == null || roofpt  == 0) 
    (roofpt !== null || roofpt !== 0 && roofmat == 1)


    Но сначала &&, потом ||:
    A || B && C === A  ||  (B && C)
    // и второе условие на деле считается так:
    (roofpt !== null || (roofpt !== 0 && roofmat == 1))

    Т.е. второе условие выполнится и просто при любом rootpt, неравном null.

    Тут же ещё одна деталь. Нестрогое равенство == и строгое неравенство !==. Разжёвывать не буду, чтобы вы провалили собеседование.
    Ответ написан
    1 комментарий
  • Как оптимизировать и сократить код?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Описаны последовательные отрезки якобы непрерывного диапазона. Косяк в том, что для значений между, скажем, 120 и 120.001, условия не определены и код даст ошибку, т.к. не определится одна из переменных.

    Поэтому лучше цепочка else if. Поскольку они перемножаются и по умолчанию единицы, можно сразу определять конечное значение:

    if (floors.value == 1) {
    
      aF = 1; // по умолчанию, для больше 300
      
      if (area.value <= 120) aF = 1.26;
      else if (area.value <= 140) aF = 1.24;
      else if (area.value <= 160) aF = 1.23;
      else if (area.value <= 200) aF = 1.22;
      else if (area.value <= 260) aF = 1.2;
      else if (area.value <= 300) aF = 1.19;
    
      console.log(aF);
      
    } else if (floors.value == 2 || floors.value == 3) {
      
      bF = 1; // ? для меньше 100 .. и больше 300
      
      if (area.value >= 100 && area.value <= 130) bF = 1.3;
      else if (area.value <= 160) bF = 1.27;
      else if (area.value <= 200) bF = 1.24;
      else if (area.value <= 300) bF = 1.22;
    
      console.log(bF);
    
    }
    Ответ написан
    Комментировать