for loop an argument in function - javascript

I was doing this code but it will take time because it will be h1 up until h24 so i decided to use a for loop but i don't know how..
this is my original code
function hover(h1,h2,h3,h4){
document.getElementById(h1).style.backgroundColor="orange";
document.getElementById(h2).style.backgroundColor="orange";
document.getElementById(h3).style.backgroundColor="orange";
document.getElementById(h4).style.backgroundColor="orange";
}
and i want to replace it something like this
function hover(
for(i = 1; i<=24; i++) {
document.write("h"+i+",");
}
)
but there is an error.. Please help me out.. Thank you

function hover() {
for(var i = 1; i < 25; i++) {
document.getElementById("h" + i).style.backgroundColor="orange";
}
}
If you could need more control, you could set the upper limit as a parameter, e.g.
function hover(limit) {
for(var i = 1; i <= limit; i++) {
document.getElementById("h" + i).style.backgroundColor="orange";
}
}
A call to hover(10); would change the background colour of h1 through h10.

There are several things wrong with the code you posted. I think I understand the problem you are trying to solve though. Try something like this:
function hover(eleId){
document.getElementById(eleId).style.backgroundColor="orange";
}
for(i=1; i<=24; i++){
hover("h"+i.toString());
}
Also note h1, h2, h3 all look like HTML tags. Check out getElementsByTagName.

You need to use Javascript's arguments object
function hover() {
var args = Array.prototype.slice.call(arguments);
var length = args.length;
for (var i = 0; i < length; i++) {
document.getElementById(args[i]).onmouseover =
function () { this.style.backgroundColor = "orange"; }
document.getElementById(args[i]).onmouseout =
function () { this.style.backgroundColor = "transparent"; }
}
}
jsFiddle Demo
HTML:
<div id="h1">A</div>
<div id="Hello">B</div>
<div id="box">C</div>
<div id="World">D</div>
JS Call:
hover("h1", "Hello", "box", "World");

Here is my suggestion :
<div id="h1">test</div>
<div id="h2">test</div>
<div id="h3">test</div>
<div id="h4">test</div>
script, notice the dummy variable
<script>
function hover(dummy){
for (var i=0; i<arguments.length; i++) {
var element = document.getElementById(arguments[i]);
element.onmouseover = function() {
this.style.backgroundColor="orange";
}
element.onmouseout = function() {
this.style.backgroundColor="white";
}
}
}
//hover('h1','h2','h3','h4');
for (var i=1;i<=24;i++) {
hover('h'+i);
}
</script>

Related

Javascript Pass parameter to function inside variable

I'm trying to assign a click handler to a JQuery object, defined in a variable :
some.object.array[8].action = function(data){console.log(data);}
anotherobject = {..}
now inside some loop, I need to assign this function to the click handler:
and want to pass the whole 'anotherobject' object
for (var i = 0; i < foo.length; i++) {
$('<div/>').click(some.object.array[i].action);
}
But how can I pass the parameter?
If I encapsulate it inside some anonymous function, I'm losing my scope...:
for (var i = 0; i < foo.length; i++) {
$('<div/>').click(function() {
some.object.array[i].action(anotherobject)
});
}
because i has changed...
How are we supposed to do this?
There are just too many ways to do this:
for (var i = 0; i < foo.length; i++) {
(function(i) {
$('<div/>').click(function() {
some.object.array[i].action(anotherobject);
});
})(i);
}
Or
for (var i = 0; i < foo.length; i++) {
$('<div/>').data("i", i).click(function() {
var i = $(this).data("i");
some.object.array[i].action(anotherobject);
});
});
}
Or
function getClickHandler(callback, parameter) {
return function() { callback(parameter); };
};
for (var i = 0; i < foo.length; i++) {
$('<div/>').click(getClickHandler(some.object.array[i].action, anotherobject));
}
If you want your action function to maintain the div as this and still accept the jQuery event object, you can use bind like this example:
function action(another, event){
console.log(this, arguments);
}
$(function(){
for (var i = 0; i<10; i++) {
var anotherObject = "another"+i;
var div = $('<div>'+i+'</div>');
// force 'this' to be 'div.get(0)'
// and 'arg0' to be 'anotherObject'
div.click(action.bind(div.get(0),anotherObject));
$("body").append(div);
}
})
Example: https://jsfiddle.net/Lwe5b9cx/ You'll need to open the console to see the output, which should look like this:
for(var i = 0; i < foo.length; i++)
{
$('<div/>').click(
(
return function(callback){
callback(anotherobject)
}
)(some.object.array[i].action)
);
}

