使用onClick函数无法获取AJAX输出

时间:2019-02-16 16:27:03

标签: javascript html css ajax

我对AJAX非常陌生,并且刚刚开始讨论这个主题。我有这个XML文件,应该使用AJAX调用来显示所需的信息。我将所有标记元素解析为相应的javascript代码,但是当我按下按钮时,即使我只想显示XML文件的标题,也无法显示我想要的内容。下面的屏幕快照显示了预期的输出。

function makeAjaxQueryWeather(){
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
    myFunction(this);
    }
  };
  xhttp.open("GET", "A8.xml", true);
  xhttp.send();
}

// handler for the readyState change
function readyStateChangeHandler(xhttp){

  if (xhttp.readyState == 4){
    // readyState = 4 means DONE

    if(xhttp.status == 200){
      // status = 200 means OK

      handleStatusSuccess(xhttp);

    }else{
      // status is NOT OK

      handleStatusFailure(xhttp);

    }
  }

}

// XMLHttpRequest failed
function handleStatusFailure(xhttp){

  // display error message

  var displayDiv = document.getElementById("display");

  displayDiv.innerHTML = "XMLHttpRequest failed: status " + xhttp.status;
}

// XMLHttpRequest success
function handleStatusSuccess(xhttp){

  var xml = xhttp.responseXML;

  // parse the XML into an object
  var weatherObj = parseXMLWeather(xml);

  // display the object on the page
  displayWeather(weatherObj);
}

// parse the XML into an object
function parseXMLWeather(xml){

  // print XML on the console
  // console.log(xml);

  //create an object to hold the information in the xml file
  var weatherObj = {};
  
  // get the forecast XML element
  var forecastElement = xml.getElementsByTagName("forecast")[0];
  // get the query location
  weatherObj.queryLocation = forecastElement.getAttribute("queryLocation");
  // get the query time
  weatherObj.queryTime = forecastElement.getAttribute("queryTime");
  
  //get the weather XML element
  var weatherElementList = xml.getElementsByTagName("weather")[0];
  weatherObj.YYYYMMDD = weatherElementList.getAttribute("yyyymmdd");
  
  //get the rest of the child XML element in weather
  weatherObj.list = [];
  for(var i=0; i < weatherElementList.length; i++) {
  
    var weatherElement = weatherElementList[i];
	
	var weather1Obj = parseWeatherElement(weatherElement);
	
	weatherObj.list.push(weather1Obj);
  
  }
  return weatherObj;
  
}

// parse a stock XML element into a JavaScript stock object
function parseWeatherElement(weatherElement) {
    var weather1Obj = {};
	
	//get all elements
	var yearElement = weatherElement.getElementsByTagName("year")[0];
	weather1Obj.year = yearElement.textContent;
	var monthElement = weatherElement.getElementsByTagName("month")[0];
	weather1Obj.month = monthElement.textContent;
	var dateElement = weatherElement.getElementsByTagName("date")[0];
	weather1Obj.date = dateElement.textContent;
	var dayOfWeekElement = weatherElement.getElementsByTagName("dayOfWeek")[0];
	weather1Obj.dayOfWeek = dayOfWeekElement.textContent;
	var overallElement = weatherElement.getElementsByTagName("overall")[0];
	weather1Obj.overall = overallElement.textContent;
	var highestElement = weatherElement.getElementsByTagName("highest")[0];
	weather1Obj.highest = highestElement.textContent;
	var lowestElement = weatherElement.getElementsByTagName("lowest")[0];
	weather1Obj.lowest = lowestElement.textContent;
	
	return weather1Obj;

}

// display the weather object on the page
function displayWeather(weatherObj){
  // print the weatherObj on the console
  // console.log(weatherObj);

  // construct HTML code to display weather information
  var html = "<h1>" + weatherObj.queryLocation + weatherObj.queryTime "</h1>";
  html = html + weatherObj.yyyymmdd;

  // show the constructed HTML code in the display div
  var displayDiv = document.getElementById("display");
  displayDiv.innerHTML = html;
}
<h1>Part 2</h1>
<button onClick="makeAjaxQueryWeather()">
Click here to view weather forecast 1
</button>
<br/> <br/>
<div id="display">
</div>

Expected output

这是XML文件: XML file

2 个答案:

答案 0 :(得分:0)

