Ответы пользователя по тегу JavaScript
  • Как нарисовать квадрат & треугольник?

    Seasle
    @Seasle Куратор тега JavaScript
    Это, наверное, лучший вопрос. Итак, краткий экскурс. Для того, чтобы нарисовать фигуру нам понадобятся всего две математические функции: sin и cos. А ещё будет неплохо вспомнить, какие числа в какой четверти круга они возвращают:
    609108ca255c2738240894.png
    Следовательно, sin(x) вернёт числа больше или равные нулю в четверти 1 и 2 (от 0° до 180°); cos(x) вернёт числа больше или равные нулю в четверти 3 и 1 (от 270° до 90°). Итак, для того чтобы нарисовать квадрат, необходимо всего 4 точки, а для треугольника - 3 (внезапно). Для квадрата нам надо разделить 360° на 4 равные части (то бишь по 90°).

    Однако, если у вопроса тэг JavaScript, я подозреваю, что надо бы действовать по-другому. Для начала вспомнить, чем радианы отличаются от градусов, дам подсказку - 1 радиан равен числу Пи, и одновременно равен 180°. Следовательно, делить мы будем уже не градусы, а радианы (потому что в JavaScript'е математические функции синуса и косинуса работают именно с ними). Поделив нужное количество радиан на 4 части, мы получим шаг угла квадрата. Значит циклом в 4-е шага можно получить все координаты, однако - всё не так просто.

    Надо ещё вспомнить, что синус и косинус возвращают числа от [-1; 1], а это значит, что квадрат будет очень маленьким, если мы впишем его в окружность, радиусом 1. Для решения уже этой проблемы, умножим полученное значение синуса и косинуса на радиус, к примеру на 100.

    Теперь при помощи цикла (сколько точек у фигуры, столько и итераций) мы можем получить все точки для координаты x (косинус) и для координаты y (синус), после чего последовательно соединить, получив квадрат.

    Если мы хотим повернуть квадрат, к примеру на 45°, то снова превращаем градусы в радианы и прибавляем к радианам в синусе и косинусе в тот момент, когда высчитываем координаты точек.

    Ну а для треугольника (и вообще любой фигуры, которую можно вписать в окружность) алгоритм действий отличается только количеством итераций.
    Ответ написан
    2 комментария
  • Что такое литерал объекта?

    Seasle
    @Seasle Куратор тега JavaScript
    Это вот это.
    {} // литерал объекта
    [] // литерал массива
    '' // литерал строки
    "" // тоже литерал строки
    `` // ещё один литерал строки
    /./ // литерал регулярного выражения (конкретно для примера - любого символа)
    Ответ написан
    Комментировать
  • Как использовать цикл for внутри данной конструкции?

    Seasle
    @Seasle Куратор тега JavaScript
    let text = '<p>1</p><p>2</p>';
    for (let i in lol) {
        text += '<p>' + i + '</p>'; // `text += <p>${i}</p>`;
    }
    Ответ написан
    Комментировать
  • Цепочка DOM запросов jquery?

    Seasle
    @Seasle Куратор тега JavaScript
    $('.some_class .just_child').first().find('li');
    Ответ написан
    2 комментария
  • Как выбрать рандомные призы из массива?

    Seasle
    @Seasle Куратор тега JavaScript
    const pick = (items) => {
      const filteredItems = items.filter(item => item.count > 0);
      const total = filteredItems.reduce((acc, item) => acc + item.count, 0);
      if (total === 0) {
        return null;
      }
      
      const pickedChance = Math.random();
      let storedChance = 0;
      
      for (const item of filteredItems) {
        storedChance += item.count / total;
        
        if (pickedChance < storedChance) {
          item.count -= 1;
          return item.name;
        }
      }
    }
    
    pick(items);
    Ответ написан
  • Как заменить определённые символы на странице?

    Seasle
    @Seasle Куратор тега JavaScript
    Если речь идёт о том, что в realtime надо менять на уже существующей странице, то так:
    const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
    const expression = /[-–—]/g;
    
    while (walker.nextNode()) {
      const node = walker.currentNode;
    
      if (expression.test(node.textContent)) {
        node.textContent = node.textContent.replace(expression, '-');
      }
    }

    Ответ написан
    Комментировать
  • Почему метод Number() начинается с большой буквы в javascript?

    Seasle
    @Seasle Куратор тега JavaScript
    Потому что это не метод, а класс (прототип). Также существуют: String, Boolean, Object, Array. При вызове классов Number, String, Boolean без оператора new они постараются привести переданное значение к примитиву (например String(true) // "true". В том случае, если их вызвать с оператором new, то они вернут новый объект (не путать с Object), значением в котором будет переданное значение. Лучше так не создавать переменные данных классов, а использовать примитивы (об этом можете почитать в книге Стоян Стефанов - JavaScript Шаблоны). У Object особое поведение при его вызове без new - он постарается понять тип переменной и впоследствии вернет экземпляр класса определенного примитива:
    Object(100) // Number { 100 }
    typeof Object(100) // "object"
    typeof 100 // "number"
    Object(100) instanceof Number // true
    100 instanceof Number // false

    Вызов класса Array без ключевого слова new или с ним:
    с 1 аргументом - вернет пустой массив, длиной равной переданному аргументу;
    с 2 и более аргументами - вернет массив значений.
    Ответ написан
    Комментировать
  • Почему по клику на кнопку download нужная картинка загружается только со второго раза?

    Seasle
    @Seasle Куратор тега JavaScript
    Потому что изображение на canvas'е будет готово после загрузки изображения.
    Вариант 1 - функция обратного вызова

    function drawImage(callback) {
      const img = new Image();
      img.setAttribute('crossOrigin', 'anonymous');
      if (currentImg.src) {
        console.log(1);
        img.src = currentImg.src;
      } else {
        console.log(2);
        img.src = currentImage.src;
      }
    
      img.onload = function() {
        canvas.width = img.width;
        canvas.height = img.height;
        const ctx = canvas.getContext("2d");
        ctx.filter = canvasFilter;
        ctx.drawImage(img, 0, 0);
    
        callback();
      };
    }
    
    download.addEventListener('click', function(e) {
      drawImage(function () {
        console.log(canvas.toDataURL());
        const dataURL = canvas.toDataURL("image/jpeg");
        let link = document.createElement('a');
        link.download = 'download.png';
        link.href = dataURL;
        link.click();
      });
    });


    Вариант 2 - promis'ы

    function drawImage(callback) {
      return new Promise(function (resolve) {
        const img = new Image();
        img.setAttribute('crossOrigin', 'anonymous');
        if (currentImg.src) {
          console.log(1);
          img.src = currentImg.src;
        } else {
          console.log(2);
          img.src = currentImage.src;
        }
    
        img.onload = function() {
          canvas.width = img.width;
          canvas.height = img.height;
          const ctx = canvas.getContext("2d");
          ctx.filter = canvasFilter;
          ctx.drawImage(img, 0, 0);
    
          resolve();
        };
      });
    }
    
    download.addEventListener('click', function(e) {
      drawImage().then(function () {
        console.log(canvas.toDataURL());
        const dataURL = canvas.toDataURL("image/jpeg");
        let link = document.createElement('a');
        link.download = 'download.png';
        link.href = dataURL;
        link.click();
      });
    });
    // или
    download.addEventListener('click', async function(e) {
      await drawImage();
      console.log(canvas.toDataURL());
      const dataURL = canvas.toDataURL("image/jpeg");
      let link = document.createElement('a');
      link.download = 'download.png';
      link.href = dataURL;
      link.click();
    });

    Ответ написан
    Комментировать
  • Не работает код по решению квадратных уравнений. Что не так с дискриминантом?

    Seasle
    @Seasle Куратор тега JavaScript
    Во-первых: не Math.round(((b ** 2) - 4 * a * c) ** 1/2); а ((b ** 2) - 4 * a * c) ** (1 / 2);.
    Во-вторых: тут какой-то бред описан:
    if (b => 1, c => 1) {
      b = "+ " + b
      c = "+ " + c
    }

    В условии Вы создаете 2 функции, причём проверите только последнюю. Меняете на
    let stringifiedB = b >= 0 ? `+ ${b}` : `- ${Math.abs(b)}`;
    let stringifiedC = c >= 0 ? `+ ${c}` : `- ${Math.abs(c)}`;
    
    console.log(`${a}х² ${stringifiedB}x ${stringifiedC} = 0`);


    На счет знака запятой в различных условиях, будет использован только самый последний.
    if (false, true) {
      console.log(1);
    } else {
      console.log(2);
    }
    // 1
    
    if (false, true, false) {
      console.log(1);
    } else {
      console.log(2);
    }
    // 2

    А функция в условии всегда будет выполнять if-блок.
    Ответ написан
  • Jquery как правильно написать конструкцию if(this).hasclass?

    Seasle
    @Seasle Куратор тега JavaScript
    - if $(this).hasClass("catalog-button_active") {
    + if ($(this).hasClass("catalog-button_active")) {
    Ответ написан
    1 комментарий
  • Как отличить класс от объекта?

    Seasle
    @Seasle Куратор тега JavaScript
    class Example {
      constructor() {}
    }
    
    const entries = [
      new Example(),
      {},
      new Object(),
      [],
      new Array(),
      42,
      'Hello World',
      true,
      null,
      undefined
    ];
    
    entries.forEach((entry, index) => {
      if (entry instanceof Example) {
        console.log(`is example - ${index}`);
      } else if (entry instanceof Array) {
        console.log(`is array - ${index}`);
      } else if (entry instanceof Object) {
        console.log(`is object - ${index}`);
      } else {
        console.log(`is ${typeof entry} - ${index}`)
      }
    });
    /*
    is example - 0
    is object - 1
    is object - 2
    is array - 3
    is array - 4
    is number - 5
    is string - 6
    is boolean - 7
    is object - 8
    is undefined - 9
    */
    Ответ написан
    Комментировать
  • Как просуммировать элементы массива, расположенные до нуля?

    Seasle
    @Seasle Куратор тега JavaScript
    let numbers = [1, 2, 3, 0, 4, 5, 6];
    let sum = 0;
    for (let i = 0; i < numbers.length; i++) {
      if (numbers[i] > 0) {
        sum += numbers[i];
      } else {
        break;
      }
    }
    console.log(sum);

    Первая ошибка - куда будете сохранять результат суммы? В индекс массива не пойдет.
    Вторая ошибка - <=. Как только проитерируется весь массив - цикл не будет завершен, а при попытке достать элемент (а мы уже всё проитерировали) Вы рискуете получить NaN.
    Третья ошибка - условие i < 0. Тут сразу две ошибки: не i а b[i]; и не <, а ===. Если оставить меньше нуля, то даже при достижении элемента равному нулю цикл не будет остановлен.
    Ответ написан
    Комментировать
  • Как изменять значения в объекте класса через input?

    Seasle
    @Seasle Куратор тега JavaScript
    Надо отслеживать изменения в input'е.
    - let val = document.querySelector('#changer').value;
    + let val = document.querySelector('#changer');

    let el = document.createElement('h3');
    let cont = document.querySelector('#box');
    t.addEventListener('input', () => {
        el.textContent = t.value;
    });
    el.textContent = t.value;
    cont.append(el);
    Ответ написан
    Комментировать
  • Как обновлять url в адресной строке или что делать?

    Seasle
    @Seasle Куратор тега JavaScript
    Если Вы хотите сделать что-то похожее на SPA (Single Page Application), то для начала Вам надо научить сервер отдавать всегда index.html. Следующий шаг - History API, это пригодится для подмены URL и генерации Ваших ссылок. А для того чтобы загрузить необходимое содержимое необходимо будет проанализировать location.pathname и отобразить необходимую информацию (как будто Вы нажали на элемент меню).
    Второй вариант попроще - использовать location.hash для хранения уникального URL, загружать будете также как в первом варианте.
    Ответ написан
    8 комментариев
  • Как исправить ошибку с таймером?

    Seasle
    @Seasle Куратор тега JavaScript
    useEffect(() => {
        let intervalId = setInterval(async () => {
            const response = await fetch('http://127.0.0.1:8000/api/timecalculate', {
                method: 'PUT',
                headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest' },
                credentials: 'include',
            });
            const content = await response.json();
            const now = new Date();
    
            console.log(content + now);
        }, 10000)
    
        return () => {
            clearInterval(intervalId);
        };
    }, []);

    UPD: https://codesandbox.io/s/qna-q969499-m7b1n
    Ответ написан
    Комментировать
  • Почему выдаёт ошибку Uncaught TypeError: ctx.clearRect is not a function?

    Seasle
    @Seasle Куратор тега JavaScript
    window.requestAnimationFrame(draw.bind(null, ctx));

    либо выносите контекст глобально либо в модуль.
    Ответ написан
    2 комментария
  • Почему после смены option не присваивается selected?

    Seasle
    @Seasle Куратор тега JavaScript
    document.querySelector('#test_id').value
    или
    document.querySelector('#test_id').selectedIndex
    или
    document.querySelector('#test_id').selectedOptions
    Ответ написан
    2 комментария
  • Как узнать что ввел пользователь в input вначале?

    Seasle
    @Seasle Куратор тега JavaScript
    input.value.trim().startsWith('value')
    Ответ написан
    Комментировать
  • Как переписать XMLHttpRequest в fetch?

    Seasle
    @Seasle Куратор тега JavaScript
    fetch('https://test-test.com/sub?channel=system:fb:advc')
      .then(response => {
        if (response.status >= 200 && response.status < 400) {
          return response.json();
        } else {
          return Promise.reject();
        }
      })
      .then(data => {
        console.log(data);
      })
      .catch(error => {
        console.log(error);
      });
    Ответ написан
  • Почему блок не меняет цвет?

    Seasle
    @Seasle Куратор тега JavaScript
    Во-первых, если подключаете скрипт не перед закрытием body, то поместите его туда.
    Во-вторых, document.getElementsByClassName возвращает HTMLCollection - массив, который будет автоматически изменять свое содержимое при изменениях на странице. Поэтому, либо берете из него первый элемент, либо используете document.querySelector.

    Также, неплохо было бы проверять элементы, прежде чем добавлять им события; вместо onevent использовать element.addEventListener('event', handler);; вместо == использовать ===; вместо style.backgroundColor использовать style.setProperty('background-color', value);.
    Ответ написан
    2 комментария