If data attribute above X number add class to element

I need to add Class highpc to each element with the data attribute of procent, which is bigger than 51. I've got a jQuery solution, but I need it in pure JavaScript. Can anyone help me? This is what I got so far:
HTML
<span data-procent="4" class="procent">4%</span>
<span data-procent="59" class="procent">59%</span>
JS
function highpc(){
var procent = this.elem.getAttribute("data-procent");
if (parseInt(procent) > 51) {
procent.className=procent.className+" highpc";
}
}
window.onload = highpc();
http://jsfiddle.net/Zc8vY/1/
You haven't specified what is this.elem, and you haven't loop in your script.
You are also using variable procent for getting the data-attribute from your element. Later, you are trying to use it for linking the element. Try updated code:
function highpc(){
var elements = document.getElementsByClassName('procent');
for(i=0;i<elements.length;i++) {
var procent = elements[i].getAttribute("data-procent");
if (parseInt(procent) > 51) {
elements[i].className=elements[i].className+" highpc";
}
}
}
Updated fiddle http://jsfiddle.net/Zc8vY/4/
This is your fixed function:
function highpc() {
var elements = document.querySelectorAll('.procent');
for (var i = 0; i < elements.length; i++) {
var procent = elements[i].getAttribute("data-procent");
if (parseInt(procent) > 51) {
elements[i].className += " highpc";
}
}
}
window.onload = highpc;
Note the last line: you don't need () after highpc because you want window.onload to be a reference to a function, not a result of execution.
References: querySelectorAll to select elements.
Demo: http://jsfiddle.net/Zc8vY/3/
Using pure javascript and implementing own getElementsByClassName.
function getElementsByClass(className){
var celems = new Array();
var elems = document.getElementsByTagName("*");
for(var i = 0; i < elems.length;i++){
if(elems[i].className.indexOf(className) != -1){
celems.push(elems[i]);
}
}
return celems;
}
function highpc(){
var elems = getElementsByClass("procent");
console.log(elems);
for(var i = 0; i < elems.length; i++){
highpc_ex(elems[i]);
}
}
function highpc_ex(elem){
var procent = elem.getAttribute("data-procent");
if (parseInt(procent) > 51) {
elem.className=elem.className+" highpc";
}
}
window.onload = highpc();
WORKING FIDDLE HERE
function highpc() {
var aSpans = document.getElementsByTagName("span");
for(var i = 0; i < aSpans.length; i++) {
var eSpan = aSpans[i];
var procent = eSpan.getAttribute("data-procent");
if (procent != null && parseInt(procent) > 51) {
eSpan.className += " highpc";
}
}
}
This is a similar variant to what others have already posted. You might find this one to be more performant for larger sets of html.
Ref: Why .getElementsByTagName() is faster than .querySelectorAll()

Setting onclick function to <li> element

I am trying to dynamically add onclick function to "li" tagged elements.
But the event does not fires.
Here is my code:
var arrSideNavButtons = [];
var sideNavLi = document.getElementsByClassName('side-nav')[0].getElementsByTagName('li');
var arrayOfSceneAudios = [scene1Audio, scene2Audio,...];
for (var i = 0; i < sideNavLi.length; i++) {
sideNavLi[i].onclick = function() {
arrayOfSceneAudios[i].play();
}
arrSideNavButtons.push(sideNavLi[i]);
}
Is it possible to code it this way?
If yes, what is my mistake?
Thanks a lot.
Wrap your onclick handler in a closure, else it only get assigned to the last elem in the loop:
for (var i = 0; i < sideNavLi.length; i++) {
(function(i) {
sideNavLi[i].onclick = function() {
arrayOfSceneAudios[i].play();
}
arrSideNavButtons.push(sideNavLi[i]);
})(i)
}
I think it's better to reuse one single function, instead of creating a new one at each iteration:
var arrSideNavButtons = [],
sideNavLi = document.getElementsByClassName('side-nav')[0].getElementsByTagName('li'),
arrayOfSceneAudios = [scene1Audio, scene2Audio,...],
handler = function() {
this.sceneAudio.play();
};
for (var i = 0; i < sideNavLi.length; i++) {
sideNavLi[i].sceneAudio = arrayOfSceneAudios[i];
sideNavLi[i].onclick = handler;
arrSideNavButtons.push(sideNavLi[i]);
}