将显示功能更改为以下代码并检查。

function displayWeather(weatherObj){
  // print the weatherObj on the console
  // console.log(weatherObj);

  // construct HTML code to display weather information
  var html = `<h1>${weatherObj.queryLocation + weatherObj.queryTime}</h1><span>${weatherObj.yyyymmdd}</span>`;
  // show the constructed HTML code in the display div
  var displayDiv = document.getElementById("display");
  displayDiv.insertAdjacentHTML('afterbegin',html);
}

答案 1 :(得分:0)

您需要使用DOMParser()将XML字符串解析为正确的XML DOM文档:

类似这样的东西:

// Convert XML string to proper XML DOM document.
function parseXML(xmlString) {
  return new window.DOMParser().parseFromString(xmlString, "text/xml");
}

然后,您可以从XMLHttpRequest函数正确解析XML字符串内容,该函数返回XML字符串。

以上功能必须在此功能中实现:

// XMLHttpRequest success
function handleStatusSuccess(xhttp) {
  var xml = xhttp.response; // Change to xhttp.response.
  xml = parseXML(xml); // Call the parseXML function here, where xml parameter is a string.

  // parse the XML into an object
  var weatherObj = parseXMLWeather(xml);
  // display the object on the page
  displayWeather(weatherObj);
}

最后一个更改是在其中

var html = "<h1>" + weatherObj.queryLocation + " " + weatherObj.queryTime + "</h1>";
html += weatherObj.YYYYMMDD; // Use weatherObj.YYYYMMDD.

然后,您得到了这样的内容:

function makeAjaxQueryWeather() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      readyStateChangeHandler(this);
    }
  };
  xhttp.open("GET", "https://gist.githubusercontent.com/dannyjhonston/e56a6461d88ebd43d039bac215fa4eb4/raw/af9b5883d35097e8a8a68b619c3b0a9f7a51dc7d/A8.xml", true);
  xhttp.send();
}

// handler for the readyState change
function readyStateChangeHandler(xhttp) {
  if (xhttp.readyState == 4) {
    // readyState = 4 means DONE
    if (xhttp.status == 200) {
      // status = 200 means OK
      handleStatusSuccess(xhttp);
    } else {
      // status is NOT OK
      handleStatusFailure(xhttp);
    }
  }
}

// XMLHttpRequest failed
function handleStatusFailure(xhttp) {
  // display error message
  var displayDiv = document.getElementById("display");
  displayDiv.innerHTML = "XMLHttpRequest failed: status " + xhttp.status;
}

// XMLHttpRequest success
function handleStatusSuccess(xhttp) {
  var xml = xhttp.response;
  xml = parseXML(xml);

  // parse the XML into an object
  var weatherObj = parseXMLWeather(xml);
  // display the object on the page
  displayWeather(weatherObj);
}

// parse the XML into an object
function parseXMLWeather(xml) {

  // print XML on the console
  // console.log(xml);

  //create an object to hold the information in the xml file
  var weatherObj = {};

  // get the forecast XML element
  var forecastElement = xml.getElementsByTagName("forecast")[0];
  // get the query location
  weatherObj.queryLocation = forecastElement.getAttribute("queryLocation");
  // get the query time
  weatherObj.queryTime = forecastElement.getAttribute("queryTime");

  //get the weather XML element
  var weatherElementList = xml.getElementsByTagName("weather")[0];
  weatherObj.YYYYMMDD = weatherElementList.getAttribute("yyyymmdd");

  //get the rest of the child XML element in weather
  weatherObj.list = [];
  for (var i = 0; i < weatherElementList.length; i++) {
    var weatherElement = weatherElementList[i];
    var weather1Obj = parseWeatherElement(weatherElement);
    weatherObj.list.push(weather1Obj);
  }
  return weatherObj;
}
// Convert XML string to proper XML DOM document.
function parseXML(xmlString) {
  return new window.DOMParser().parseFromString(xmlString, "text/xml");
}

