Задать вопрос
Ответы пользователя по тегу JavaScript
  • Можно ли с помощью js удалить атрибут в элементе img?

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

    Плагин rocket-lazy-load можно деактивировать для определённых картинок,
    если добавить им атрибут data-no-lazy="1"

    <img src="logo.png" data-no-lazy="1" title="Лого от Артемия за килобакс" alt="">
    Ответ написан
    6 комментариев
  • Не работает код Js - как сделать, чтобы при нажатии на кнопку всегда выполнялось добавление элементов на html - страницу?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    в переменной var divContent у вас строка текста (пусть и HTML).
    в следующей строке appendChild() ожидает не строку текста, а HTML узел (Node) – его можно создать как у вас выше document.createElement().

    В общем два пути:
    1. Создавать HTML, но тогда приклеивать его через element.innerHTML = myHTML;
    2. Создавать узлы и их через appendChild() Но у вас требуется два инпута вставить, с множеством атрибутов. На чистом JS это займет несколько строк:
    spoiler
    var input = document.createElement('input');
    input.type = "text";
    input.placeholder = "Наименование";
    input.className = "expenses-item";
    newDiv.appendChild(input);
    
    input = document.createElement('input');
    input.type = "text";
    input.placeholder = "Цена";
    input.className = "expenses-item";
    newDiv.appendChild(input);
    Ответ написан
    1 комментарий
  • Как эффективно выбирать каждый n элемент массива?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    «Эффективно» в смысле кратко, в одну строку:
    const everyNth = (arr, n) => arr.filter((e, i) => i % n === 0);
    
    // применение
    everyNth([0, 11, 22, 33, 44, 55, 66, 77], 7) // [0, 77]


    «Эффективно» без лишних итераций, старым добрым циклом for():
    function everyNth(arr, n) {
      const result = [];
      for (let i=0; i<arr.length; i+=n) result.push(arr[n]);
      return result;
    }


    Какой быстрее – сделал проверку на jsPerf
    Цикл for()быстрее в 7 раз!
    скрин
    5dffbba9538a7281867384.png
    Ответ написан
    Комментировать
  • Как сделать AJAX запрос без jqury?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Дело в Content-type: вы передрали код из примера с application/x-www-form-urlencoded, который предполагает отправку данных как в GET-параметрах: a=1&b=2&c=3

    При этом шлёте JSON-закодированные данные.

    Замените на
    request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");


    В PHP обработчике брать php://input
    $data = json_decode(file_get_contents("php://input"));
    Ответ написан
    6 комментариев
  • Работа с массивами. Метод forEach и его принцип работы?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    forEach() вызывает функцию по очереди с каждым из элементов массива. В данном примере вызовется function(1), function(3), function(4), ... function(5)

    result это объект, где свойствами будут встреченные цифры (как строки).

    Пока цифра не встречалась, такого свойства у result нет, и, например, result[1] будет поначалу undefined. И в таком случае создаётся это свойство со значением 1.

    А если такое свойство (со значением-счётчиком = 1 или уже больше) найдено, это значение не равно undefined, и оно будет увеличено на 1.

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

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вопрос плохо составлен: некоторые, включая меня, в начале решили что школьник не знает математику.
    В комментариях выяснилось, что вопрос вызван опасениями проблем ошибок округления дробных чисел.
    Но не раскрыты детали – какие значения могут быть введены, что требуется на выходе.

    Возможно, достаточно простого округления Math.round() для определения попадания в интервал:
    var priceProduct = 2000;
    var monthlyPayment = 230;
    
    var precision = 1e-6; // точность одна миллионная
    
    var months = priceProduct / monthlyPayment;
    var nearest = Math.round(months);
    var diff = months - nearest;
    if (diff > precision) months = nearest + 1; // == Math.ceil()


    Если уверены, что проблема есть и точность важна – то можно использовать библиотеку для операций с десятичными числами любой точности. Например, decimal.js
    Ответ написан
    2 комментария
  • Как посчитать уникальные символы в строке?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Что не так:
    1. цикл в цикле – лучше обойтись одним, если можно. Поиск можно заменить на indexOf()
    2. в качестве накопителя уникальных строка как-то нетрадиционна. Обычно массив, или ключи объекта. Или, изысканно, Set – и потом будет интересовать его длина (размер, size, кардинальность : )

    const text2 = 'You know nothing Jon Snow';
    
    function countUniqChars(str) {
      return new Set(str.split('')).size;
    }
    
    countUniqChars(text2) // 13
    Ответ написан
    Комментировать
  • Что лучше использовать для построения диаграммы?

    sergiks
    @sergiks Куратор тега PHP
    ♬♬
    Отличная библиотека для графиков, особенно интерактивных – d3js

    Готового решения там нет, но есть всё необходимое для сборки такого. Посмотрите галерею примеров.
    И, в частности, donut chart и Pie chart update.
    Ответ написан
    Комментировать
  • Как работает функция изменения положения элемента в массиве?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Чтобы поменять местами, надо:
    1. выдернуть первый,
    2. выдернуть второй,
    3. вставить на новое место первый,
    4. вставить на новое место второй.

    Метод массива .splice() умеет и выдирать и вставлять одновременно. Его аргументы:
    позиция-из-которой, сколько-выдрать, вставить-этого, вставить-ещё, ...
    А возвращает он массив выдранных. Поэтому [0] вернёт первый выдранный элемент.

    Можно расписать вашу функцию подробнее:
    function swap(arr, from, to) {
      // выдёргиваем:
      const A = arr.splice(from, 1)[0];
      const B = arr.splice(to-1, 1)[0]; 
      // -1 т.к. массив стал короче после первой операции
    
      // вставляем
      arr.splice(from, 0, B); // 0 - ничего не вырезаем, только вставляем
      arr.splice(to, 0, A);
    }

    Ещё проще то же выглядит безо всяких splice()
    function swap(arr, from, to) {
      // выдёргиваем-копируем:
      const A = arr[from];
      const B = arr[to]; 
    
      // вставляем-заменяем
      arr[from] = B;
      arr[to] = A;
    }
    Ответ написан
    3 комментария
  • Как найти и изменить динамический элемент в Javascript?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    MutationObserver позволяет следить за изменениями DOM.

    Это для «тяжёлых случаев», где вы никак не влияете на код, добавляющий элементы.
    Ответ написан
    Комментировать
  • Как вам такое решение задачки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Предложу свой велосипед на костылях. Без сортировки!
    const zip = arr => arr
      .reduce((agg, c) => {
        const iR = agg.indexOf(c + 1);
        const iL = agg.lastIndexOf(c - 1);
        if (!!~iR && !!~iL) agg.splice(iL, 2); // закрыли дырку
        else if (!!~iR) agg[iR] = c; // сдвинули границу
        else if (!!~iL) agg[iL] = c; // то же
        else { // вставляем сироту - найти позицию сразу после меньшего
          let pos = 0;
          while (pos < agg.length  &&  agg[pos] < c) pos++;
          agg.splice(pos, 0, c, c); // вставляем дважды
        }
        return agg;
      }, [])
      .reduce((agg, c, i, arr) => {
        if (!(i&1)) agg.push(arr[i+1] === c ? c : [c, arr[i+1]].join('-'));
        return agg;
      }, [])
      .join(', ')
    ;

    Массив границ диапазонов, в нём всегда чётное число элементов.
    Очередное число вставляем в массив: ищем, есть ли его ближайшие соседи слева и справа.
    • Если есть оба, число закрывает «дырку», надо просто убрать этих двух соседей.
    • Если нашёлся только один – заменяем его собой, сдвигая границу.
    • Если ни одного соседа, значит, число пока сирота, вставляем его дважды,
      как будто это и левая и правая граница диапазона.
    Так из первого примера получается [ 0, 5, 8, 9, 11, 11 ]
    Остаётся форматирование. Смотрим только чётные элементы. Если текущий и следующий элементы равны, это «одинокое» число. Если не равны — это диапазон через дефис. И склеиваем через запятую-с-пробелом.

    Учитывая сортированность собираемого массива, можно ускорить, заменив indexOf() и lastIndexOf() на самописный поиск, останавливающийся на элементе, бОльшем или меньшем искомого.

    Fiddle с тестами

    Ответ написан
    2 комментария
  • Объясните в чем тут проблема?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Пользуйтесь консолью – это бесплатно, спортивно, современно!
    console.log(this); // window
    В вашем коде this не принимает значение кнопки, а наследует его из внешнего кода. В данном случае, глобального, поэтому this === window

    Вероятно, вы ожидали, что this будет нажатой кнопкой. Так бы работало без стрелочной функции, если по-старинке передавали function(evt) {}
    Ответ написан
    Комментировать
  • Как получить access_token с правом app_widget?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Виджеты сообществ — документация
    0. Получение ключа доступа
    Для работы с виджетами в сообществе необходимо получить токен сообщества с правом доступа app_widget при помощи события VK Connect: VKWebAppGetCommunityAuthToken в приложении с типом VK Mini Apps.


    Создайте приложение ВК типа VK Mini Apps.

    Понадобится библиотека VK Connect: npm install @vkontakte/vk-connect

    И что-то вроде такого в index.js:
    import connect from '@vkontakte/vk-connect'; 
    
    // Sending event to client
    connect
      .sendPromise('VKWebAppGetCommunityAuthToken', {
        "app_id": 6909581, // id вашего свежесозданного mini App
        "group_id": 1,  // id группы, где вы админ, куда виджет
        "scope": "app_widget"
      })
      .then(data => {
        // Обработка события в случае успеха
        console.log(data);
      })
      .catch(error => {
        //Обработка событияв случае ошибки
      });
    Затем, наверное, webpack'ом билдится готовый скрипт, который подгружается в браузер.

    При этом сам токен вы не получаете, не сохраняете, не копируете. Просто теперь у этого VK Mini App'а вашего есть права на обновление кода виджета в вашем сообществе.
    Ответ написан
    Комментировать
  • Как проверить находится ли пользователь на открытой вкладке?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Есть Page Visibility API (на англ.)

    Оттуда пример кода, который приостанавливает воспроизведение видео, если таб стал неактивным:
    spoiler
    // Set the name of the hidden property and the change event for visibility
    var hidden, visibilityChange; 
    if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support 
      hidden = "hidden";
      visibilityChange = "visibilitychange";
    } else if (typeof document.msHidden !== "undefined") {
      hidden = "msHidden";
      visibilityChange = "msvisibilitychange";
    } else if (typeof document.webkitHidden !== "undefined") {
      hidden = "webkitHidden";
      visibilityChange = "webkitvisibilitychange";
    }
     
    var videoElement = document.getElementById("videoElement");
    
    // If the page is hidden, pause the video;
    // if the page is shown, play the video
    function handleVisibilityChange() {
      if (document[hidden]) {
        videoElement.pause();
      } else {
        videoElement.play();
      }
    }
    
    // Warn if the browser doesn't support addEventListener or the Page Visibility API
    if (typeof document.addEventListener === "undefined" || hidden === undefined) {
      console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
    } else {
      // Handle page visibility change   
      document.addEventListener(visibilityChange, handleVisibilityChange, false);
        
      // When the video pauses, set the title.
      // This shows the paused
      videoElement.addEventListener("pause", function(){
        document.title = 'Paused';
      }, false);
        
      // When the video plays, set the title.
      videoElement.addEventListener("play", function(){
        document.title = 'Playing'; 
      }, false);
    
    }
    Ответ написан
  • Как узнать элемент с которого начинаются цифры в массиве?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Вот такая колбаса вернёт массив, где только «правильные» числа:
    [10, 20, 30, 50, 235, 3000].filter(n => !!~[1,2,5].indexOf(+n.toString()[0]))
    // результат  [ 10, 20, 50, 235 ]
    Вывод на экран пилите самостоятельно.

    Метод массива filter() оставит только те элементы, для которых функция внутри вернёт true. Функция аргумент (в скобках) применяется по очереди к каждому элементу массива (числу).
    Переводит число в строку, забирает первй символ (первую цифру) и переводит опять в число (оператор +).
    indexOf() ищет полученную первую цифру в массиве допустимых: 1, 2, 5 и возврашает его индекс (0, 1 или 2) или -1, если не найдено.
    Битовое инвертирование ~ из -1 сделает 0. А из любого другого числа (из 0, 1 или 2) – сделает ненулевое число. Два !! это два булевых оператора отрицания. Из аргумента делают true или false. Из 0 получится false, из любого другого true. Таким образом связка !!~ и indexOf() даёт ответ на вопрос найден или не найден?
    Ответ написан
    Комментировать
  • Как получить индексы выделенной подстроки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    См. как работать с Selection API.

    Метод getRangeAt() вернёт диапазон Range. Выделенных фрагментов может быть и несколько, но в вашем примере понадеемся на единственный getRangeAt(0)

    У объекта диапазона Range есть свойства startOffset и endOffset – то, про что спрашиваете.

    Ответ написан
    7 комментариев
  • Импорт и экспорт объектов в Javascript. В чём проблема?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    попробуйте с webpack
    Ответ написан
    Комментировать
  • Как сделать так что бы шахматная фигура по клику перемещалась на другую ячейку?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно разделить данные и их отрисовку. Массив «состояния» доски: какая фигура в какой ячейке. Пустая клетка – пустая строка. Клетка с королевой – 'Q'. И функция, которая отрисовывает всю доску, исходя из Состояния.

    Для обозначения фигур использовать буквы из шахматной нотации. King = K, Queen = Q, Bishop = B, Knight = N, Rook = R, pawn = p
    Понадобится словарь, где ключу фигуры соответствует символ для его отображения.

    Каждая ячейка кликабельна. Кнопка в себе хранит координаты X и Y – понадобятся в обработчике клика, общем для всех.
    Хранится переменная для предыдущего. Изначально пуста. Если кликнули по фигуре, а «предыдущая» пуста, значит это Первый клик - выбор фигуры для хода.
    Второй клик должен выбрать другую ячейку, куда поставить выбранную ранее фигуру, или отменить выделение, если Второй раз выбрана та же клетка, что в Первый.

    Ответ написан
    7 комментариев
  • Вернуть программу в исходное состояние методом reset?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно пройтись по всем текстовым инпутам в секции и дать им value=""
    function reset() {
      [...document.querySelectorAll('section.main input[type="text"]')]
        .forEach( el => el.value='' )
      ;
    }


    Пара общих замечаний
    • Вместо
      document.getElementsByClassName('budget_day-value')[0]

      лаконичнее document.querySelector('.budget_day-value')
    • Пояснительный текст к каждому input'у семантически корректнее оборачивать в тег <label>, и либо указывать id инпута в атрибуте for="", либо включать инпут внутрь этого лейбла. Так клик по названию поля сделает фокус внутри этого поля.

    Ответ написан
  • Правильно ли я понимаю что такое замыкание?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Чтобы понять и понять правильно, можно прочитать целиком страницу про Closure на Learn JavaScript ru.

    Оттуда:

    Замыкания

    В программировании есть общий термин: «замыкание», – которое должен знать каждый разработчик.

    Замыкание – это функция, которая запоминает свои внешние переменные и может получить к ним доступ. В некоторых языках это невозможно, или функция должна быть написана специальным образом, чтобы получилось замыкание. Но, как было описано выше, в JavaScript, все функции изначально являются замыканиями (есть только одно исключение, про которое будет рассказано в Синтаксис "new Function").

    То есть, они автоматически запоминают, где были созданы, с помощью скрытого свойства [[Environment]] и все они могут получить доступ к внешним переменным.

    Когда на собеседовании фронтенд-разработчик получает вопрос: «что такое замыкание?», – правильным ответом будет определение замыкания и объяснения того факта, что все функции в JavaScript являются замыканиями, и, может быть, несколько слов о технических деталях: свойстве [[Environment]] и о том, как работает лексическое окружение.
    Ответ написан
    Комментировать