开发者问题收集

窗口 onload 和 onclick 事件

2017-07-30
3229

大家好,我正在尝试制作简单的天气应用,但遇到了一个问题。一切都很顺利,直到我决定制作一个函数,将摄氏温度转换为华氏温度,反之亦然。我决定制作一个函数,在 window.load 事件之后调用 onclick 事件,但由于某种原因,它不起作用。当我使用 onclick 元素时,我收到以下错误。

Uncaught TypeError: Cannot set property ‘onclick’ of 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 上不起作用

3个回答

窗口 onLoad

The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links and sub-frames have finished loading.

您试图在 element 存在之前获取它。

请参阅: MDN

只需在创建时分配 onClick 处理程序:

 myUnit = createNode('span');  
 myUnit.addEventListener('click', function(e) { changeUnits()})
 ...

请参阅: jsbin

btzr
2017-07-30

页面加载时,ID 为 unit 的元素并不存在,因为它是在 AJAX 调用发生时生成的。

一旦发生 AJAX 调用,您应该将 onclick 定义为一个函数(与使用 window.onload 的方式相同,而不仅仅是指向一个函数的指针,即

document.getElementById("unit").onclick = function() {
    chnageUnits();
}
toastrackengima
2017-07-30

您可以在创建节点后添加事件监听器,如下所示

    let myUnit = createNode('span');
    myUnit.addEventListener('click', changeUnits);

工作 jsbin http://jsbin.com/xuvanen/edit?html,js,output

azs06
2017-07-30