我正在创建一个“本地天气”应用程序,并且创建了一个下拉菜单,您可以在其中单击一个位置,然后显示诸如城市,国家和温度的信息。但是,每次单击位置时,我都无法显示信息。

这是我的代码。

如您所见,我能够加载当前位置和温度。我要做的是列出全局变量,并在function getLocation()中调用它们,然后在function getWeather()中运行信息。对于下拉菜单,我创建了一个名为mainCities的数组,并将城市附加到function testMenu()的下拉菜单中。在此功能中,我添加了onclick=testWeather('place')。为此,我创建了另一个名为function testWeather(cityLocation)的函数,在该函数中,我再次列出了全局变量的信息,并尝试在function getWeather()中再次运行它,但是它不起作用。我错过了什么?

您可以在以下位置查看我的代码的运行情况:http://codepen.io/kikibres/pen/EZMJZw



$(document).ready(function() {

  var currentLat;
  var currentLong;
  var currentCity;
  var currentRegion;
  var currentCountry;

  var mainCities = {
    'San_Francisco': {
      'region': 'California',
      'country': "United States",
      'lat': 37.7749300,
      'lon': -122.4194200
    },
    'St._Louis': {
      'region': 'Missouri',
      'country': "United States",
      'lat': 38.6272700,
      'lon': -90.1978900
    },
    'Miami': {
      'region': 'Florida',
      'country': "United States",
      'lat': 25.7742700,
      'lon': -80.1936600
    },
    'Tokyo': {
      'region': 'Tokyo',
      'country': "Japan",
      'lat': 35.689500,
      'lon': 139.6917100
    }
  };

  function testMenu() {
    for (var place in mainCities) {
      var city = place.replace(/_/g, ' ');
      $('#testMenu').append("<li onclick=testWeather('" + place + "');><a href='#'>" + city + "</a></li>");
    }
  };

  function testWeather(cityLocation) {
    currentLat = testLocation[cityLocation].lat;
    currentLong = testLocation[cityLocation].lon;
    currentRegion = testLocation[cityLocation].region;
    currentCity = testLocation[cityLocation];
    currentCountry = testLocation[cityLocation].country;

    getWeather();

  };

  function getLocation() {
    $.getJSON('http://ip-api.com/json/?callback=?', function(data) {

      currentRegion = data.regionName;
      currentCity = data.city;
      currentCountry = data.country;
      currentLat = data.lat;
      currentLong = data.lon;

      //$("#cityname").text(currentCity);

      getWeather();

    });
  };

function getWeather() {

  $("#cityname").text(currentCity);
  $("#state").text(currentRegion);
  $("#country").text(currentCountry);

  $.getJSON('http://api.openweathermap.org/data/2.5/weather?lat=' + currentLat + '&lon=' + currentLong + '&units=imperial&APPID=e656b9ee098cf2341fcfdb365b96b4a8', function(json) {

    var showfahrenheit = true;
    var tempfahrenheit = Math.round(json.main.temp);
    var temcelcius = Math.round((tempfahrenheit - 32) * 5/9);

    $("#temp").html(tempfahrenheit);

    $('#unit-switch').on('click', function() {
      if (showfahrenheit === false) {
        $("#temp").html(tempfahrenheit);
        showfahrenheit = true;
      } else {
        $("#temp").html(temcelcius);
        showfahrenheit = false;
      }

      $("#unit-toggle").toggleClass("toggle");
			//$('#temp').toggleClass('toggle');
    });

  });
};

  $(".cityarea").html(getLocation);
  testMenu();


});

