I am trying to make a loop that will display some images and add an event listener to each image which, when clicked will assign the appropriate value to humanGoal. I have:
var humanGoal;
function displayPicker(round){
for(var i = 0; i <= round; i++){
document.write('<img src=img/die' + i + '.png id="' + 'picker' + i + '">');
document.getElementById('picker'+i).addEventListener("click", function () {
humanGoal = i;
document.write('you picked ' + humanGoal );
});
}
}
why does humanGoal always === round+1, instead of the variable i from the for loop?
The humanGoal variable is being overwrited with every for loop iteration and holds the round + 1 value at the end. Different words speaking - it will always display a wrong index.
Solution: apply same class to the each img element, bind a click event listener and display the actual index by passing i variable inside the Array#forEach function.
function displayPicker(round){
for (var i = 0; i <= round; i++){
document.write('<img src=img/die' + i + '.png id="' + 'picker' + i + '" class="img">');
}
var elems = document.getElementsByClassName('img');
Array.from(elems).forEach((v,i) => v.addEventListener('click', function() {
console.log(`You picked ${i}`);
}));
}
displayPicker(5);
See answer to your question is simple, when you were trying to assign human goal with value of i, the loop is already been iterated over "rounds" value that why you always getting i === round inside click function.
See the below code snippet,
<html>
<script>
var humanGoal;
function displayPicker(round){
for(var i = 0; i <= round; i++){
document.write('<img src=img/die' + i + '.png id="' + 'picker' + i + '">');
document.getElementById('picker'+i).addEventListener("click", function () {
console.log("me getting called second");
humanGoal = i;
document.body.append('you picked ' + humanGoal );
});
console.log("me getting called first");
}
}
</script>
<body onload="displayPicker(4)">
</body>
</html>
for getting the correct result you can follow the approach provided by #Kind user
Related
I'm creating a front-end page where user can create textarea by pressing a button and then save the information in the localStorage. When the load button is pressed, the same number textareas appear and their content comes from the localStorage. The problem is that when I retrieve the info from the localStorage, the value has "", which I want to remove.
I have tried replace(/"([^"]+(?="))"/g, '$1');
i = localStorage.getItem('AllNum');
// Allnum is the is where the generated textareas are placed
function add() {
//i represents the number of textareas
i++;
$('#alltxt').append('<div class="textarea"><input></input><textarea id="txt' + i + '"></textarea></div>');
}
function save() {
for (var a = 1; a <= document.getElementById("alltxt").childElementCount; a++) {
localStorage.setItem("txt" + a, document.getElementById('txt' + a).value);
}
localStorage.setItem('AllNum', i);
}
function load() {
if (document.getElementById("alltxt").childElementCount < localStorage.getItem('AllNum')) {
for (var i = 1; i <= localStorage.getItem('AllNum'); i++) {
$('#alltxt').append('<div class="textarea"><input></input><textarea id="txt' + i + '">"' + invert(i) + '"</textarea></div>');
}
}
}
function invert(i) {
var a = localStorage.getItem('txt' + i);
a = a.replace(/"([^"]+(?="))"/g, '$1');
return a;
}
https://codepen.io/abooo/pen/RvbOzV?editors=1010
To test the code generate some textareas, then enter some values in them and press +. After this reload the page. Finally click Load button. You can see that 123 changed into "123"
The problem is that you have "" around the text you are putting in.
In your load function, change "' + invert(i) + '" to ' + invert(i) + ' (Remove the two ").
I was given this task with some existing code to change the string color of each of three selector.value(s) that is output onto an input element to three different colors. The code boils the three selectors into a single output variable. Without destroying the code, I cannot figure out how to select each individual variables prior to condensing them.
If I could use the fontcolor() method, my life would be great but it's 2018 and I can't. Is there any way you can think of to solve this issue?To clarify, I need to alter the colors of the strings that belong to output(red), select1.value(blue) and select2.value(black.
Most of the action for this is happening in the parseOutput() function but I'm just stuck and don't think it's possible without rewriting the entire program.
function updateSelector(result){
var options = result.options;
var elementId = "select" + result.element;
var logger = document.getElementById('logger');
var selector = document.getElementById(elementId);
//logger.innerHTML = JSON.stringify(elementId);
selector.innerHTML = options;
selector.disabled = false;
}
google.script.run.withSuccessHandler(updateSelector).processOptions(0);
plate();
function resetAll(){
for (var i = 0;i<3;i++){
var selector = document.getElementById('select' + i);
selector.disabled = true;
selector.innerHTML = "";
}
google.script.run.withSuccessHandler(updateSelector).processOptions(0);
}
function finalSelection(){
var output = document.getElementById('out');
//output.focus();
output.select();
}
function plate(){
var plate = document.getElementById('plate');
plate.innerHTML = atob('Q3JhZnRlZCBieTogWmFjaGFyeSBTdGFjaG93aWFr');
}
//Adds the location as initial output, followed by divider, application, and issue if select1 is selected
//else statement added so if select0 is [Costco Website Name], to ommit the " - "
function parseOutput(){
var output = "";
if (select1.value.length > 0 && select0.value !== "[Costco Website Name]"){
output = output + ' - ' + select1.value + ' // ' + select2.value;
} else{
output = output + select1.value + ' // ' + select2.value;
}
out.value=output.trim();
}
And this is the Div that displays the output:
<div class="wide"><p><input class="wide" type="readonly" id="out" onfocus="this.select();"></p></div>
A modern replacement for fontcolor would use a span and a style (or class), e.g.:
function modernFontColor(str, color) {
return '<span style="color: ' + color + '">' + str + '</span>';
}
or
function modernFontClass(str, cls) {
return '<span class="' + cls + '">' + str + '</span>';
}
...where the class defines the styling.
Please tell me solution of this problem.
I am creating 5 dynamic divs and their ids using a for loop. I want to get the the loop counter value and each of the created div's html in the format "counter: html" like 1:123. Right now I am getting only the loop counter value.
<html>
<div id="feed"></div>
</html>
<script>
for (var i = 1; i <= 5; i++) {
$('#feed').append('<div id="news' + i + '" value='
123 '/>');
var abc = $("#news" + i).attr("value");
console.log(abc);
}
</script>
Thanks in advance.
Try this.
$(document).ready(function() {
for (var i = 1; i <= 5; i++) {
$('#feed').append('<div id="news' + i + '" value="123"></div>');
//and I want to get the value of dynamic created div using this code but I am getting only the loop counter value. Please help me to get this answer.
var abc = $("#news" + i).attr('value');
console.log(abc + " : " + i);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<html>
<div id="feed"></div>
</html>
This snippet doesn't even work for me, this however, does:
for (var i = 1; i <= 5; i++) {
$('#feed').append('<div id="news' + i + '" value="123"/>');
var abc = $("#news" + i).attr("value");
console.log(abc);}
I simply changed the single quotes of value='123' to double quotes: value="123".
Don't use ids use a class
'<div id="news' + i + '" value='123'/>' should be '<div class="news">123</div>'
Use .html() not .attr("value")
for (var i = 0; i <= 4; i++) {
$('#feed').append('<div class="news">123</div>');
var abc = $('.news').eq(i).html(); // gets the html of the div with the class "news" at the index supplied by `i`, keep in mind that arrays are 0 based so 0 is the first, 1 is the second....
console.log((i+1)+':'+abc);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="feed"></div>
updating the answer as per the updated question. This code will work for you. Give it a try.
for (var i = 1; i <= 5; i++) {
$('#feed').append('<div id="news' + i + '">'+ i +': Test</div>');
}
But I tell you again not to use the value tag, you already have your counter in id so split it fro there if you want.
Cheers!!
You're using id's. You can't use an id on multiple divs, so you need to use class.
Not quite sure what you want, and div tag not supposed have value attribute, if you want to add your defined attribute use data-my_attribute instead. In your code, everything is ok except for this code :
Change this :
$('#feed').append('<div id="news' + i + '" value='123'></div>');
into this :
$('#feed').append('<div id="news' + i + '" value="123"></div>');
I seem to somehow be losing the value of a variable im setting...
What im trying to do is not so important, so I've set up a (Well commented) jsFiddle to show you what im getting. Also the code is below.
If anyone can see whats going on any help is appreciated :)
See jsFiddle > http://jsfiddle.net/qNWuV/4/ < Recommend you take a look here
var habs = ["417,77", "410,363", "388,433", "262,435", "262,210", "391,101", "384,183", "61,114", "331,171", "164,433", "361,248", "302,329", "154,307", "410,350", "173,298", "308,429"]; //just an array of co-ords for another part of my app. Only the .length is used below.
//############################
// NOTE: as this problem depends on random numbers you MAY not see it. If "undefined" is ANYWHERE in the Result, the problem is occurring, otherwise re-run the code.
//############################
function link_habs(habs) {
var test2 = '';
var hab_length = habs.length;
for (var e in habs) {
var hab_link_1 = get_link(hab_length, e + ',');
var hab_link_2 = get_link(hab_length, e + ',' + hab_link_1);
document.write('<br /><br />each1: ' + hab_link_1); //Variable lost?
document.write('<br />each2: ' + hab_link_2 + '<br />'); //Variable lost?
test2 += e + ':' + hab_link_1 + ',' + hab_link_2 + '<br />';
}
document.write('<br /><br /><br />' + test2);
}
function get_link(count, not) {
var nots = not.split(',');
for (var i in nots) { nots[i] = parseInt(nots[i], 10); }
var hab_link = Math.floor(Math.random() * count);
if (nots.indexOf(hab_link) === -1) {
document.write('<br />returned: ' + hab_link); //Variable is intact HERE
return hab_link;
} else {
get_link(count, not);
}
}
link_habs(habs);
Cheers
Charlie
You are not returning the value from the recursive call.
Change:
get_link(count, not);
into:
return get_link(count, not);
In the get_link function, you are traversing the nots array using for / in. You should use a regular for loop.
Given:
// Positions the bars relative to scale
this.gDrawBars = function() {
// Go through all the bars
for (i = 0; i < this.gData.length; i++) {
// Check part of it is within range
if (this.gDisplayFrom < this.gData[i][2] || this.gDisplayTo > this.gData[i][1]) {
// Is the entire bar showing
var isEntireBarInRange = (this.gDisplayFrom < this.gData[i][2] && this.gDisplayTo > this.gData[i][1]);
var div = document.createElement('div');
div.id = "gBar" + i;
div.className = 'gBar';
div.innerHTML = this.gData[i][0];
var self = this;
div.onmouseover = function() {
gBarHighlight(this, this.gData[i][1], this.gData[i][2]);
};
div.onmouseout = function() {
gBarUnHighlight(this, this.gData[i][1], this.gData[i][2]);
};
this.gContainer.appendChild(div);
//this.gContainer.innerHTML += "<div id=\"gBar" + i + "\" class=\"gBar\" onmouseover=\"gBarHighlight(this, '" + this.gData[i][1] + "', '" + this.gData[i][2] + "')\" onmouseout=\"gBarUnHighlight(this, '" + this.gData[i][1] + "', '" + this.gData[i][2] + "')\">" + this.gData[i][0] + "</div>";
The commented line at the bottom works fine, but I'm trying to change it to add these functions dynamically. It needs to pass this.gData[i][1] into the functions but it can't, because the i value has no meaning outside the loop.
How can I get around this? IE, make the function recognise it's being passed a value to use and not a reference.
You need to retain the value of i in a new execution context.
Place the code that assigns the handlers into a named function, and call that in the loop, passing i as an argument.
Place this function before the for loop:
function setupMouseOverOut( el, i ){
el.onmouseover = function() {
gBarHighlight(this, this.gData[i][1], this.gData[i][2]);
};
el.onmouseout = function() {
gBarUnHighlight(this, this.gData[i][1], this.gData[i][2]);
};
}
...then call it in the for loop:
setupMouseOverOut( div, i );
This way the value of i that you passed out of the for loop is retained in the new execution context of the setupMouseOverOut() function call, and the new functions you set as handlers will refer to that local variable.
It's not a function, it's an event. You need to add it as an event to the element:
div.addEventListener('mouseover', function() {
// ...
});
Note that when you do it this way you don't have that 'on' word there.