// parse a stock XML element into a JavaScript stock object
function parseWeatherElement(weatherElement) {
  var weather1Obj = {};

  //get all elements
  var yearElement = weatherElement.getElementsByTagName("year")[0];
  weather1Obj.year = yearElement.textContent;
  var monthElement = weatherElement.getElementsByTagName("month")[0];
  weather1Obj.month = monthElement.textContent;
  var dateElement = weatherElement.getElementsByTagName("date")[0];
  weather1Obj.date = dateElement.textContent;
  var dayOfWeekElement = weatherElement.getElementsByTagName("dayOfWeek")[0];
  weather1Obj.dayOfWeek = dayOfWeekElement.textContent;
  var overallElement = weatherElement.getElementsByTagName("overall")[0];
  weather1Obj.overall = overallElement.textContent;
  var highestElement = weatherElement.getElementsByTagName("highest")[0];
  weather1Obj.highest = highestElement.textContent;
  var lowestElement = weatherElement.getElementsByTagName("lowest")[0];
  weather1Obj.lowest = lowestElement.textContent;

  return weather1Obj;
}

// display the weather object on the page
function displayWeather(weatherObj) {
  // print the weatherObj on the console
  // console.log(weatherObj);

  // construct HTML code to display weather information
  var html = "<h1>" + weatherObj.queryLocation + " " + weatherObj.queryTime + "</h1>";
  html += weatherObj.YYYYMMDD;

  // show the constructed HTML code in the display div
  var displayDiv = document.getElementById("display");
  displayDiv.innerHTML = html;
}
<h1>Part 2</h1>
<button onClick="makeAjaxQueryWeather()">
Click here to view weather forecast 1
</button>
<br/> <br/>
<div id="display">
</div>


更新:保持代码尽可能简单。

分析您需要做什么,基本上您需要:

  1. 使用XMLHttpRequest获取XML内容。因此,在此示例中,我创建了一个辅助函数,可以随时随地轻松地执行AJAX请求。

var newXHR = null;
function sendXHR(type, responseType, url, data, successCallback, failureCallback) {
    newXHR = new XMLHttpRequest() || new window.ActiveXObject("Microsoft.XMLHTTP");
    newXHR.responseType = responseType;
    newXHR.open(type, url, true);
    newXHR.send(data);
    newXHR.onreadystatechange = function () {
        if (this.readyState === 4) {
            if (this.status === 200) {
                successCallback(this.response);
            } else {
                failureCallback(this.response);
            }
        }
    };
}

因此,您可以通过以下方式使用:

sendXHR("GET", "text", "https://gist.githubusercontent.com/dannyjhonston/e56a6461d88ebd43d039bac215fa4eb4/raw/af9b5883d35097e8a8a68b619c3b0a9f7a51dc7d/A8.xml", null, function (response) {
    // Success you can use the response object. In this case you get the XML string content.
}, function (error) {
    displayDiv.innerHTML = "XMLHttpRequest failed: status " + error;
});
  1. 将XML字符串内容解析为XML文档。

function parseXML(xmlString) {
    return new window.DOMParser().parseFromString(xmlString, "text/xml");
}

因此,在前面的代码中,您可以通过以下方式使用parseXML函数:

sendXHR("GET", "text", "https://gist.githubusercontent.com/dannyjhonston/e56a6461d88ebd43d039bac215fa4eb4/raw/af9b5883d35097e8a8a68b619c3b0a9f7a51dc7d/A8.xml", null, function (response) {
    var xml = parseXML(response);
}, function (error) {
    displayDiv.innerHTML = "XMLHttpRequest failed: status " + error;
});
  1. 从XML转换为JavaScript对象。使用parseXML(response)函数的结果,您获得了XML DOM,因此现在您可以浏览XML文档中的每个节点以创建JavaScript对象。根据您的需要。

function convertXMLToObject(xml) {
    var obj = {}, forecastElement = xml.children[0];
    if (forecastElement) {
        obj.queryLocation = forecastElement.getAttribute("queryLocation");
        obj.queryTime = forecastElement.getAttribute("queryTime");
        obj.list = [];
        var weatherElement, weatherElements = forecastElement.children, weatherElementsLen = weatherElements.length;
        for (var i = 0; i < weatherElementsLen; i++) {
            weatherElement = weatherElements[i];
            if (weatherElement) {
                obj.list.push({
                    yyyymmdd: weatherElement.getAttribute("yyyymmdd"),
                    year: weatherElement.children[0].textContent,
                    month: weatherElement.children[1].textContent,
                    date: weatherElement.children[2].textContent,
                    dayOfWeek: weatherElement.children[3].textContent,
                    overall: weatherElement.children[4].textContent,
                    overallCode: weatherElement.children[5].textContent,
                    highest: weatherElement.children[6].textContent,
                    lowest: weatherElement.children[7].textContent
                });
            }
        }
    }
    return obj;
}

