你好我们正在尝试制作简单的天气应用程序而且我遇到了一个问题。一切正常,直到我决定制作一个将摄氏温度改为华氏温度的功能,反之亦然。我决定创建一个函数,我会在window.load事件之后调用onclick事件,但由于某种原因它无法正常工作。当我使用onclick元素时,我得到以下错误。
未捕获的TypeError:无法设置属性'onclick'为null
当我添加到window.load时没有任何反应。这是我的JS:
// This won't work on github because openweatherapp requires payed version of api for https and github forces https
const ipApi = 'http://ip-api.com/json';
const body = document.getElementsByTagName("body")[0];
fetch(ipApi)
.then(response => response.json())
.then(function(data) {
let latitude = data.lat;
let longitude = data.lon;
let city = data.city;
const openWeatherAppId = '********';
const openWeatherUrl = 'http://api.openweathermap.org/data/2.5/weather?lat=' + latitude + '&lon=' + longitude + '&units=metric' + '&APPID=' + openWeatherAppId;
fetchWeather(city, openWeatherUrl);
})
.catch(function(error) {
// If there is any error you will catch them here
console.log(error);
});
function fetchWeather(city, api) {
fetch(api)
.then(response => response.json())
.then(function(data) {
let desc = data.weather[0].description;
let temperature = data.main.temp;
let icon = data.weather[0].icon;
var iconSrc = 'http://openweathermap.org/img/w/' + icon + '.png';
let myCity = createNode('h2');
myCity.innerHTML = city;
let myDesc = createNode('p');
myDesc.innerHTML = desc;
let myDiv = createNode('div');
myDiv.setAttribute('id', 'temperatureDiv');
let myTemp = createNode('p');
myTemp.innerHTML = temperature;
myTemp.setAttribute('id', 'temperature'); // Give ID to 'p' so I can use with DOM
let myUnit = createNode('span');
myUnit.innerHTML = 'Celsius';
myUnit.setAttribute('id', 'unit'); // Give ID to 'p' so I can use with DOM
let myIcon = createNode('img');
myIcon.src = iconSrc;
append(body, myCity);
append(body, myDesc);
append(body, myDiv);
append(myDiv, myTemp);
append(myDiv, myUnit);
append(body, myIcon);
changeUnits(temperature);
})
.catch(function(error) {
// If there is any error you will catch them here
console.log(error);
});
}
function changeUnits (myTemperature) {
let currentTemp = myTemperature; // This is current temperature in celsius
if (document.getElementById('unit').innerHTML == 'Celsius') {
document.getElementById('temperature').innerHTML = (currentTemp * 1.8 + 32).toFixed(0);
document.getElementById('unit').innerHTML = 'Fahrenheit';
} else {
document.getElementById('temperature').innerHTML = currentTemp;
document.getElementById('unit').innerHTML = 'Celsius';
}
}
window.load = function () {
document.getElementById('unit').onclick = changeUnits;
}
function createNode(element) {
return document.createElement(element); // Create the type of element you pass in the parameters
}
function append(parent, el) {
return parent.appendChild(el); // Append the second parameter(element) to the first one
}
任何人都可以帮助我。这是JSBin,所以你看到发生了什么http://jsbin.com/jujifo/edit?html,js,console,output 我正在使用openweather API,因此请使用http,这样您就可以看到代码在运行中无法在https
上运行答案 0 :(得分:1)
加载事件在文档加载过程结束时触发。此时,文档中的所有对象都在DOM中,并且所有图像,脚本,链接和子帧都已完成加载。
你试图在{存在之前'获得element
。
请参阅:MDN
只需在创建时分配onClick
处理程序:
myUnit = createNode('span');
myUnit.addEventListener('click', function(e) { changeUnits()})
...
请参阅:jsbin
答案 1 :(得分:0)
当页面加载时,ID为unit
的元素不存在,就像您的AJAX调用发生时一样。
一旦发生了AJAX调用,你应该将onclick
定义为一个函数(与window.onload
的方式相同,而不仅仅是指向一个函数的指针,即
document.getElementById("unit").onclick = function() {
chnageUnits();
}
答案 2 :(得分:0)
您可以在创建节点后添加事件侦听器,如此
let myUnit = createNode('span');
myUnit.addEventListener('click', changeUnits);
答案 3 :(得分:0)
使用window.onload
代替window.load
。试试这个:
window.onload = function () {
document.getElementById('unit').addEventListener('click', changeUnits);
}
或者,在大多数现代浏览器中,您可以使用脚本标记上的async
或defer
属性来避免默认的同步阻止行为。