JSON数据在推送到DOM时显示重复项

时间:2016-10-18 14:52:37

标签: jquery html json

你好新手在这里试图找出我的jQuery代码有什么问题。该代码应该从API中提取地震信息并将其显示在DOM中。问题是我在DOM中看到了重复的信息,但如果我使用控制台调用来显示该信息,那么它就是唯一的。

HTML:

<div class="control-wrapper">
  <h2>Start date: <input type="text" id="datepicker"></h2>
  <h2>End date: <input type="text" id="datepicker_2"></h2>
  <button id="generate">Generate</button>
</div>

<h2>Total # of EQ's: <span id="total"></span></h2>
<div class="wrapper" id="template">
  <h1>Name: <span id="title"></span></h1>
  <h3>Magnitued: <span id="mag"></span></h3>
  <h3>Tsunami Warning: <span id="tsunami"></span></h3>
</div>

jQuery的:

$(document).ready(function(){
  var scriptString = 'https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=';
  var button = $('#generate');

  /**DATEPICKER**/
  var startDate = 0;
  var endDate = 0;
  $( '#datepicker' ).datepicker();
  $('#datepicker').datepicker('option', 'dateFormat', 'yy-mm-dd');
  $( '#datepicker_2' ).datepicker();
  $('#datepicker_2').datepicker('option', 'dateFormat', 'yy-mm-dd');

  /** GENERATE BUTTON ON CLICK **/
  button.on('click', function(){
    startDate = $('#datepicker').val();
    endDate = $('#datepicker_2').val();
    scriptString = scriptString + startDate +'&endtime=' + endDate;
    makeRequest(scriptString);
  });
});

/** MAKEREQUEST EXECUTES AFTER THE GENERATE BUTTON IS CLICKED **/
function makeRequest(requestString){
  var myRequest;
  var eqs = [];

  var myRequest = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
  myRequest.onreadystatechange = function(){
    if(myRequest.readyState === 4 && myRequest.status === 200){
      var jsonObj = JSON.parse(myRequest.responseText);//Grabs json object
      var data = jsonObj.features;
      pushToDOM(data);
    }
  }
  myRequest.open("GET", requestString, true);
  myRequest.send();
}

/** RECIEVES ARRAY OF EQS AND PUSHES THE FIRST TO THE DOM **/
function pushToDOM(eqs){
  var tot = $('#total');
  tot.text(eqs.length);

  /*ADDS EQs TO DOM*/
  for(x in eqs){
    var wrap = $('.wrapper').clone();
    wrap.attr('id', x);
    var place = eqs[x].properties.place;
    var mag = eqs[x].properties.mag;
    var tsu = eqs[x].properties.tsunami;
    wrap.find('#title').text(place);
    wrap.find('#mag').text(mag);
    if(tsu === 0){
      wrap.find('#tsunami').text('No');
    }
    else{
      wrap.find('#tsunami').text('Yes');
    }
    $('body').delay().append(wrap);
    if(x === 10){
      break;
    }
  }
}

Codepen

PS:我编写脚本的方式似乎是一个问题,因为它在显示信息之前锁定了浏览器,所以,如果有任何方法可以改进我的代码结构或算法,请告诉我。

谢谢!

1 个答案:

答案 0 :(得分:3)

首先,您的代码存在一些问题。您需要花时间阅读一些jQuery教程。

目前,这些是我在下面确定并修复的问题。

  • jQuery总是将动作应用于所有匹配的元素。因此,无需单独初始化日期选择器。
  • jQuery有built-in Ajax support。不要使用手动滚动的XmlHttpRequest代码,特别是不要使用您从某个网站复制的代码(这通常是正确的:不要复制和粘贴您不了解的代码。)
  • jQuery负责URL参数编码,您可以将参数作为对象传递,如下所示。
  • jQuery为你做JSON解析,所以这也不是问题。
  • 克隆HTML元素时,请确保它们不包含任何id属性。 ID应该在整个文档中是唯一的,重复ID会破坏内容。使用CSS类来标识元素的类型。
  • 您需要在第二次单击按钮时删除所有以前添加的元素。这将解决您的重复问题。
  • 在加载数据时禁用按钮是一个不错的选择,因此设置日期字段的默认值。
  • 您应该在.fail()电话中添加某种错误处理(请参阅documentation for the jQuery XHR object$.getJSON()的使用情况)。

下面的可运行代码示例:

&#13;
&#13;
$(function () {
  $('.datepicker').datepicker({dateFormat: 'yy-mm-dd'});
  $('#starttime').datepicker("setDate", "-1d");
  $('#endtime').datepicker("setDate", "0d");

  $('#generate').on('click', function () {
    $('#generate').text("loading...").prop("disabled", true);
    $('#total').text("");

    $.getJSON('https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson', {
      starttime: $('#starttime').val(),
      endtime: $('#endtime').val()
    }).done(function (geoJson) {
      $('#total').text(geoJson.features.length);
      $('.earthquake').remove();

      $.each(geoJson.features, function (i, feature) {
        var $item = $('#earthquake-template').clone().removeAttr("id").addClass("earthquake");

        $item.find('.place').text(feature.properties.place);
        $item.find('.tsunami').text(feature.properties.tsunami ? 'Yes' : 'No');
        $item.find('.mag').text(feature.properties.mag);
        $item.appendTo('body');
      });
    }).fail(function (jqXhr, status, error) {
      alert("Could not fetch earthquake info - " + error);
    }).always(function () {
      $('#generate').text('Generate').prop('disabled', false);
    });
  });
});
&#13;
h1, h2, h3 { font-size: small; }
#earthquake-template { display: none; }
.earthquake { border: 1px solid silver; margin-top: 5px; }
div.ui-datepicker { font-size:10px; }
&#13;
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

<div class="control-wrapper">
  <h2>Start date: <input type="text" class="datepicker" id="starttime"></h2>
  <h2>End date: <input type="text" class="datepicker" id="endtime"></h2>
  <button id="generate">Generate</button>
</div>

<h2>Total # of EQ's: <span id="total"></span></h2>
<div id="earthquake-template">
  <h1>Name: <span class="place"></span></h1>
  <h3>Magnitude: <span class="mag"></span></h3>
  <h3>Tsunami Warning: <span class="tsunami"></span></h3>
</div>
&#13;
&#13;
&#13;