0

I'm fairly new to javascript, and getting quite frustrated by the following code

<!DOCTYPE html>

<html>

<script>
var time = '0'
var area = 'neast'

function update_area(input) {
	area = input;
    load_updated_image(area,time);
};

function update_time(input) {
	time = input;
    load_updated_image(area,time);
};

function load_updated_image(area,time) {
	var url = 'http://personal.psu.edu/kps5442/modelimages/hrrr_'+area+'_wetbulb'+time+'.png';
	document.getElementById("theImage").src = url;
    document.getElementById("url").innerHTML = url;
};
</script>


<body onload="load_updated_image(area,time)">

<p>URL Output:</p>
<p id="url"></p>

<font size = 4><b>Forecast Hour: &nbsp;</b> 
<font size = 3>
<a href="#" onmouseover="update_time(0);" /> 00</a>&nbsp;
<a href="#" onmouseover="update_time(1);" /> 01</a>&nbsp;
<a href="#" onmouseover="update_time(2);" /> 02</a>&nbsp;


<img id="theImage" src=undefined width="850" height="600" />	

<br> <font size = 4><b>Region Selection: &nbsp;</b>

<a href="#" onclick="update_area(neast);" /> Northeast</a>&nbsp;
<a href="#" onclick="update_area(seast);" /> Southeast</a>&nbsp;

</body>
</html>

I have 18 different "hours" of images for different regions across the US. The goal is to change the hour of the image when the hour links are moused over, and update the region when the region links are clicked.

The function update_time() works as expected, changing the image as I mouse over the links. However, the function update_area() fails with the following error:

"Uncaught ReferenceError: neast is not defined"

I'm not sure why this is happening, because the update_time and update_area functions are built in exactly the same way, and I globally defined the time and area variables at the start of the script.

Any help would be appreciated!

6
  • In the code you have posted, I don't see a definition for the variable "neast" (or "seast" for that matter) Commented Feb 28, 2019 at 17:13
  • the variable is not called neast, it's called area Commented Feb 28, 2019 at 17:13
  • Please note that this is not proper HTML code, outside of your javascript. Under modern HTML5 rules, there are no self-closing elements. It's not a hard error, but don't add that /> at the end of an <img, also <font> hasn't existed as element since 1998. Also, if you need click functionality, use <button>, not <a>, and definitely not with href="#", which is an active instruction to scroll the document to the top. Finally, on... handlers are also legacy JS, so you want to use addEventLister in your javascript, after you've declared all your HTML. Commented Feb 28, 2019 at 17:15
  • 1
    basically: if you're working off of a tutorial, please find a modern tutorial instead, this one's teaching you how to do everything using 20 year old conventions, none of which apply today. Commented Feb 28, 2019 at 17:16
  • @Mike'Pomax'Kamermans Could you please give an example of how I would use addEventListener in my case? Commented Mar 1, 2019 at 14:18

2 Answers 2

3

You have to put the arguments in quotes .

onclick="update_area('neast');"
onclick="update_area('seast');"

<!DOCTYPE html>

<html>

<script>
var time = '0'
var area = 'neast'

function update_area(input) {
	area = input;
    load_updated_image(area,time);
};

function update_time(input) {
	time = input;
    load_updated_image(area,time);
};

function load_updated_image(area,time) {
	var url = 'http://personal.psu.edu/kps5442/modelimages/hrrr_'+area+'_wetbulb'+time+'.png';
	document.getElementById("theImage").src = url;
    document.getElementById("url").innerHTML = url;
};
</script>


<body onload="load_updated_image(area,time)">

<p>URL Output:</p>
<p id="url"></p>

<font size = 4><b>Forecast Hour: &nbsp;</b> 
<font size = 3>
<a href="#" onmouseover="update_time(0);" /> 00</a>&nbsp;
<a href="#" onmouseover="update_time(1);" /> 01</a>&nbsp;
<a href="#" onmouseover="update_time(2);" /> 02</a>&nbsp;


<img id="theImage" src=undefined width="850" height="600" />	

<br> <font size = 4><b>Region Selection: &nbsp;</b>

<a href="#" onclick="update_area('neast');" /> Northeast</a>&nbsp;
<a href="#" onclick="update_area('seast');" /> Southeast</a>&nbsp;

</body>
</html>

In JavaScript variables are not restricted to a single 'type', but a String will always be contained in quotes and a number will not. Also a variable cannot be, or start with, a number. This is why when you use a string as an argument it must be contained within quotes, otherwise it thinks you are sending a variable.

Sign up to request clarification or add additional context in comments.

3 Comments

