I think you do not need multiple functions here. You can pass this to the function and refer that inside function.
Please Note: The return value of addEventListener is undefined.
Try the following way:
let airClick = document.querySelector('#Air').addEventListener('click', function(){getUserChoice(this)});
let fireClick = document.querySelector('#Fire').addEventListener('click', function(){getUserChoice(this)});
let waterClick = document.querySelector('#Water').addEventListener('click', function(){getUserChoice(this)});
function getUserChoice(el) {
var imageUrl = '';
if(el.id == 'Air')
imageUrl = 'https://media1.giphy.com/media/RK7pdHVS4N7he/source.gif';
if(el.id == 'Fire')
imageUrl = 'https://i.gifer.com/5NOX.gif';
if(el.id == 'Water')
imageUrl = 'https://media2.giphy.com/media/kTEpI5N6y0bUA/source.gif';
el.style.backgroundImage = `url(${imageUrl})`;
el.firstElementChild.style.opacity = 0.4;
}
Solution 3 :
Adding only slight modification to your existing code:
// Im trying to make these variables have a string return value of their name using a function, as well as applying certain style changes all at once.
let airClick = document.querySelector('#Air').addEventListener('click', getUserChoice().airAfterClick);
let fireClick = document.querySelector('#Fire').addEventListener('click', getUserChoice().fireAfterClick);
let waterClick = document.querySelector('#Water').addEventListener('click', getUserChoice().waterAfterClick);
function getUserChoice() {
function airAfterClick() {
let air = document.querySelector('#Air')
air.style.backgroundImage = "url('https://media1.giphy.com/media/RK7pdHVS4N7he/source.gif')";
air.firstElementChild.style.opacity = 0.4;
return "air"
}
function fireAfterClick() {
let fire = document.querySelector('#Fire')
fire.style.backgroundImage = "url('https://i.gifer.com/5NOX.gif')";
fire.firstElementChild.style.opacity = 0.4;
return "fire"
}
function waterAfterClick() {
let water = document.querySelector('#Water')
water.style.backgroundImage = "url('https://media2.giphy.com/media/kTEpI5N6y0bUA/source.gif')";
water.firstElementChild.style.opacity = 0.4;
return "water"
}
return {
airAfterClick,
fireAfterClick,
waterAfterClick
}
}
<button id="Air">
<p>
Air
</p>
</button>
<button id="Fire">
<p>
Fire
</p>
</button>
<button id="Water">
<p>
Water
</p>
</button>
You need to return the inner functions from the main function getUserChoice so that it can be listened to by click listeners in the buttons.
Solution 4 :
Better to share the work of a small function.
Added a separate object with pictures.
When you click on an element, you send the element that e.target clicked on and the value is fire, wather or air
When processing a click, you call a function that substitutes the background, and then send data to the server.
backgrounds = {
'air': "url('https://media1.giphy.com/media/RK7pdHVS4N7he/source.gif')",
'fire': "url('https://i.gifer.com/5NOX.gif')",
'water': "url('https://media2.giphy.com/media/kTEpI5N6y0bUA/source.gif')"
}
let airClick = document.querySelector('#Air').addEventListener('click', function(e) {getUserChoice(e.target, 'air')});
let fireClick = document.querySelector('#Fire').addEventListener('click', function(e) {getUserChoice(e.target, 'fire')});
let waterClick = document.querySelector('#Water').addEventListener('click', function(e) {getUserChoice(e.target, 'water')});
function getUserChoice(el, type) {
function setBackground(el, type) {
el.style.backgroundImage = backgrounds[type];
// el.firstElementChild.style.opacity = 0.4;
}
function sendDataToServer(type) {
console.log('send ' + type + ' to computer');
}
setBackground(el, type);
sendDataToServer(type);
}
Instead, what you can do is pass an anonymous function to the event handler, call your method which returns a value and use it as appropriate
function airClick()
{
var ele = document.getElementById("Air");
ele.addEventListener("click", function(event){
var result = getUserChoice(event);
// result is your return value
}, false);
}
Problem :
// Im trying to make these variables have a string return value of their name using a function, as well as applying certain style changes all at once.
let airClick = document.querySelector('#Air').addEventListener
('click', getUserChoice);
let fireClick = document.querySelector('#Fire').addEventListener
('click', getUserChoice);
let waterClick = document.querySelector('#Water').addEventListener
('click', getUserChoice);
function getUserChoice() {
function airAfterClick() {
let air = document.querySelector('#Air')
air.style.backgroundImage = "url('https://media1.giphy.com/media/RK7pdHVS4N7he/source.gif')";
air.firstElementChild.style.opacity = 0.4;
return "air"
}
function fireAfterClick() {
let fire = document.querySelector('#Fire')
fire.style.backgroundImage = "url('https://i.gifer.com/5NOX.gif')";
fire.firstElementChild.style.opacity = 0.4;
return "fire"
}
function waterAfterClick() {
let water = document.querySelector('#Water')
water.style.backgroundImage = "url('https://media2.giphy.com/media/kTEpI5N6y0bUA/source.gif')";
water.firstElementChild.style.opacity = 0.4;
return "water"
}
}
So what I’m trying to do here is so that when a user clicks on one of the elements on the player side, certain styles activate, for example changing the air element’s background to a gif of a tornado once it’s clicked, as well as doing certain other actions, more importantly returning a string value of whatever the element name is. That way I can use it as a return value and then do comparisons with the computer’s choice.
However I don’t know how to exactly do this, and Im not really sure Im formatting my code correctly. But from what I’m attempting to do in my code is to have multiple functions within a function of getUserChoice which activates any of the functions inside of it once it is clicked.
I just have a couple hangups if im going about this the right way. Or if there’s an easier way.
1.) If im doing functions within functions should I use an IF statement that activates the function depending on whats clicked? Is that even possible?
2.) Would it make more sense to do the addEventListener inside of the getUserChoice function instead?
Thank u guys for all the help!
Comments
Comment posted by Josemari Bautista
Hi thanks a lot, this solution worked the best for me! But I still have a couple questions about it, how can I use the return value of what was clicked? For exampe say I wanted to return the string “fire” after the fire element was clicked. Would I have to create a separate variable to store that information?
Comment posted by mplungjan
Depends on where and for what you want to use it. You can creat a global var like currentElement and set that in the click handler
Comment posted by Titus
There are a couple of problems with this solution. First
Comment posted by mplungjan
If the return value of addEventListener is undefined why do you still have it? I think my version is more elegant
Comment posted by mplungjan
What is the rationale to nest the functions like that instead of making them members
Comment posted by Nuhman
@mplungjan Yea you’re right. I was thinking of the same but couldn’t think of any possible advantage. Please let me know if any. Also wanted only to make minimal changes to OP’s code.
Comment posted by mplungjan
addEventListener does not return anything. Also DRY (Don’t repeat yourself) See my answer for a more elegant way of not having to add type everywhere