未捕获的TypeError:无法读取null的属性'removeChild'(使用来自Instagram的JSONP响应)

时间:2016-04-27 23:14:55

标签: javascript json

我正在尝试制作Google Places API + Instagram API应用程序。用户输入位置和关键字以及结果和相关的Instagram照片呈现。结果'lat / lng坐标存储在一个数组中,然后连接到Instagram URL JSON-P响应。此URL作为脚本标记附加到HTML,稍后在呈现照片时将其删除。但是我遇到了一个错误:

未捕获的TypeError:无法读取null的属性“removeChild”。

这是Javascript。这个JS是我的应用程序的一个更简单的版本(位置是预定义的)。

document.addEventListener('DOMContentLoaded', function () {

var sanFran = {lat: 37.7700623, lng: -122.4463697};
var losAngeles = {lat: 34.0482814, lng: -118.2479595};
var newYork = {lat: 40.7484444, lng: -73.9878441};
var chicago = {lat: 41.8503659, lng: -87.7064438};
var boston = {lat: 42.3134791, lng: -71.1271966};

var locationArray = [sanFran, losAngeles, newYork, chicago, boston];

function loop(array){
    for(var i = 0; i < array.length; i++){
        var lat = array[i].lat;
        var lng = array[i].lng;
        var accessToken = '249457765.1fb234f.adc28edf9d7f4ad2ad281752445eac86';
        var url = 'https://api.instagram.com/v1/media/search?lat=' + lat + '&lng=' + lng + '&distance=100' + '&access_token=' + accessToken + '&callback=?';
        getJSONP(url, success, i);
    }
}

function getJSONP(url, success, i) {

        var ud = '_' + +new Date,
        script = document.createElement('script'),
        body = document.getElementsByTagName('body')[0] 

        //callback for JSON-P response
        window[ud] = function(data) {

            script.parentNode.removeChild(script);
            success && success(data, i);
        };
        console.log(url);
        body.appendChild(script);
        script.src = url.replace('callback=?', 'callback=' + ud);


}

function success(response, i){
        var results = document.getElementById("results");
        var responseLength = response.data.length;
        var totalResults = 5;

        //cap photos to 5 or less
        responseLength = totalResults;

        for(var j = 0; j < responseLength; j++){
            var img = document.createElement("IMG");
            img.src = response.data[j].images.thumbnail.url;
            results.appendChild(img);
            img.id = "img";
        }               
}
loop(locationArray);
});

这是HTML:

<!DOCTYPE html>
<html>
  <head>
    <title>Places and Instagram App</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="style1.css" rel="stylesheet">
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCxUwNycYzt3GGO0FvZGYJd3zUQQDEFal8&libraries=places"></script>
<script src="stack.js"></script>

  </head>
  <body>
    <h1>Instagram Photos</h1>
    <div id = "results">
    </div>
  </body>
</html>

理论上,如果应用程序正常运行,总共会呈现25张照片。

注意:我不能使用JQuery或任何外部库/框架。我也使用此解决方案作为参考:Failed to execute 'removeChild' on 'Node',但它对我不起作用(控制台中的错误消失但照片仍然无法呈现)。此外,当控制台在窗口[ud]变量中记录[数组项]时,看起来项目没有以正确的顺序传递。谢谢你的帮助。

2 个答案:

答案 0 :(得分:0)

我改变了你的代码,首先关闭,现在你将位置数组传递给函数getLocationPhotos(),这个方法将调用方法getLocation(),在那里你将从Instagram中检索所有的照片。您遇到的一个问题是,当某个请求根本没有任何响应时,您正在硬编码请求的responseLength。例如,您的请求中的一个回复

  

/ ** / _1461800988408({“meta”:{“code”:200},“data”:[]})

此外,每个请求都在前一个请求结束后执行,因此您可以按顺序显示所有图像。这是我制作的新代码:

document.addEventListener('DOMContentLoaded', function () {

var sanFran = {lat: 37.7700623, lng: -122.4463697};
var losAngeles = {lat: 34.0482814, lng: -118.2479595};
var newYork = {lat: 40.7484444, lng: -73.9878441};
var chicago = {lat: 41.8503659, lng: -87.7064438};
var boston = {lat: 42.3134791, lng: -71.1271966};

var locationArray = [sanFran, losAngeles, newYork, chicago, boston];

function getLocationPhotos(locations){
    if(locations.length) getLocation(locations, successCallback, 0);
}

function getLocation (locations, successCallback, index) {
        var lat = locations[index].lat;
        var lng = locations[index].lng;
        var accessToken = '249457765.1fb234f.adc28edf9d7f4ad2ad281752445eac86';
        var url = 'https://api.instagram.com/v1/media/search?lat=' + lat + '&lng=' + lng + '&distance=100' + '&access_token=' + accessToken + '&callback=?';
        getJSONP(url, function (response, index) {
            successCallback(response, index);
            if (locations.length - 1 > index) getLocation(locations, successCallback, index + 1);
        }, index);
}

function getJSONP(url, successCallback, index) {

        var ud = '_' + +new Date(),
        script = document.createElement('script'),
        body = document.getElementsByTagName('body')[0]; 

        //callback for JSON-P response
        window[ud] = function(data) {

            script.parentNode.removeChild(script);
            if(!data) return errorCallback(index, successCallback);
            if(successCallback) successCallback(data, index);
        };
        console.log(url);
        body.appendChild(script);
        script.src = url.replace('callback=?', 'callback=' + ud);


}

function errorCallback(index, afterEndsCallback) {
  console.log('Your index' + index + 'had a problem retrieving the data');
  afterEndsCallback([], index);
}

function successCallback(response, i){
        var results = document.getElementById("results");
        var responseLength = response.data.length;

        for(var j = 0; j < responseLength; j++){
            var img = document.createElement("IMG");
            img.src = response.data[j].images.thumbnail.url;
            results.appendChild(img);
            img.id = "img";
        }               
}
getLocationPhotos(locationArray);
});

Link to the code

答案 1 :(得分:-1)

有效。将脚本放在最后或在窗口onload上执行。