Why this Javascript code does not work as expected? [duplicate] - javascript

This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 5 years ago.
I am learning Javascript language and so I am on a project while I came across this issue. Here is the code:
function koko() {
items = document.getElementsByTagName("a");
for (var pos = 0; pos < items.length; pos++) {
this.items[pos].addEventListener("click", function() {
console.log(pos);
});
}
}
koko();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
Click me 1
Click me 2
Click me 3
</body>
</html>
Every time I click on any item with a tag I get same value on the console that is items.length. But I am expecting it to print the position/index of the element that is clicked. For example, if I click Click me 2 it should print 1. What am I missing here?

When the click listener is executed, pos has the value of 3, your code is fine, look at this example:
function koko() {
items = document.getElementsByTagName("a");
for (var pos = 0; pos < items.length; pos++) {
this.items[pos].addEventListener("click", function() {
console.log(this.innerHTML);
});
}
}
koko();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
Click me 1
Click me 2
Click me 3
</body>
</html>

Try this for the desired results
function koko() {
items = document.getElementsByTagName("a");
for (var pos = 0; pos < items.length; pos++) {
this.items[pos].id = pos;
this.items[pos].addEventListener("click", function() {
console.log(this.id);
});
}
}
koko();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
Click me 1
Click me 2
Click me 3
</body>
</html>

You function logs pos, WHEN the button is clicked, not when the event listener is added. To fix this, you can use this code:
function koko() {
items = document.getElementsByTagName("a");
for (var pos = 0; pos < items.length; pos++) {
this.items[pos].addEventListener("click", function() {console.log(this.id);});
}
}
koko();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
Click me 1
Click me 2
Click me 3
</body>
</html>
The changes it makes from the original code:
Added id to each link. The number in this is written to the screen.
Changed Javascript to write the id of the link.

Related

How to track clicks of a button?