@import url('https://fonts.googleapis.com/css?family=Roboto:300,400');
body {
  position: relative;
}
html,body{
  height:100%;
}
.wrapper {
  width: 100%;
  height: 100%;
  position: relative;
}
.container {
  position: relative;
  display: block;
  margin: 0 auto;
  width: 60%;
}
.header h1 {
  text-align: center;
  font-family: 'Roboto', sans-serif;
  font-weight: normal;
  margin: 0 0 10px 0;
}
.weatherbox {
  text-align: center;
}
.cityarea h2 {
  color: #000000;
  font-family: 'Roboto', sans-serif;
  font-weight: normal;
  font-size: 2em;
  margin: 0;
}
.countryarea {
  position: relative;
   display: -webkit-flex;
  display: flex;
  -webkit-justify-content: center;
  justify-content:         center;
  margin: 0 auto;
}
.countryarea h3 {
  margin: 0 0 10px 0;
  font-family: 'Roboto', sans-serif;
  font-weight: normal;
}
.countryarea h3:first-child {
  margin-right: 8px;
}
.dropdown {
  position: relative;
  display: inline-block;
  font-size: 16px;
  color: #FFF;
}
.dropdown-header {
  display: block;
  padding: 3px 20px;
  font-size: 12px;
  line-height: 1.42857143;
  color: #777;
  white-space: nowrap;
  text-transform: uppercase;
}
input[type=checkbox]{
  display: none;
}
label{
  box-sizing: border-box;
  display: inline-block;
  width: 100%;
  background-color: #57A0D4;
  padding: 10px 20px;
  cursor: pointer;
  text-align: center;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
  border-radius: 5px;
  font-size: 20px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
label .fa-globe {
  margin-right: 10px;
}
/*  The ul will have display:none by default */
ul{
  position: absolute;
  list-style: none;
  text-align: left;
  width: 100%;
  min-width: 160px;
  z-index: 1;
  padding: 5px 0;
  margin: 2px 0 0;
  font-size: 14px;
  text-align: left;
  box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.2);
  display: none;
  background-color: #fff;
  border: 1px solid #ccc;
  border: 1px solid rgba(0,0,0,.15);
  border-radius: 4px;
  -webkit-box-shadow: 0 6px 12px rgba(0,0,0,.175);
  box-shadow: 0 6px 12px rgba(0,0,0,.175);
}
ul li{
  /*padding: 15px;*/
  background-color: #fff;
  color: #4FB9A7;
  margin-bottom: 1px;
  cursor: pointer;
}
ul li a {
  padding: 8px 20px;
  color: inherit;
  text-decoration: none;
  display: block;
}
ul li a:hover{
  background-color: #4FB9A7;
  color: #FFF;
}
input[type=checkbox]:checked ~ label {
  background-color: #3D88BD;
}
input[type=checkbox]:checked ~ ul {
  display: block;
}
ul .divider {
  height: 1px;
  margin: 9px 0;
  overflow: hidden;
  background-color: #e5e5e5;
}
.temperaturearea span#temp {
  position: relative;
  color: #000000;
  font-size: 80px;
}
.temperaturearea #temp:after {
    content: '';
    position: absolute;
    height: 10px;
    width: 10px;
    top: 16px;
    right: -17px;
    border: 3px solid #000000;
    border-radius: 50%;
}
.weather > span {
  position: relative;
  font-size: 1.2rem;
}
.weather > span:before {
    content: '';
    position: absolute;
    left: -10px;
    top: 0px;
    height: 3px;
    width: 3px;
    border: 2px solid #000;
    border-radius: 50%;
}
.main-toggle span {
  margin: 0 0 0 16px;
}
.main-toggle span:last-child {
  margin-left: 11px;
}
.weather button {
		background: #6bbf6b;
		border: none;
		border-radius: 30px;
		outline: none;
		width: 45px;
		height: 20px;
		margin: 5px 5px 0;
		cursor: pointer;
		position: relative;
		transition: background .2s;
}
.weather button:active {
		background: #67b567;
	}
.weather #unit-toggle {
		position: absolute;
		display: inline-block;
		left: -8px;
		top: 2px;
		width: 15px;
		height: 15px;
		background: #fff;
		border-radius: 50%;
		transition: left .2s;
}
#unit-toggle.toggle {
		left: 16px;
}

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="wrapper">
  <div class="container">
    <div class="header"><h1>Local Weather</h1></div>
    <div class="weatherbox">
      <div class="cityarea">
      <h2 id="cityname"></h2>
      </div>
      <div class="countryarea">
        <h3 id="state"></h3>
        <h3 id="country"></h3>
      </div>
      <div class="dropdownlocation">
        <div class="dropdown">
        <input type="checkbox" id="checkbox-toggle">
    <label for="checkbox-toggle"><i class="fa fa-globe" aria-hidden="true"></i><i class="fa fa-caret-down" aria-hidden="true"></i></label>
    <ul id="testMenu">
        <li><a href="#">Current Location</a></li>
        <li class="divider"></li>
        <li class="dropdown-header">Main Cities</li>
    </ul>
      </div>
      </div>
    <div class="temperaturearea">
      <div>
      <span id="wicon"></span>
      </div>
      <div id="wdescription"></div>
      <span id="temp"></span>
      <div class="weather main-toggle"> <!-- Begin Unit Switch -->
      <span>F</span>
      <button id="unit-switch"><span id="unit-toggle"></span></button>
      <span>C</span>
    </div>
    </div>
    </div>
  </div>