使用上面的函数,您将获得以下JavaScript对象:

{
  "queryLocation": "Whoville",
  "queryTime": "22/07/2017 15:30:45",
  "list": [
    {
      "yyyymmdd": "20170727",
      "year": "2017",
      "month": "7",
      "date": "27",
      "dayOfWeek": "THU",
      "overall": "Considerable clouds",
      "overallCode": "cloudy",
      "highest": "18",
      "lowest": "5"
    },
    {
      "yyyymmdd": "20170726",
      "year": "2017",
      "month": "7",
      "date": "26",
      "dayOfWeek": "WED",
      "overall": "Cloudy with thunderstorm",
      "overallCode": "thunderstorm",
      "highest": "15",
      "lowest": "4"
    },
    {
      "yyyymmdd": "20170725",
      "year": "2017",
      "month": "7",
      "date": "25",
      "dayOfWeek": "TUE",
      "overall": "Considerable",
      "overallCode": "cloudy",
      "highest": "18",
      "lowest": "5"
    },
    {
      "yyyymmdd": "20170724",
      "year": "2017",
      "month": "7",
      "date": "24",
      "dayOfWeek": "MON",
      "overall": "Partly sunny",
      "overallCode": "partlySunny",
      "highest": "21",
      "lowest": "10"
    },
    {
      "yyyymmdd": "20170723",
      "year": "2017",
      "month": "7",
      "date": "23",
      "dayOfWeek": "SUN",
      "overall": "Plenty of sunshine",
      "overallCode": "sunny",
      "highest": "25",
      "lowest": "11"
    }
  ]
}
  1. div标签中显示天气信息。最后,使用上一点获得的JavaScript对象,您可以使用以下功能:

function renderObject(data) {
    var html = "";
    html += "<h1>";
    html += data.queryLocation;
    html += " @ ";
    html += data.queryTime;
    html += "</h1>";
    if (data.list && data.list.length) {
        html += "<div class=\"weather\">";
        var len = data.list.length, obj;
        for (var i = 0; i < len; i++) {
            obj = data.list[i];
            html += "<div title=\"";
            html += obj.yyyymmdd;
            html += "\"><div><p><span class=\"dayOfWeek\">";
            html += obj.dayOfWeek;
            html += "</span> ";
            html += obj.month;
            html += "/";
            html += obj.date;
            html += "</p>";
            html += "<p><span class=\"icon ";
            html += obj.overallCode;
            html += "\"></span></p></div><div><p class=\"overall\">";
            html += obj.overall;
            html += "</p><p><span class=\"highest\">";
            html += obj.highest;
            html += "°</span>/";
            html += obj.lowest;
            html += "°</p></div></div>";
        }
        html += "</div>";
    }
    return html;
}

这样,您可以在HTML中获得以下结果。

enter image description here

此外,您应该尝试使用不引人注目的JavaScript。

只需在按钮中使用一个ID,就像下面的标记一样:

<button id="btnGetData" type="button">
  Click here to view weather forecast 1
</button>

使用JavaScript并使用以下语法对其进行调用:

var btnGetData = document.getElementById("btnGetData");
btnGetData.onclick = function () {
    getXMLContent();
};

在这里,我分享了完整的示例,以便您进行查看。我添加了一些CSS3规则,以实现更好的可视化效果。