I’m trying to track the clicks on a button on my website. I’ve tried adding the following but to no success. I’m a noob to JS..
function trackButton(e) {
onPage.innerHTML = ++i;
}
var i = 0;
var onPage = document.getElementById(‘track’);
var clickCount = document.getElementById(‘bttn’);
clickCount.addEventListener('click', function (e) {
addOne(e);
}, false);
You did some mistake:
The function addOne doesn't exist, it's trackbutton
it's i++ to increment a value, not ++i
And some tips for you:
Use let and const (ES6) for the variable, not var
And the e for the event is useless here, you are not using it, so it's not mandatory here
Do these change and it must work !
UPDATE:
To increment a value ++i works, see the documentation
Change the quotes ‘‘ with " " or ' '.
Like so: document.getElementById(‘track‘) to document.getElementById('track')
I was checkin your code and its almost all right, i think that the problem its in your addOne function, here is a way to resolve the problem.
i creat the button and paragraph elements in html and in javascript a variable n where we are going to storage the clicks tha the user did and we increment n when the function its called in the button's event
var n = 0;
var button = document.getElementById('track');
button.addEventListener('click', trakeo);
var texto = document.getElementById('number');
function trakeo(){
n++
texto.innerHTML = n;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>A Great Demo on CodePen</title>
</head>
<body>
<button id="track">Button</button>
<p id="number"></p>
</body>
</html>
Try to use
addEventListener('click',)
https://www.w3schools.com/jsref/met_element_addeventlistener.asp

While True loop prevents page from loading

I apologise if my question seems simple, I am still trying to figure out JavaScript. I am building a website where I want the contents of a <p> to constantly change. I want it to loop over the contents of an array defined in my javascript code. However, when I put everything in a while (true) (because I want it to happen constantly), the <p> content never changes and the page is stuck on loading.
Here is the code I have so far:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="about.css">
<meta charset="UTF-8">
<title>My Site</title>
</head>
<script>
function changeDynamicText() {
var descriptions = ['list', 'of', 'strings', 'to', 'loop', 'over'];
let i = 0;
while (true) {
window.setTimeout(function() {
document.getElementById("dynamicline").innerHTML = descriptions[i];
}, 600);
i = i + 1;
if (i >= descriptions.length) i = 0;
}
}
</script>
<body onload="changeDynamicText()">
<p id="dynamicline">Starting Text</p>
</body>
</html>
Help of any kind is greatly appreciated.
When you use while(true), it will block the JavaScript event loop and therefore no longer render the rest of the body.
You can achieve what you're trying to do by working asynchronously. You already did use setTimeout in there, but you could also use setInterval to trigger the method on a recurring basis.
function changeDynamicText() {
var descriptions = ['list','of','strings','to','loop','over'];
let i = 0;
setInterval(function () {
document.getElementById("dynamicline").innerHTML = descriptions[i];
i = i + 1;
if (i >= descriptions.length) i = 0;
}, 600);
}
You can use setInterval instead.
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="about.css">
<meta charset="UTF-8">
<title>My Site</title>
</head>
<script>
function changeDynamicText() {
var descriptions = ['list','of','strings','to','loop','over'];
let i = 0;
setInterval(() => {
document.getElementById("dynamicline").innerHTML = descriptions[i];
i = (i + 1) % descriptions.length;
}, 600)
}
</script>
<body onload="changeDynamicText()">
<p id="dynamicline">Starting Text</p>
</body>
</html>
You can easily do this with setInterval instead of setTimeout. Use setInterval when you need something to constantly do something in periods of time.
And I moved the i manipulation inside of the interval because you want that to execute each time the function gets called.
Also, it's just a really good habit to get into to put your script tags as the very last element of the body in the HTML document. This way you can ensure that all DOM content has loaded before attempting to manipulate the DOM.
Here is a JSFiddle with the code below: https://jsfiddle.net/mparson8/41hpLaqw/2/
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="about.css">
<meta charset="UTF-8">
<title>My Site</title>
</head>
<body onload="changeDynamicText()">
<p id="dynamicline">Starting Text</p>
<script>
function changeDynamicText() {
var descriptions = ['list','of','strings','to','loop','over'];
let i = 0;
let interval = window.setInterval(function () {
document.getElementById("dynamicline").innerHTML = descriptions[i];
i = i + 1;
if (i >= descriptions.length) i = 0;
}, 600);
}
changeDynamicText();
</script>
</body>
</html>
while (true) always blocks the page until it finishes using a break statement, in your code is never finishing, so what you need to do is call the function itself in the timeout (and make i a global variable to keep track of the array position)
let i = 0;
function changeDynamicText() {
var descriptions = ['list','of','strings','to','loop','over'];
setTimeout(function () {
document.getElementById("dynamicline").innerHTML = descriptions[i];
changeDynamicText()
}, 600);
i = i + 1;
if (i >= descriptions.length) i = 0;
}
loops are blockers infinite loops are infinite blockers. What you need is a time based switcher - a built in timeout functionality which you can call in a cyclical manner - or a, on interval ticker. Any of them will do...
function changeDynamicText() {
var descriptions =
['list','of','strings','to','loop','over'];
var i = 0;
setInterval( tick, 800 );
function tick( ) {
dynamicline.innerHTML = descriptions[ i++ ];
if(i >= descriptions.length-1 ) i = 0
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="about.css">
<meta charset="UTF-8">
<title>My Site</title>
</head>
<script>
</script>
<body onload="changeDynamicText()">
<p id="dynamicline">Starting Text</p>
</body>
</html>

Auto Click all Links In Div ID

I have a WP blog page which shows recent posts using category shortcodes
On that page, i have a list of links leading to their posts.
I can't edit the links to add id or class to them, so i am manually using a div to wrap the shortcode and a javascript which makes the links open to new tab upon click, is there a way i can open all the links to new tabs open single click? (REMEMBER, I CANT EDIT THE LINKS)
Here is my codes
<!--- i cant edit the links below ----->
<div id="boss" class="boss">
Example 1
Example 2
Example 3
Example 4
</div>
JAVASCRIPT
<script type="text/javascript">
window.onload = function(){
var a = document.getElementById('boss').getElementsByTagName('a');
for (var i=0; i<a.length; i++){
a[i].setAttribute('target', '_blank');
}
}
</script>
am trying to load all the links to their new tabs upon click
<div onclick="boss();">Something To Click On</div>
ITS NOT WORKING, ANY HELP PLS?
Fullcode example:
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript">
function boss() {
var a = document.getElementById('boss').getElementsByTagName('a');
for (var i = 0; i < a.length; i++) {
a[i].setAttribute('target', '_blank');
openNewTab(a[i], "click");
}
}
function openNewTab(obj, evtName) {
try {
if (obj.dispatchEvent !== null && obj.dispatchEvent !== undefined) {
//var event = new Event(evtName);
var event = document.createEvent("MouseEvents");
event.initMouseEvent(evtName, true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
obj.dispatchEvent(event);
} else if (obj.fireEvent !== null && obj.fireEvent !== undefined) {
event = document.createEventObject();
event.button = 1;
obj.fireEvent("on" + evtName, event);
obj.fireEvent(evtName);
} else {
obj[evtName]();
}
} catch (e) {
alert(e);
}
}
</script>
</head>
<body>
<div onclick="boss();">Something To Click On</div>
<div id="boss">
Example 1
Example 2
Example 3
Example 4
</div>
</body>
</html>
That would be easy with jQuery. You can use .each() and .attr() to achieve it.
NOTE
Try this script in your WordPress. Since the below output is a iframe, it won't work!
$ = jQuery;
$(document).ready(function(){
$("#boss > a").each(function(){
$(this).attr("target","_blank");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="boss" class="boss">
Example 1
Example 2
Example 3
Example 4
</div>
Good Luck :)

How can I get answer on same page instead of an alert?

I want a button that every time you click it it gives you a different answer(Animals, Movies or TV Shows, and so on), the thing is I have a button (that I found online, I'm new at coding) but that button gives me the answer in a little alert box, is there a way to make it give me the answer below the button? Here's the code I found:
var words = ['Animals', 'Movies', 'TV Shows'];
function randomAlert() {
var alertIndex;
var randomValue = Math.random();
if (randomValue < 0.5) {
alertIndex = 0;
}
else if(randomValue < 0.8) {
alertIndex = 1;
}
else {
alertIndex = 2;
}
alert(words[alertIndex]).innerHTML
}
You can just get rid of the alert call and insert it into a div, span, h1, whatever. Here's an example out of the many ways:
var words = ['Animals', 'Movies', 'TV Shows'];
function randomSelect() {
var index;
var randomValue = Math.random();
if (randomValue < 0.5) {
index = 0;
}
else if(randomValue < 0.8) {
index = 1;
}
else {
index= 2;
}
document.getElementById('answer').innerText = words[index]; //Get's an element of id 'answer'
}
randomSelect(); //Executes function
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="answer">
<!-- Answer is inserted into here !-->
</div>
</body>
</html>
The above get's an element of id answer and inserts it into the element's text. This is done by accessing the innerText attribute of the element, which returns the text of the element. I then reassign the value to the index. This is quite a simple way of doing it, and I cleaned up some of the names of functions, variables.

Show changes from an currently executing for loop

I could need some help, or maybe just an answer. Is there a way to show changes made by aa js within an executing for loop ? I know there is a way with setInterval, but I have an example with a greater progress where I need it to progress the problem with a for loop. So here is my try:
<!doctype html>
<html>
<head>
<title>life change test</title>
<meta charset="UTF-8">
</head>
<body>
<div id="wrapper">
</div>
<script type="text/javascript">
var el = document.getElementById("wrapper");
/*var i = 0;
var counter = setInterval(function(){
el.innerHTML = i;
i++;
if(i == 18000){
clearInterval(counter);
}
}, 10);*/
for (var i = 400000; i >= 0; i--) {
el.innerHTML = i;
};
</script>
</body>
</html>
My Firefox just freezes until it is completely done, and than displays the result. Is there a chance to actually see the progress ?

Categories