0

I am working on a javascript app which displays images of the results of different US elections. I am thinking there must be a quicker way to do this than what I am doing. There must be some way I can have one function that displays an election map with the year as a parameter, but how can I do this with image variables? I am trying to think of a quicker way to write this code. If anyone knows, please help me out.

<script>

var el2020img = "<img src=270towin.png width=600 height=300>";
var el2016img = "<img src=201019164452-2016-election-map.jpg width=600 height=300>";



function the2020election(){
document.getElementById("demo").innerHTML=el2020img;
}
function the2016election(){
    document.getElementById("demo").innerHTML=el2016img;
}
</script>

I am wondering about how to do this.

  • Something like `function theElection(selector, content) { document.getElementById(selector).innerHtml=content }`? – Techno Nov 05 '22 at 21:01
  • [Create an object](//developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Object_initializer) that holds both images, then just [access them](//developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Property_Accessors). You don’t need two separate functions and you don’t need two separate variables. – Sebastian Simon Nov 05 '22 at 21:02

1 Answers1

1

One way would be to use an object indexed by year, whose values are the filenames associated with the year.

const srcs = {
  2020: '270towin.png',
  2016: '201019164452-2016-election-map.jpg'
};

And then, instead of having multiple standalone functions, have a single function that takes the year as an argument.

const demo = document.getElementById("demo");
const populate = (year) => {
  demo.innerHTML = `<img src="${srcs[year]}" width=600 height=300>`;
};

A nicer way would be to rename the images so that they all have a consistent format, such as 2016.png and 2020.png. Then the object becomes unnecessary, and you could do

const populate = (year) => {
  demo.innerHTML = `<img src="${year}.png" width=600 height=300>`;
};
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • 1
    You can also avoid `innerHTML` by using `demo.replaceChildren(Object.assign(document.createElement("img"), { src: srcs[year], width: 600, height: 300 }));`. Not totally necessary to do in this small case, but useful to know in general. Alternatively, the `` element can stay the same and then only the `src` property needs to be altered. – Sebastian Simon Nov 05 '22 at 21:05
  • thanks for your help. I don't understand why you use const populate = (year) rather than populate(year)? – Joseph Foley Nov 06 '22 at 08:29
  • @JosephFoley See [`const`](//developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/const) and [Arrow function expressions](//developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions). `populate(year)` by itself would be invalid syntax. If you mean `function populate(year){`…`}`, this is the old, pre-ES6 way of defining functions which lacks a few advantages and has a few problems that the modern approaches get right. – Sebastian Simon Nov 06 '22 at 09:00
  • Yeah, you can use a `function` instead if you want, arrow functions everywhere are just my preference. – CertainPerformance Nov 06 '22 at 14:38
  • Also, ,how can I call this function after an "onclick"? – Joseph Foley Nov 07 '22 at 07:46
  • @JosephFoley `someElement.addEventListener('click', () => populate(2016))` or, even better, add only a single event listener to a parent element and use a data attribute or the text content on the button to identify what image to insert – CertainPerformance Nov 07 '22 at 07:47
  • Thanks for your help. This works but only on a double click. Is there any reason for this? – Joseph Foley Nov 07 '22 at 08:15
  • nevermind, I figured it out now – Joseph Foley Nov 07 '22 at 09:18