</div>

最佳答案

代码有两个问题,因为您已经在document.ready内定义了所有函数和变量,所以您无法在document.ready之外访问任何这些函数和变量。这就是为什么当您在onclick li上调用'testWeather'时,它会引发'testWeather'的原因,因此未定义。为了解决这个问题(您应该使变量和函数成为全局变量),您应该在document.ready之外定义所有变量。只需在document.ready中保留下面两行代码即可。
$(".cityarea").html(getLocation); testMenu();

但是,这只能解决“ testWeather”未定义的问题,并且代码中还有更多问题,在其中的testWeather函数中,您使用的是一个未定义的名为testLocation的属性,因此您将在此处获取JavaScript错误。您已将测试位置保存在mainCities变量中,因此应使用mainCities而不是testLocation。这两项更改将使您的应用正常运行。这是更正的JavaScript代码。您的代码还有一个小错误,您读取当前城市的方式不正确。

$(document).ready(function () {
     $(".cityarea").html(getLocation);
     testMenu();
 });
    var currentLat;
    var currentLong;
    var currentCity;
    var currentRegion;
    var currentCountry;

    var mainCities = {
        'San_Francisco': {
            'region': 'California',
            'country': "United States",
            'lat': 37.7749300,
            'lon': -122.4194200
        },
        'St._Louis': {
            'region': 'Missouri',
            'country': "United States",
            'lat': 38.6272700,
            'lon': -90.1978900
        },
        'Miami': {
            'region': 'Florida',
            'country': "United States",
            'lat': 25.7742700,
            'lon': -80.1936600
        },
        'Tokyo': {
            'region': 'Tokyo',
            'country': "Japan",
            'lat': 35.689500,
            'lon': 139.6917100
        }
    };

    function testMenu() {
        for (var place in mainCities) {
            var city = place.replace(/_/g, ' ');
            $('#testMenu').append("<li onclick=testWeather('" + place + "');><a href='#'>" + city + "</a></li>");
        }
    };

    function testWeather(cityLocation) {
        currentLat = mainCities[cityLocation].lat;
        currentLong = mainCities[cityLocation].lon;
        currentRegion = mainCities[cityLocation].region;
        currentCity = mainCities[cityLocation];
        currentCountry = mainCities[cityLocation].country;

        getWeather();

    };

    function getLocation() {
        $.getJSON('http://ip-api.com/json/?callback=?', function (data) {

            currentRegion = data.regionName;
            currentCity = data.city;
            currentCountry = data.country;
            currentLat = data.lat;
            currentLong = data.lon;

            //$("#cityname").text(currentCity);

            getWeather();

        });
    };

    function getWeather() {

        $("#cityname").text(currentCity);
        $("#state").text(currentRegion);
        $("#country").text(currentCountry);

        $.getJSON('http://api.openweathermap.org/data/2.5/weather?lat=' + currentLat + '&lon=' + currentLong + '&units=imperial&APPID=e656b9ee098cf2341fcfdb365b96b4a8', function (json) {

            var showfahrenheit = true;
            var tempfahrenheit = Math.round(json.main.temp);
            var temcelcius = Math.round((tempfahrenheit - 32) * 5 / 9);

            $("#temp").html(tempfahrenheit);

            $('#unit-switch').on('click', function () {
                if (showfahrenheit === false) {
                    $("#temp").html(tempfahrenheit);
                    showfahrenheit = true;
                } else {
                    $("#temp").html(temcelcius);
                    showfahrenheit = false;
                }

                $("#unit-toggle").toggleClass("toggle");
                //$('#temp').toggleClass('toggle');
            });

        });
    };

10-07 18:10