This works! I'm curious, though, why don't I need quotes for 0, 1, 2 etc but not for seast and neast? I thought in this case the numbers are treated as strings as well.
variable names cannot be 0 1 etc but seast/neast can be both a string or a variable. Without quotes function searchs for variables named seast/neast which are not defined. Putting in quotes tell the unction they are strings and are passed successfully.
please don't just repeat bad code, at the very least also rewrite this to modern HTML and JS so that @KarlSchneider learns how to do this in 2019 instead of 1997 =(
0

You're starting your document with <!doctype html> so you're saying you're writing HTML5, but there is a whole bunch of things that are incredibly wrong here due to use HTML3.2 and obsolete ways to invoke javascript.

Under modern HTML5 rules, there are no self-closing elements. It's not a hard error, but don't add that /> at the end of an <img.... Also <font> hasn't existed as element for 20 years now. It was removed in HTML4.1 in 1998. Then some semantics: if you need button functionality (i.e. clickable, but NOT navigating to some (part of a) page), use <button>. That's what it's for. Do not use <a>, and definitely not with href="#", because that's an active instruction for the browser to scroll to the top of the page. Finally, on...=... handlers are an ancient attribute that is unfortunately still supported, but you should never use. Use addEventListener in your Javascript, after you've declared all your HTML.

So let's just fix everything at the same time:

<!-- this line literally tells the browser "I am using HTML5" -->
<!DOCTYPE html>
<html>
  <!-- always have a header section -->
  <head>
    <!-- no / at the end of meta elements -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Always just fill this in, it's good practice</title>
    <style>
      /* you want this in its own file, see the note at the end of this post */
      h1 {
        font-size: 100%;
        font-weight: bold;
       }
    </style>
  </head>
  <body>
    <!-- sectioning isn't mandatory, but extremely good practice -->
    <section id="output">
      <h1>URL Output:</h1>

      <p>Forecast Hour:</p>

      <div class="controls">
        <!-- let's use data attributes, and be explicit about the values here -->
        <button class="forecast update" data-value="0">0h</button>
        <button class="forecast update" data-value="1">1h</button>
        <button class="forecast update" data-value="2">2h</button>
      </p>

      <!-- if you've never see the figure/figcaption elements: they exist -->
      <figure id="forecast-image">
        <!-- no / at the end of this element -->
        <img src="placeholder.jpg" width="850" height="600" alt="forecast map">
        <figcaption></figcaption>
      </figure>
    </section>

    <section>
      <h1>Region Selection</h1>

      <div class="controls">
        <button class="area update" data-value="neast">Northeast</buton>
        <button class="area update" data-value="seast">Southeast<button>
      </div>
    </section>

    <!-- don't put your script in the page. put it in its own file -->
    <script src="updates.js"></script>
  </body>
</html>

And then we make a second file for the javascript called updates.js:

// this goes last, so that the DOM is done by the time you invoke your script.
var currentTime = 0;
var currentArea = `NorthEast`;

// this function doesn't need parameters: we already know what they are
function load_updated_image() {
  var url = `http://personal.psu.edu/kps5442/modelimages/hrrr_${currentArea}_wetbulb${currentTime}.png`;
  let figure = document.getElementById(`forecast-image`);
  // update the image
  let img = figure.querySelector(`img`);
  img.src = url;
  // update the image caption with a link
  let caption = figure.querySelector(`figcaption`);
  caption.innerHTML = ``;
  let link = document.createElement(`a`);
  link.href = url;
  caption.appendChild(link);
}

// update the area, and called image update
function update_area(area) {
  currentArea = area;
  load_updated_image();
};

// update the time, and called image update
function update_time(time) {
  currentTime = timel
  load_updated_image();
};

// add the initial page load handling
document.addEventListener(`ready`, evt => load_updated_image());

// add the click handling for forecast time buttons
let forecastButtons = document.querySelectorAll(`button.forecastupdate`);
forecastButtons.forEach(button => {
  // get the button's data-value 
  value = button.dataset.value;

  // and then set up a click listener to update the forecast time
  button.addEventListener(`click`, evt => update_time(value));
});

// add the click handling for forecast area buttons
let areaButtons = document.querySelectorAll(`button.area.update`);
forecastButtons.forEach(button => {
  // get the button's data-value 
  value = button.dataset.value;

  // and then set up a click listener to update the forecast area
  button.addEventListener(`click`, evt => update_area(value));
});

And then to be even more proper, don't use <style>...</style> but make a new file called "forecast.css" and then link to that in your page using <link href="forecast.css" rel="stylresheet"> (note: this is still HTML5, you don't put /> at the end. Link elements simply don't have a closing tag)

1 Comment

Thank you so much for the detailed response -- this helps me out a lot and will a lot more in the future!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.