Cross-browser getClassName JavaScript function

I'm working on a small project that needs to get all elements by className, there is obviously the HTML5 .getElementsByClassName, but I'm trying to create a little function that provides a small polyfill for it, it's just not working. any help much appreciated. Or if there is an easier way of doing this.
function getClassName(element) {
if(!document.getElementsByClassName(element)) {
var retnode = [];
var myclass = new RegExp('\\b'+element+'\\b');
var elem = this.getElementsByTagName('*');
for (var i = 0; i < elem.length; i++) {
var classes = elem[i].className;
if (myclass.test(classes)) retnode.push(elem[i]);
}
return retnode;
} else {
document.getElementsByClassName(element);
}
}
Then calling it like so:
document.getClassName('active'){
active.className += 'new';
}
Your function is wrong.
The name implies you are getting a class name, not an element.
You use the variable element when you mean className
check for support is wrong
if(!document.getElementsByClassName) {
missing return in else
return document.getElementsByClassName(element);
I would recommend sse the one from here or here to add the polyfill
Grab yourself an addClass method...something like
function hasClass(elem,className) {
return elem.className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'));
}
function addClass(elem,className) {
if (!hasClass(elem,cls)) elem.className += " "+className;
}
Than you will just do
var elems = document.getClassName('active');
for (var i=elems.length-1; i>=0; i--) {
addClass(elems[i],"active");
}

Javascript for loop and alert

I am looping through a list of links. I can correctly get the title attribute, and want it displayed onclick. When the page is loaded and when I click on a link, all of the link titles are alerted one by one. What am I doing wrong?
function prepareShowElement () {
var nav = document.getElementById('nav');
var links = nav.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].onclick = alert(links[i].title);
}
}
What you were doing was actually running the alert function.
enclosing the whole thing in an anonymous function will only run it when it is clicked
for (var i = 0; i < links.length; i++) {
links[i].onclick = function () {
alert(this.title);
}
}
You are assigning the onclick to the return value of alert(links[i].title); which doesn't make any sense, since onclick is supposed to be a function.
What you want instead is somethig like onclick = function(){ alert('Hi'); };
But
Since you are using a variable i in that loop you need to create a local copy of it
onclick = function(){ alert(links[i].title); }; would just use the outer scope i and all your links would alert the same message.
To fix this you need to write a function that localizes i and returns a new function specific to each link's own onclick:
onclick = (function(i){ return function(e){ alert(links[i].title); }; })(i);
Final result:
function prepareShowElement () {
var nav = document.getElementById('nav');
var links = nav.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].onclick = (function(i){ return function(e){ alert(links[i].title); }; })(i);
}
}
You can use jquery. To display title of the link on click.
$("#nav a").click(function() {
var title = $(this).attr('title');
alert(title);
});
links.forEach(function(link) {
link.onclick = function(event) {
alert(link.title);
};
}
Also note that your original solution suffered from this problem:
JavaScript closure inside loops – simple practical example
By passing in our iteration variable into a closure, we get to keep it. If we wrote the above using a for-loop, it would look like this:
// machinery needed to get the same effect as above
for (var i = 0; i < links.length; i++) {
(function(link){
link.onclick = function(event) {
alert(link.title);
}
})(links[i])
}
or
// machinery needed to get the same effect as above (version 2)
for (var i = 0; i < links.length; i++) {
(function(i){
links[i].onclick = function(event) {
alert(links[i].title);
}
})(i)
}
You need change .onclick for a eventlistener same:
function prepareShowElement () {
var nav = document.getElementById('nav');
var links = nav.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click',function() {
alert(links[i].title);
},false);
}
}

Categories

Resources