Ответы пользователя по тегу JavaScript
  • Как в localstorage вывести больше одной записи?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    держать тудусы в массиве.

    Сохранять массив (JSON-сериализованный).

    const lsKey = 'todo items';
    
    // в самом начале посмотреть, есть ли сохранённые данные?
    const data = JSON.parse(localStorage.getItem(lsKey)) || [];
    
    // добавление нового
    const item = { id: 123, name: 'aaa', title: 'bbb' };
    data.push(item);
    localStorage.setItem(lsKey, JSON.stringify(data));
    Ответ написан
  • В коде не удаётся заставить отработать третий условный оператор else if в методе start. Как переиначить условие, что бы заработало?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    у вас в одном if .. else if объединены проверки двух независимых переменных.

    if (Car.started === false && Car.fuel > 0) {
      // и строго равно false, и fuel больше 0
    } else if (Car.started && Car.fuel <= 0) {
       // сюда попадают не прошедшие первый if
      // и к тому же соответствующие второй проверке started && fuel <= 0
    }
    // никуда не попадут:
    // Car.started = undefined (не строго false, но и не переводится в true
    // Car.started === false, но и fuel > 0
    Ответ написан
  • Как сделать калькулятор для расчета страховки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    По событию изменения селекта или чекбокса, всё перерасчитывать:
    Ответ написан
    8 комментариев
  • Как передать значение из тега H3 в модальную форму?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    функцию swa() забыли привести, как вы начали её писать?

    В неё перым аргументом попадёт объект Event, у которого есть свойство target – элемент, по которому кликнули. В данном случае это тег <a>

    Для этого элемента можно найти родителя (свойство parent) – это div. А в нём уже найти элемент H3:
    const title = event.target.parent.querySelector('h3').innerText;
    Ответ написан
    Комментировать
  • Как получить доступ к глобальной переменной из функции?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Всё дело во времени.
    Массив объявляется и сразу доступен, пустой.
    Запрос отправляете сразу.
    И ожидаете результатов тут же, сразу же — вот это ошибка.

    Ответ на запрос приходит не сразу, а (много) позже. Асинхронно. Обращаться к «глобальному» массиву есть смысл только после получения ответа.

    Поэтому откройте удивительный мир промисов!
    Ну, или просто вызывайте отрисовку таблицы redraw_table() в коллбэке по успешному завершению выполнения запроса.
    Ответ написан
    1 комментарий
  • Как сгруппировать id объектов, у которых совпадают остальные свойства?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Нет смысла выделять первый id как особый, и добавлять к нему в массив match другие похожие — все id с одинаковыми прочими значениями равноправны. Поэтому предлагаю как результат просто массивы, где собраны id с совпадающими свойствами.

    Понадобится хэш из ключей, исключая id, упорядоченных по алфавиту, и значений. Этот отпечаток будет одинаков у совпадающих объектов, несмотря на разные id (и разный порядок ключей).

    Получаем объекты { id, hash }, затем составляем «словарь», где ключи – хэши, а значения – Set'ы с id, у которых оказался одинаковый хэш. Set'ы – чтобы не повторялись одинаковые id.

    Потом остаётся из этих Set'ов сделать обычные массивы.
    const arr = [
      { id: 1, we: 'cn', le: null },
      { id: 2, le: null, we: 'cn' },
      { id: 3, we: 'cn', le: 'car' },
      { id: 1, we: 'cn', le: null },
    ];
    
    const dict = arr
      .map(({ id, ...obj }) => {
        const keys = Object.keys(obj).sort();
        const ordered = keys.reduce((acc, c) => {
          acc[c] = obj[c];
          return acc;
        }, {});
        return { id, hash: JSON.stringify(ordered) };
      })
      .reduce((acc, c) => {
        (acc[c.hash] ??= new Set()).add(c.id);
        return acc;
      }, {});
    
    Object.values(dict).map(s => [...s]); // [ [1, 2], [3] ]
    Ответ написан
    9 комментариев
  • Как исправить код, чтобы он заработал?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    HTML отдельно, JS отдельно.
    Слушателей событий добавлять через addEventListener()
    Забыть про document.write(). Вместо этого использовать element.innerText = "Хабр"; например.
    Обновлять запись баланса понадобится из двух разных мест: в начале, и при каждом выигрыше. Поэтому – в функцию.

    Ответ написан
  • Как импортировать все export default файлы из папки?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    «Кроме импорта каждого» стандартных вариантов нет.

    Можно сделать в папке index.js, в который таки прописать каждый файл в папке.
    // papka/index.js
    import a from './a';
    import b from './b';
    // ...
    
    export { a, b, };


    Зато потом удобно
    // main.js
    import * as Papka from '/papka';
    
    const { a, b } = Papka;
    console.log(a, b);
    
    // или
    Object.entries(Papka).forEach(([key, value]) => console.log(key, value));
    Ответ написан
    1 комментарий
  • Как выполнить последовательно функцию js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    async/await тут лишний, достаточно просто
    const get_element_list = id => {
      return axios({
        url: `${url_hook}/lists.element.get.json`,
        method: 'post',
        data: {
          IBLOCK_TYPE_ID: 'lists',
          IBLOCK_ID: 17,
          filter: {
            PROPERTY_70: 1,
            PROPERTY_74: id,
          },
        },
      }).then(response => {
        const result = response.data.result[0];
        console.log(result, response.status, response.data); // посмотрите, что тут
      });
    };
    Ответ написан
    Комментировать
  • Как записать надпись на кнопке в cookies?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сохранять удобнее не в куках, а в localStorage.

    Нужна модель данных. Есть кнопки, у каждой, наверное, уникальный id. На случай, если их перемешают иначе, или добавится новая — полагаться только на порядковый номер в коллекции, i, не годится: сейчас на 3-м месте одна кнопка, завтра окажется другая, а мы для неё запомнили включённое состояние.

    Итак, есть кнопки с уникальными id. Кнопка может быть добавлена или не-добавлена в избранное. Булево значение: true или false. Запоминать будем набор пар ключ-значение. Ключ id, значение true/false. Что-то типа { "abc123": true, "xyz789": false, }

    При загрузке страницы проверить, есть ли сохранённый комплект? Применить его. Остальным кнопкам значение по-умолчанию.

    При любом изменении кнопок — сохранять обновлённую коллекцию.

    Надписи показывать исходя из true/false в этой коллекции.
    Ответ написан
    Комментировать
  • Интересная задача на js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Решение не верно, т.к. расчитывает только на эти 4 имени. Что, если там будут другие?

    Алгоритм:
    1. составить объект, где ключи – имена, а значения – счётчики, сколько раз имя встретилось.
    2. после полного подсчёта, найти максимум и минимум счётчиков.
    3. собрать имена, у которых счётчик равен максимуму или минимуму. Каждого, теоретически, может оказаться больше одно, поэтому – в массивы имён.
    4. пройти по всем ключам объекта со счётчиками, и исключить имена, которые есть среди макс и мин. – останутся «остальные».


    spoiler
    const mostLeastAndTheRest = names => {
      const dict = names.reduce((acc, name) => ((acc[name] ??= 0), acc[name]++, acc), {});
      // { "Женя": 3, "Иван": 1, "Виктор": 4, "Константин": 1 }
    
      const values = Object.values(dict);
      const max = Math.max(...values);
      const min = Math.min(...values);
    
      const entries = Object.entries(dict);
      const winners = entries.filter(([_, value]) => value === max).map(([key, _]) => key);
      const losers = entries.filter(([_, value]) => value === min).map(([key, _]) => key);
      const rest = Object.keys(dict).filter(name => !winners.includes(name) && !losers.includes(name));
      return { winners, losers, rest };
    };
    
    mostLeastAndTheRest(['Женя', 'Женя', 'Иван', 'Женя', 'Виктор', 'Виктор', 'Константин', 'Виктор', 'Виктор']);
    /*
    {
      "winners": [ "Виктор" ],
      "losers": [ "Иван", "Константин" ],
      "rest": [ "Женя" ]
    }
    */


    Ещё вопрос — особый случай, если всех одинаковое число, то все – «победители» или «проигравшие» ?
    Ответ написан
    1 комментарий
  • Как отправлять сообщение вебсокета другим подключениям, не текущему?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Сервер, приняв событие А, знает, с какого соединения он его принял.

    Это соединение и исключать при рассылке всем (остальным).

    Не знаю, как у вас реализована рассылка-всем, но, вероятно, есть цикл перебора активных подключений (у каждого свой id), и отправка сообщения. В этом цикле можно проверять, не тот ли это id, с которого пришло входящее.
    Ответ написан
  • Как скрыть API KEY телеграмма?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Всё, что оказалось в браузере — утекло.

    Поэтому ключа не должно быть «просто в js», никак.

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

    Копать в направлении POST-запроса из JS с помощью fetch() или, удобнее, axios.
    На бэке принимать сообщение и отправлять его в тележку, используя curl
    Ответ написан
    Комментировать
  • Как сделать русское лото?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    нужен рандом без повторений. Как вариант, сделать массив из всех доступных чисел 1..99, и каждый раз вынимать случайно выбранное число из массива — так точно повторов не будет.

    // массив 1..99
    const range = Array(99)
      .fill()
      .map((_, i) => i + 1); // массив 1..99
    
    // 6 неповторяющихся выигрышных
    const win = Array(6)
      .fill()
      .map(() => range.splice(Math.floor(Math.random() * range.length), 1).pop())
      .sort((a, b) => a - b);
    
    // [ 1, 55, 69, 76, 91, 92 ]
    Для выбора выпавших чисел игрока этот же range уже использовать нельзя – в нём не хватает 6 чисел.
    Ответ написан
    5 комментариев
  • Как при нажатии на элемент узнать его место в массиве у родителя?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    у parent'а возьмите свойство children, в нём найдите indexOf кликнутого элемента.

    Такой же вопрос с ответами: https://qna.habr.com/q/1177140
    Ответ написан
    2 комментария
  • Как корректно вывести значение из data атрибута в инпут?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    -$(this).parents( ".wrapper" ).find(".btn-order-show").attr('data-color', choice);
    +$(this).parents( ".wrapper" ).find(".btn-order-show").data('color', choice);
    Ответ написан
  • Как записать данные в переменную после выполнения axios?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Опять кто-то не понял асинхронности.

    axios.get() возвращает Promise. Его метод .then() выполнится не сразу, а когда-то потом, когда будет получен результат запроса. Представьте, что интернет очччеенньь мееедленнныыыйй.

    Зато остальной код выполняется привычно сразу («синхронно»). В т.ч. и console.log() в последней строке – сразу же за созданием объекта. Но на тот момент веб-запрос ещё не выполнился.

    TL&DR надо ждать. Это можно делать несколькими способами: коллбэком, промисами, обёрткой вокруг них async/await.
    Например
    class Address {
      address = null;
      data = [];
     
      data() {
        return this.data;
      }
      
      constructor(address) {
        this.address = address;
      }    
    
      fetchInformation() {
        return axios.get(`${API_BASE}/getAddressInformation`, {
          params: {
            address: this.address
          }
        }).then(({ data }) => this.data = data);
      }
    }
    
    async function initialize() {
      const address = new Address(TEST_WALLET);
      await address.fetchInformation();
      console.log(address);
    }
    
    initialize();
    Ответ написан
    4 комментария
  • DOM. Конструктор класса?

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

    У всех (ну, почти) объектов в JavaScript в корне цепочки наследования — глобальный Object. У прототипа которого есть свойство constructor. Это ссылка на функцию, создавшую сей инстанс.

    У функций в JavaScript есть свойство name.

    Не важно, как именно создан объект. Если он — объект, у него, скорее всего, есть конструктор:
    const el = document.createElement('div');
    el.constructor.name // "HTMLDivElement"


    А вот с классом
    class Habr {
      constructor(q) {
        this.q = q;
      }
    }
    
    const h = new Habr('есть конструктор?');
    h.constructor.name  // "Habr"
    Ответ написан
    Комментировать
  • Как это расшифровать?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    можно предположить, что это массив, где разделитель 'x'. Это даст 71 число.
    большинство начинается с "2004", но каждое 9-е — с "2005". Эти 2005-е все одинаковы: 20056745.
    Итого 8 групп по 8, и 7 разделителей между ними. 64 + 7 = 71

    Многие значения после префикса"2004" повторяются:
    7155 7155 7155 7155 7155 7155 7155 7155
    6881 6881 6881 6881 6881 6881 6881 6881
    6881 6881 6881 6881 6881 6881 6881 6881
    7429 7566 7429 7429 7566 7429 7429 7429
    8114 7018 8114 7840 6881 7840 7840 8114
    7703 7703 7840 7018 6881 7018 7155 7703
    7155 7840 7566 7566 7292 7566 8114 7155
    7018 7703 7977 7566 7155 7566 7155 7018
    код для получения
    const value = '20047155x20046881x20046881x20047429x20048114x20047703x20047155x20047018x20056745x20047155x20046881x20046881x20047566x20047018x20047703x20047840x20047703x20056745x20047155x20046881x20046881x20047429x20048114x20047840x20047566x20047977x20056745x20047155x20046881x20046881x20047429x20047840x20047018x20047566x20047566x20056745x20047155x20046881x20046881x20047566x20046881x20046881x20047292x20047155x20056745x20047155x20046881x20046881x20047429x20047840x20047018x20047566x20047566x20056745x20047155x20046881x20046881x20047429x20047840x20047155x20048114x20047155x20056745x20047155x20046881x20046881x20047429x20048114x20047703x20047155x20047018';
    
    value.split('x').map(s => +s.replace(/^2004/, ''))
      .reduce((acc, c, i) => {
      if ((i + 1) % 9 !== 0) {
        (acc[i % 9] ??= []).push(c);
      }
      return acc;
    }, [])
      .map(ar => ar.join(' '))
      .join('\n')

    Причём, уникальных значений там всего 10:
    7155, 6881, 7429, 8114, 7703,
    7018, 7566, 7840, 7977, 7292
    как получить
    [...value.split('x').map(s => +s.replace(/^2004/, ''))
      .reduce((acc, c, i) => {
      if ((i + 1) % 9 !== 0) {
        acc.add(c);
      }
      return acc;
    }, new Set())].join(', ')
    Ответ написан
    3 комментария
  • Как добавить следующий символ к переменной js?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Если непременно хочется с циклом и условиями, то так:
    function makeAbbr(words) {
      let result = '';
      for (let i = 0; i < words.length; i++) {
        const char = words[i];
        if (char !== ' ' && (i === 0 || words[i - 1] === ' ')) {
          result += char;
        }
      }
      return result;
    }
    символ — не пробел, И, к тому же, самый первый в тексте, ИЛИ перед ним был пробел.

    Но приятнее, конечно, разбить текст на массив слов, и от каждого взять первую букву:
    const makeAbbr = words =>
      words
        .trim() // убрать пробелы по краям строки
        .split(/\s+/) // разбить по пробелу(ам) в массив
        .map(w => w[0].toUpperCase()) // от каждого взять первые буквы
        .join(''); // склеить в строку
    
    makeAbbr(' мир    труд май') // "МТМ"
    Ответ написан
    4 комментария