(function() {
  var newXHR = null;

  function sendXHR(type, responseType, url, data, successCallback, failureCallback) {
    newXHR = new XMLHttpRequest() || new window.ActiveXObject("Microsoft.XMLHTTP");
    newXHR.responseType = responseType;
    newXHR.open(type, url, true);
    newXHR.send(data);
    newXHR.onreadystatechange = function() {
      if (this.readyState === 4) {
        if (this.status === 200) {
          successCallback(this.response);
        } else {
          failureCallback(this.response);
        }
      }
    };
  }

  function getXMLContent() {
    var displayDiv = document.getElementById("display");
    if (displayDiv) {
      sendXHR("GET", "text", "https://gist.githubusercontent.com/dannyjhonston/e56a6461d88ebd43d039bac215fa4eb4/raw/af9b5883d35097e8a8a68b619c3b0a9f7a51dc7d/A8.xml", null, function(response) {
        var xml = parseXML(response), obj = convertXMLToObject(xml);
        displayDiv.innerHTML = renderObject(obj);
      }, function(error) {
        displayDiv.innerHTML = "XMLHttpRequest failed: status " + error;
      });
    }
  }

  function parseXML(xmlString) {
    return new window.DOMParser().parseFromString(xmlString, "text/xml");
  }

  function convertXMLToObject(xml) {
    var obj = {}, forecastElement = xml.children[0];
    if (forecastElement) {
      obj.queryLocation = forecastElement.getAttribute("queryLocation");
      obj.queryTime = forecastElement.getAttribute("queryTime");
      obj.list = [];
      var weatherElement, weatherElements = forecastElement.children,
        weatherElementsLen = weatherElements.length;
      for (var i = 0; i < weatherElementsLen; i++) {
        weatherElement = weatherElements[i];
        if (weatherElement) {
          obj.list.push({
            yyyymmdd: weatherElement.getAttribute("yyyymmdd"),
            year: weatherElement.children[0].textContent,
            month: weatherElement.children[1].textContent,
            date: weatherElement.children[2].textContent,
            dayOfWeek: weatherElement.children[3].textContent,
            overall: weatherElement.children[4].textContent,
            overallCode: weatherElement.children[5].textContent,
            highest: weatherElement.children[6].textContent,
            lowest: weatherElement.children[7].textContent
          });
        }
      }
    }
    return obj;
  }

  function renderObject(data) {
    var html = "";
    html += "<h1>";
    html += data.queryLocation;
    html += " @ ";
    html += data.queryTime;
    html += "</h1>";
    if (data.list && data.list.length) {
      html += "<div class=\"weather\">";
      var len = data.list.length, obj;
      for (var i = 0; i < len; i++) {
        obj = data.list[i];
        html += "<div title=\"";
        html += obj.yyyymmdd;
        html += "\"><div><p><span class=\"dayOfWeek\">";
        html += obj.dayOfWeek;
        html += "</span> ";
        html += obj.month;
        html += "/";
        html += obj.date;
        html += "</p>";
        html += "<p><span class=\"icon ";
        html += obj.overallCode;
        html += "\"></span></p></div><div><p class=\"overall\">";
        html += obj.overall;
        html += "</p><p><span class=\"highest\">";
        html += obj.highest;
        html += "°</span>/";
        html += obj.lowest;
        html += "°</p></div></div>";
      }
      html += "</div>";
    }
    return html;
  }

  var btnGetData = document.getElementById("btnGetData");
  btnGetData.onclick = function() {
    getXMLContent();
  };
}());
body {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  font-size: 1em;
  margin: 0 10px;
  padding: 0;
}

.weather {
  margin: 10px;
  width: 70%;
}

.weather div {
  border: #95b6e0 solid 1px;
  display: flex;
  margin: 5px;
  padding: 0;
}

.weather div div {
  border-style: none;
  display: block;
  padding: 5px;
  width: 50%;
}

.weather div div p {
  display: block;
  margin: 0;
  padding: 0;
}

.weather .dayOfWeek {
  background-color: inherit;
  color: #2b6daf;
  font-weight: 500;
}

.weather .overall {
  font-style: italic;
}

.weather .highest {
  font-size: 2em;
}

.weather .icon {
  background: url(https://cdn1.vectorstock.com/i/1000x1000/13/30/weather-icons-vector-731330.jpg) no-repeat;
  display: inline-block;
  height: 48px;
  width: 48px;
}

.weather .icon.sunny {
  background-position: 4px 6px;
  background-size: 400% 400%;
}

.weather .icon.partlySunny {
  background-position: -46px 7px;
  background-size: 400% 400%;
}

.weather .icon.cloudy {
  background-position: -48px -81px;
  background-size: 400% 448%;
}

.weather .icon.thunderstorm {
  background-position: -48px -41px;
  background-size: 400% 460%;
}
<h1>Part 2</h1>
<button id="btnGetData" type="button">
		Click here to view weather forecast 1
	</button>
<br /> <br />
<div id="display">
</div>