Почему fetch будет выполняться только тогда, когда его нет в функции?

Я только изучаю вызов Javascript/API, и у меня проблемы с выборкой. Когда я вызываю функцию выборки из myFunction, она ничего не делает (что я вижу), но если я уберу ее из myFunction, она отобразит ожидаемое сообщение об ошибке.

Я пытался использовать Google, но я не нашел ничего, что помогло бы мне. Я добавил операторы console.info, чтобы убедиться, что функция вызывается, и это так.

Я попытался убрать оператор fetch из функции и вместо этого просто поместить его в виде скрипта в html-файл. Тогда это работает нормально. Однако я хочу вызвать его, используя имя функции, которая находится в файле javascript, и я хотел бы понять, почему сейчас она работает неправильно. Я думаю, что это как-то связано с тем, что выборка не возвращается до выхода из функции, но я не уверен.

функция JavaScript:

function myFunction(){


    fetch('https://sickw.com/api.php?format=html&key=SOME_KEY&imei=12908438754328705&service=999999')
      .then(response => response.text())
      .then(data => {
        //document.write(data)
        console.info(data)
      });

    //make sure the function was called
    console.info("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
}

html-код:

<!DOCTYPE html>
<html lang = "en">

<head>
  <meta charset = "utf-8" />
  <meta name = "viewport" content = "width=device-width, initial-scale=1.0" />

  <title>Ghibli App</title>

  <link href = "https://fonts.googleapis.com/css?family=Dosis:400,700" rel = "stylesheet" />
  <link href = "style.css" rel = "stylesheet" />
</head>

<body>
  <div id = "root"></div>

  <form>
    <select id = "carrier">
      <option value = "carrier">Carrier</option>
      <option value = "icloud">iCloud</option>
    </select>
    <button onClick = "myFunction('carrier');">Submit</button>"
  </form>

  <script src = "scripts.js"></script>
</body>

</html>

Я ожидаю, что появится страница с надписью «Ошибка S01: неверный идентификатор службы!» однако страница вообще не меняется, когда я вызываю код из myFunction().

Вам нужно остановить отправку формы.

SLaks 13.05.2019 20:57

Вы должны изменить свой ключ API

SLaks 13.05.2019 20:58

Не используйте document.write() после загрузки страницы. stackoverflow.com/questions/802854/…

Barmar 13.05.2019 21:01

Я бы даже сказал, что просто не используйте document.write().

Patrick Roberts 13.05.2019 21:07
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
4
93
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Почему вы ничего не видите:

Проблема не в том, что вы вызываете fetch из функции, а в том, что вы вызываете эту функцию внутри onclick кнопки в форме.

Когда вы помещаете элемент <button> внутрь элемента <form>, его поведение по умолчанию — отправка формы (публикация результатов на другой веб-странице и загрузка этой новой страницы в браузере). Поскольку в вашей форме нет атрибута action, она просто перезагрузит текущую страницу. Эта перезагрузка текущей страницы приводит к тому, что вы не видите никаких результатов.

Исправление проблемы первый:

Чтобы форма не возвращалась, вам нужно вызвать preventDefault() событие, переданное вашей функции:

function myFunction(event){
    event.preventDefault();

    fetch('https://sickw.com/api.php?format=html&key=SOME_KEY&imei=12908438754328705&service=999999')
      .then(response => response.text())
      .then(data => {
        //document.write(data)
        console.info(data)
      });

    //make sure the function was called
    console.info("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
}

Второй выпуск

Однако из-за того, как вы вызываете эту функцию (передавая ее методу onclick элемента HTML), у вас нет доступа к этому событию. Чтобы исправить это, вы должны использовать метод addEventListener следующим образом:

document.getElementsByTagName("button")[0].addEventListener("click", myFunction);

Если вы дадите кнопке идентификатор, его можно заменить на:

document.getElementById("button-id").addEventListener(...)

Третий выпуск

Вы передаете 'carrier' прямо в свою функцию, но я предполагаю, что вы хотите прочитать значение из элемента <select>. Для этого вы должны использовать document.getElementById и .value, чтобы прочитать выбор:

var carrier = document.getElementById("carrier").value;

Как только вы это сделаете, вы можете использовать carrier в своем fetch запросе.

Четвертый выпуск

Как уже упоминалось в комментариях, вам следует избегать звонков на document.write. Написаны книги о том, почему это плохо, но правильный ответ — использовать DOM API для изменения элементов на странице. Например:

var p = document.createElement("p");
p.innerHTML = data;
document.appendChild(p);

Окончательный код

index.html

<!DOCTYPE html>
<html lang = "en">

<head>
  <meta charset = "utf-8" />
  <meta name = "viewport" content = "width=device-width, initial-scale=1.0" />

  <title>Ghibli App</title>

  <link href = "https://fonts.googleapis.com/css?family=Dosis:400,700" rel = "stylesheet" />
  <link href = "style.css" rel = "stylesheet" />
</head>

<body>
  <div id = "root"></div>

  <form>
    <select id = "carrier">
      <option value = "carrier">Carrier</option>
      <option value = "icloud">iCloud</option>
    </select>
    <button id = "button-id">Submit</button>"
  </form>

  <script src = "scripts.js"></script>
</body>

</html>

script.js

function myFunction(event){
    event.preventDefault();
    var carrier = document.getElementById("carrier").value;
    fetch('https://sickw.com/api.php?format=html&key=SOME_KEY&imei=12908438754328705&service=999999&carrier=' + carrier)
      .then(response => response.text())
      .then(data => {
          var p = document.createElement("p");
          p.innerHTML = data;
          document.appendChild(p);
      });
}

document.getElementById("button-id").addEventListener("click", myFunction);

Спасибо за помощь! Что касается проблемы № 2, вы говорите, что я должен использовать addEventListener вместо onClick, чтобы я мог получить доступ к событию?

Sam Ventocilla 15.05.2019 20:56

@SamVentocilla Совершенно верно. Вместо использования HTML-атрибута onclick, если вы используете метод addEventListener JavaScript, ваша функция будет автоматически вызываться с событием в качестве первого параметра, который вы можете использовать для предотвращения поведения события по умолчанию (отправки формы). Мне нужно проверить это, чтобы быть уверенным, но я думать в качестве обходного пути, вы можете использовать атрибут HTML onclick и вернуть свою функцию false. В любом случае использование addEventListener считается лучшей практикой, поскольку оно отделяет ваш код от вашего представления.

stevendesu 15.05.2019 20:59

Другие вопросы по теме