Ответы пользователя по тегу JavaScript
  • Можно ли сделать switch-case из списка?

    @Interface
    Можно примерно так
    let one = ['a', 'b', 'c'];
    let two = ['1', '2', '3'];
    
    const inp = '2';
    
    const foundList = [one, two].find(list => list.includes(inp));
    
    switch (foundList) {
        case one: console.log('one'); break;
        case two: console.log('two'); break;
    }


    , но имхо лучше if'ами
    Ответ написан
    Комментировать
  • Как заблокировать нажатие по клавиатуре?

    @Interface
    Дефолтное поведение можно предотвратить через event.preventDefault(), но это не для всего сработает. Например, перебить Ctrl+w у вас не получится.

    Если вы пытаетесь заблокировать открытие dev-tools :) - бросьте это дело. Все равно, любой кто хоть немного шарит откроет все, что ему нужно и своего добьется, а тот кого это остановит все равно ничего серьезного там сделать не смог бы.
    Ответ написан
    Комментировать
  • Как из массива вывести большое количество товаров на чистом js?

    @Interface
    var goods = {};
    
    const numberOfGoods = 100;
    for (let i = 0; i < numberOfGoods; i++) {
     goods[`item${i}`] = {
        id: i,
        name: `диван №${i}`,
        description: `тут описание дивана №${i}`,
        price: Math.round(Math.random() * 200 + 1000), // цены рандомно от 1000 до 1200
     }
    }
    
    var out ='';
    for (var key in goods){
      out += 'Название: ' + goods[key].name+ '<br/>';
      out += 'Описание: ' + goods[key].description+ '<br/>';
      out += 'Есть на складе: ' + goods[key].price+ '<br/>'; // почему вдруг "pirce" = "есть на складе" ¯\_ツ_/¯
      out += '<hr>';
    }
    document.getElementById('outGoods').innerHTML = out;
    Ответ написан
    5 комментариев
  • Как можно наиболее быстро искать данные по JSON файлу?

    @Interface
    Если у вас "json" это пришедший из postgress'овского jsonb поля - то postgress умеет делать запросы внутри jsonb: https://hackernoon.com/how-to-query-jsonb-beginner... (первая ссылка в гугле).

    Если такой вариант не подходит очевидная оптимизация - высунуть создание регэкспа из цикла. Хотя я не уверен, что какой-нить v8 это несоптимизировал самостоятельно. (на моей машине это сокращает время втрое примерно)

    Какой у вас объем данных? Поиск по множеству строк не должен занимать много времени. И пока у вас не миллионы этих строк все должно быть быстро. Эквивалентный код на моей машине выполняет проход регэкспом по массиву из миллиона строк менее чем за 100мс. Если у вас бОльшие объемы или хотя бы сопоставимые - вы что-то делаете не так :) Ну или если вы ожидаете обработку такого объема данных моментально, то стоит скорректировать ожидания.

    P.s. это нода или браузер? Если нода - то пляски на стороне js все равно не имеют смысл так как радикально ускорить не получится, а вот 2-3 пользователя ищущие что-то вам все положат.
    Ответ написан
  • Почему random не работает?

    @Interface
    if(x=input){
    ->
    if(x === input){

    И высуньте значение из массива, зачем вы его туда положили?
    Ответ написан
    Комментировать
  • Ключ в объекте в таком формате?

    @Interface
    Ключем в объекте может любая строка или Symbol (es6), все остальное будет приведено к строке. Если ваш ключ - строка, нет никаких проблем. Если хочется больше свободы или уверенности - используйте Map (es6), он умеет использовать объекты как ключи, например.
    Ответ написан
    2 комментария
  • Как задать задержку в цикле for?

    @Interface
    let $body = document.querySelector('body');
    let $bodyH = $body.clientHeight;
    let $bodyW = $body.clientWidth;
    
    function sleep(ms) {
    	return new Promise(resolve => setTimeout(resolve, ms));
    }
    
    async function main() {
    	let ask = prompt('How many circles you want to draw?');
    
      if (ask !== null || ask !== '') {
        for (let i = 0; i < ask; i++) {
          drowCircle(i);
          await sleep(1000);
        }
      }
    }
    
    main();
    
    function drowCircle(i) {
      let $circle = document.createElement('div');
      let $circleSize = getRand(50, 100);
      let positionX = getRand(0, $bodyW - $circleSize);
      let positionY = getRand(0, $bodyH - $circleSize);
    
      $body.insertAdjacentElement('afterbegin', $circle);
    
      $circle.style.width = $circle.style.height = `${$circleSize}px`;
      $circle.style.zIndex = i+1;
      $circle.style.backgroundColor = `rgb(${getRand(0,255)},${getRand(0,255)},${getRand(0,255)})`;
      $circle.style.borderRadius = '50%';
      $circle.style.position = 'absolute';
      $circle.style.top = `${positionY}px`;
      $circle.style.left = `${positionX}px`;
    }
    
    function getRand(min, max) {
      let rand = min - 0.5 + Math.random() * (max - min + 1);
      return Math.round(rand);
    }
    Ответ написан
    Комментировать
  • Почему puppeteer пишет, что node detached?

    @Interface
    Сама нода 100% есть, потому что если просто получать ее textContent, это работает.

    Это ошибочный вывод. textContent вполне работает с "виртуальной" нодой:
    const node = document.createElement('div');
    node.textContent = 'hello';
    console.log(node.textContent)
    Ответ написан
    Комментировать
  • Как узнать, что пользователь прокрутил страницу до нужного элемента на странице?

    @Interface
    Помимо того, что предложили другие пользователи. Можете попробовать https://developer.mozilla.org/en-US/docs/Web/API/I...

    Это вроде то что вам нужно, но не уверен насчет поддержки браузерами (подойдет ли вам такая)
    Ответ написан
    Комментировать
  • Как исключить дребезг живого поиска?

    @Interface
    Тут стоит использовать throttle или debounce
    https://lodash.com/docs/#throttle
    https://lodash.com/docs/#debounce

    Когда-то давно я писал маленькую библиотеку, которая как раз решает задачу с поиском. Я не то чтобы предлагаю ее использовать (хотя я был бы только рад :) ), но зато там есть демо, где иллюстрируется работа throttle: https://int0h.github.io/promise-decorators/
    Сама библиотека: https://github.com/int0h/promise-decorators
    Пример с поиском: https://github.com/int0h/promise-decorators/blob/g... (живьем есть на демо странице)

    Еще хорошая иллюстрация есть в rxmarbles: https://rxmarbles.com/#debounce
    (можно это же решать rx'ом)
    Ответ написан
    2 комментария
  • Можно ли написать функцию, которая проверяет существует ли переменная или нет (js)?

    @Interface
    Дисклеймер: так как вопрос скорее теоретический, я не стараюсь предоставить "адекватное" решение.
    Конечно, все это нельзя использовать в реальном проекте!


    Интересный вопрос.

    Начнем с того, что определимся насколько критично сохранить сигнатуру функции? В зависимости от этого, решения можно поделить на 2 категории:
    - где допускается изменение сигнатуры
    - где сигнатура должна быть строго такой и никакой иначе

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

    Стоит оговориться, что строго говоря такую функцию в данном виде написать нельзя, потому как при вызове функции переменная уже должна быть "разименована", а значит мы так или иначе будем работать с ее значением или с какими-то косвенными сайд эффектами вызванными обращением к ней.


    Сначала рассмотрим несколько решений с изменением сигнатуры: они попроще и в каком-то смысле более логичны.

    есть как минимум 2 категории решений с изменением сигнатуры:
    - функция будет принимать строку
    - функция будет принимать функцию

    При этом проблема того, что все падает до попадания в функцию, пропадает сама собой.

    вот несколько решений:

    1) класс решений построенный на анализе кода в рантайме:
    решение заключается в том, что вызываемая функция анализирует свой код (а также код функции которая вызвала ее и т.д.)
    https://stackoverflow.com/questions/2051678/gettin... вот тут есть частчный разбор такого решения.
    Приводить его в виде кода я не буду :)

    Плюсы:
    - вроде как решает задачу
    - сигнатура изменилась не сильно
    Минусы:
    - крайне жирное решение с точки зрения производительности
    - сигнатура не та, что просили
    - нельзя использовать 'use strict', так как решения возможно будут завязаны на arguments.callee.caller

    Уровень безумия: достаточно безумное

    2) решение построенное на том, что приниматься будет функция:
    isExists(() => someVar); // такая будет сигнатура

    Это решение хоть и меняет сигнатуру, но ее возможно сохранить максимально подобной желаемой

    Одна из возможных реализаций:
    function isExists(someVarFn){
        try {
            someVarFn();
        } catch(e) {
            if (e instanceof ReferenceError) {
                return false;
            }
            throw e;
        }
        return true;
    }

    Примеры использования:
    function f1() {
        let x;
        console.log(isExists(() => x)); //  => true
        console.log(isExists(() => y)); //  => false
    }
    
    function f2() {
        let x;
        console.log(isExists(() => x)); //  =>  true
        console.log(isExists(() => y)); //  => false
    }
    
    f1();
    f2();


    Плюсы:
    - плюс-минус адекватная производительность
    - довольно компактно
    Минусы:
    - несильно меняется сигнатура функции
    - api получается несколько не очевидным

    Уровень безумия: почти адекватное

    3) решения с использованием eval:
    Суть похожа на решение #2, но с другим api:
    function isExists(varName, fn){
        return fn(`(()=>{
            try {
                const nop = ${varName};
            } catch(e) {
                if (e instanceof ReferenceError) {
                    return false;
                }
                throw e;
            }
            return true;
        })()`);
    }
    
    function f1() {
        let x;
        console.log( isExists('x', c => eval(c)) ); //  => true
        console.log( isExists('y', c => eval(c)) ); //  => false
    }
    
    function f2() {
        let y;
        console.log( isExists('x', c => eval(c)) ); //  =>  false
        console.log( isExists('y', c => eval(c)) ); //  => true
    }
    
    f1();
    f2();


    Плюсы:
    - сложнее чем в №2 передать какую-то фигню
    Минусы:
    - сигнатура отлиается сильнее и уродливей
    - сложнее / жирнее / больше чем №2

    Уровень безумия: безумненько

    Решения с сохранением сигнатуры:

    4) магия es6 Proxies + with
    класс решений строится на стратегии: слушать доступ к глобальному объекту и если он происходит и в нем нет переменной с таким именем - такой переменной нет:
    const pseudoUndefined = {};
    
    const scopeTrap = new Proxy(window, {
        has() {return true},
    
        get(target, prop) {
            if (prop in window) {
                return window[prop];
            } else {
                return pseudoUndefined;
            }
        }
    })
    
    function isExists(someVar) {
        return someVar !== pseudoUndefined;
    }
    
    // весь код использующий функцию должен быть обернут в такой with :(
    with (scopeTrap) {
    
        let y;
        console.log( isExists(x) ); //  =>  false
        console.log( isExists(y) ); //  => true
    
    }


    Плюсы:
    - мы сохранили желаемую сигнатуру! Ура!
    Минусы:
    - теперь вместо исключения будет получаться что-то совсем левое. Хорошего дебагга! :D
    - накладные расходы производительности
    - все нужно обернуть в with
    - необходима поддержка es6+

    Уровень безумия: с точки зрения реализации - задача подъемная. использовать в бою - а вы знаете толк!

    Решения с предобработкой:

    Первые две категории решений исходят из того, код (включая код вызовов функции) будет исполняться без изменений напряму интерпретатором. Если развязать себе руки, то открывается целый спектр новых решений:

    5) первое, что приходит в голову с приобретением такой свободы - это, очевидно... написание своего языка программирования компилируемого в js / своего интерпретатора js и т.д.
    В рамках этого решения особого труда (относительно всего прочего) не составит реализовать такую функцию нативно.

    Плюсы: ...
    Минусы: ...
    (Без комментариев)

    Уровень безумия: я думаю все понятно
    ...

    есть и более сдержанные решения, например, используя compile-time можно оптимизировать предыдущие решения:

    6) можно используя парсер составить дерево областей видимости (хэш-таблица [функция <-> список переменных]), привязать каждую область к функции, через позицию в исходном коде (возможно придется сохранять дополнительную информацию). А дальше все это интегрировать с решением №1.

    В итоге:

    Плюсы относительно (#1):
    - относительно хорошая производительность
    Минусы:
    - сложно
    - дорого
    - требует compile-time

    Уровень безумия: стало еще безумнее, чем было :)

    7) написать (или найти) плагин для babel'я (или чего-то другого), который будет трансформировать доступ к переменным в особую функцию

    Плюсы относительно (#1):
    - достигнут результат
    Минусы:
    - требует поддержки
    - требует compile-time
    - упадет производительность (вероятнее всего существенно)

    Уровень безумия: буднечно безумное
    Ответ написан
    3 комментария
  • Почему я не могу получить ответ на запрос к удаленному источнику?

    @Interface
    "Access-Control-Allow-Origin": "*"
    это должно быть в заголовках ответа, а не запроса
    Ответ написан
    Комментировать
  • Как вывести результат асинхронной функции во внешнюю переменную?

    @Interface
    Вас спасет async/await!
    Почитать можно тут https://habr.com/ru/company/ruvds/blog/326074/, например
    Ответ написан
    Комментировать
  • Отвратительный лог ошибок в nuxt?

    @Interface
    Вам нужно настроить source-maps, почитайте как это сделать в вашей среде.
    Для webpack можно тут, например, почитать https://survivejs.com/webpack/building/source-maps/

    Source-map как раз и позволяет получать адекватные stack-trace'ы и вообще крайне полезная вещь для отладки
    Ответ написан
    Комментировать
  • Как переписать функцию map js для возможности использования в ie11?

    @Interface
    Вы используете es6. => ` вот это все. Это синтаксис - полифил не поможет.

    Вставьте код сюда: https://babeljs.io/repl/
    бабель его преобразует к es5, например.

    Почитайте про: es5, es6 (es2015), babel, транспайлеры, отличия между транспайлером и полифилом
    Ответ написан
    3 комментария
  • Как правильно разделить массив?

    @Interface
    lodash хорошо решает эту задачу, посмотрите метод partition: https://lodash.com/docs/4.17.11#partition

    const arr = {
      list: [
        {id: 1, pos: {dv: "T5"}},
        {id: 2, pos: {dv: "T10"}},
        {id: 3, pos: {dv: "T12"}},
        {id: 4, pos: {dv: "T11"}},
        {id: 5, pos: {dv: "T45"}},
        {id: 6, pos: {dv: "T56"}},
        {id: 7, pos: {dv: "T38"}},
        {id: 8, pos: {dv: "T-9"}},
        {id: 9, pos: {dv: "T0"}}
      ]
    };
    
    _.partition(arr.list, obj => Number(obj.pos.dv.slice(1)) >= 38)
    Ответ написан
  • Почему регулярка быстрее indexOf?

    @Interface
    Прежде всего нужно понять - действительно ли быстрее?

    Есть замечательный доклад на эту тему: https://www.youtube.com/watch?v=HPFARivHJRY - очень рекомендую к просмотру.

    На вскидку:
    - движок может выкидывать тот или иной кусок бенчмарка
    - движок может реализовывать какой-либо кэш и считать один раз

    P.s. в мозиле результаты другие: победил lodash, что иронично потому что у него под капотом indexOf
    Ответ написан
    4 комментария
  • Как уменьшить значение типа #cef1ff?

    @Interface
    Как вариант решения с обработкой переполнения разрядов и трехсимвольных цветов
    function hexToTriple(hex) {
        hex = hex.slice(1);
        if (hex.length === 3) {
            return hex.split('').map(byte => parseInt(byte.repeat(2), 16));
        } else if (hex.length === 6) {
            return hex.match(/.{2}/g).map(byte => parseInt(byte, 16));
        } else {
            throw new Error(`invalid color ${hex}`);
        }
    }
    
    function tripleToHex(triple) {
        return '#' + triple.map(byte => byte.toString(16).padStart(2, '0')).join('');
    }
    
    function hexColorSubtract(hexAColor, hexBColor) {
        const [tripleA, tripleB] = [hexAColor, hexBColor].map(hexToTriple);
        const resultTriple = tripleA.map((byte, index) => {
            return Math.max(byte - tripleB[index], 0);
        });
        return tripleToHex(resultTriple);
    }
    
    // использование:
    
    hexColorSubtract("#cef", "#110011"); // #bbeeee
    Ответ написан
    Комментировать
  • Как поменять тег src у img?

    @Interface
    vadimkravchenko0, проблема в том, что вы обратились не совсем на тот ресурс. Точнее скорее всего нужного вам ресурса просто нет. Потому что все вопросы и проблемы можно условно разделить на 2 категории:
    - общие вопросы
    - конкретные задачи

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

    Ваша проблема индивидуальна, а значит ответ на нее будет в большей части бесполезен для любого другого пользователя. Поэтому всегда полезнее выразить свой вопрос так, чтобы он помог решить кому-то еще похожую (а не точно такую же) проблему. Но если вы его сформулируете в общем виде - ответ будет слишком простым и его действтельно легко найти.

    У вас есть 2 пути:
    - разбираться самостоятельно, изучая материалы и т. д. (тогда забудьте про "Но я совсем чайник в кодах, мне это и не нужно.")
    - либо обратиться на фриланс (это может быть и друг, который шарит и может помочь за шоколадку)

    Если я правильно понял проблему, вам должен помочь user-script. Установите себе greasemonkey (расширение браузера), например. И напишите и добавьте туда свой user-script. Скрипт вам уже написал Johnny Lowhunter

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

    К сожалению, вряд-ли получится это все решить не вникая в вопрос. Так что, если вы хотите сделать это сами - изучите js немного хотя бы. Если хотите решить конкретную задачу - то это запрещено правилами строго говоря.
    Ответ написан
    Комментировать