How to create a custom loop? - javascript

I made a custom loop that delays 300ms on it's each iteration. But in this loop, the line ul.syle.height = i + 'px'; is throwing a error that TypeError: Cannot set property 'height' of undefined at main.js
But the variable ul is working fine above at the line var ul_scrollHeight = ul.scrollHeight;.
Then why it is not working inside 'setTimeout'? Here getNextSibling is another function in my code.
function fun1() {
var ul = getNextSibling(this);
var ul_scrollHeight = ul.scrollHeight;
var i = 1;
function customLoop() {
setTimeout(function () {
ul.syle.height = i + 'px'; // Not Working
if (i <= ul_scrollHeight) {
customLoop();
}
}, 300)
}
customLoop();
}

I think you just have a typo on that line:
ul.syle.height = i + 'px';
Because ul.syle is missing a t, so that returns undefined, which did not have a property height. 🙂

Related

A function inside javascript if condition is not getting called

I am new to Js and trying to develop program which can move object in zig zag format across canvas, i wrote this function but it not getting called when i run program. If anyone can check out my code it would be really helpful, thanks also like to mention that all previous functions in code are working fine but this specific function is not getting called program run until If condition but skip the function part. Also i am not looking to work with Jquery or CSS right now
if (rightPos) {
function myInterval3() {
console.log('hello');
var eLeftPos1 = e.offsetLeft;
//console.log(e.offsetLeft);
e.style.left = (eLeftPos1 + s) + 'px';
//console.log(e.style.left);
}
}
var e = document.getElementById("aDiv");
var s = 1;
function myInterval() {
var eLeftPos = e.offsetLeft;
//console.log(e.offsetLeft);
e.style.left = (eLeftPos + s) + 'px';
//console.log(e.style.left);
leftPos = (eLeftPos + s) >= 300
if (leftPos) {
function myInterval1() {
console.log(leftPos)
var eTopPos = e.offsetTop;
//console.log(e.offsetLeft);
e.style.top = (eTopPos + s) + 'px';
//console.log(e.style.top);
topPos = (eTopPos + s) >= 100
if (topPos) {
clearInterval(internal1)
}
if (topPos) {
function myInterval2() {
var eRightPos = e.offsetLeft;
//console.log(eRightPos)
e.style.left = (eRightPos - 9) + 'px'
/*console.log(e.style.left)*/
rightPos = (eRightPos - 9) <= 20
if (rightPos) {
clearInterval(interal2)
}
}
var interal2 = setInterval(myInterval2, 10)
}
}
var internal1 = setInterval(myInterval1, 100);
if (rightPos) {
function myInterval3() {
console.log('hello');
var eLeftPos1 = e.offsetLeft;
//console.log(e.offsetLeft);
e.style.left = (eLeftPos1 + s) + 'px';
//console.log(e.style.left);
}
}
}
if ((eLeftPos + s) >= 300) {
clearInterval(internal)
}
}
var internal = setInterval(myInterval, 100);
You've defined a function named myInterval3, but you're not calling it. When you write
function myInterval3() { ... }
That defines a function named myInterval3, but that's all that it does. To actually have the code inside the function run, you need to call it.
myInterval3()
To have the function called on a repeating interval, use setInterval (like you have for your other functions:
setInterval(myInterval3, 100)

using requestAnimationFrame

I'm using this function to set a transform property of some elements,but the animation is not so smooth in firefox and it's less smooth when window size is bigger(in any browser).I have read a lot of thing's on blogs which are saying that I can make much smoother animation using requestAnimationFrame,but I don't understand how I can implement it inside of my function.Can somebody explain me how I can use it inside of my function?
function sectionMovement(delay,section) {
setTimeout(function () {
var val = ((v.sectionIndex + 1) > v.leavingSection) ?
val = 100 :
val = 0;
document.getElementById("sec_"+section+"").style.transform = "translateY(-"+val+"%)"
}, delay);
};
Something like this:
function updateSection(selector) {
var elem = document.getElementById("sec_" + section);
return function step() {
var val = ((v.sectionIndex + 1) > v.leavingSection) ? // not sure what 'v' is?
100 :
0;
elem.style.transform = "translateY(-"+val+"%)";
requestAnimationFrame(step);
}
}
var sel = "myElementId";
requestAnimationFrame(updateSection(sel));
You will also likely want an external variable to check against to know when to stop the animation.

Why are these variables getting cleared/reset?

I am attempting to write a small library for scrolling events in JavaScript, but I must be missing something easy, because it seems that my vars are getting reset at some point inside of this method.
Here is the code:
var scrollEvents = {
change: window.onscroll = function (selector, property, initialValue, changedValue) {
// grab the selectors and convert them into an array so we can use forEach()
var items = document.getElementsByClassName(selector);
var itemArray = [].slice.call(items);
// window.pageYOffset has better compatibility than document.body.scrollTop
var scrollPos = window.pageYOffset;
var breakPoint = 10;
if (scrollPos > breakPoint) {
console.log('if');
console.log(items);
console.log(itemArray);
itemArray.forEach(function (i) {
i.setAttribute("style", property + ": " + changedValue + ";");
console.log("style", property + ": " + changedValue + ";")
});
} else {
console.log('else');
console.log(itemArray);
itemArray.forEach(function (i) {
i.setAttribute("style", property + ": " + initialValue + ";");
});
}
}
};
And I would like to call it like so:
scrollEvents.change("foo", "height", "400px", "800px");
I have quite a few extra console.log() calls inside there because I have been trying to diagnose the issue, but I have rewritten the code several times and seem to have hit a dead end.
The behavior I would like is that I can call scrollEvents.change() passing those parameters to change style attributes at certain scroll points.
Here is the code without all the extra console.log()'s:
var scrollEvents = {
change: window.onscroll = function (selector, property, initialValue, changedValue) {
// grab the selectors and convert them into an array so we can use forEach()
var items = document.getElementsByClassName(selector);
var itemArray = [].slice.call(items);
// window.pageYOffset has better compatibility than document.body.scrollTop
var scrollPos = window.pageYOffset;
var breakPoint = 10;
if (scrollPos > breakPoint) {
itemArray.forEach(function (i) {
i.setAttribute("style", property + ": " + changedValue + ";");
});
} else {
itemArray.forEach(function (i) {
i.setAttribute("style", property + ": " + initialValue + ";");
});
}
}
};
UPDATE:
Thanks to #pointy this library now works: https://github.com/ryanpcmcquen/scrollEvents
You've set up an object with a property called "change", and you've assigned a function to that property. The assignment also assigned the function to the "onscroll" property of the window object.
When the browser detects a user scroll operation, it will invoke that function, and regardless of your formal parameter list in the declaration it'll pass either nothing (Internet Explorer) or an event object.
Making a call to scrollEvents.change will invoke the event handler function, but that will have no effect on how the browser invokes the event handler when the user messes with the scrollbar or mouse wheel (or whatever).
I'm not sure exactly how you intend for this API to work, so it's hard to say how to fix it. If you want to attach just one event handler at a time, then the simplest thing to do would be to wrap your current code in another function:
var scrollEvents = {
change: function (selector, property, initialValue, changedValue) {
window.onscroll = function(event) {
// grab the selectors and convert them into an array so we can use forEach()
var items = document.getElementsByClassName(selector);
var itemArray = [].slice.call(items);
// window.pageYOffset has better compatibility than document.body.scrollTop
var scrollPos = window.pageYOffset;
var breakPoint = 10;
if (scrollPos > breakPoint) {
itemArray.forEach(function (i) {
i.setAttribute("style", property + ": " + changedValue + ";");
});
} else {
itemArray.forEach(function (i) {
i.setAttribute("style", property + ": " + initialValue + ";");
});
}
};
}
};
Now when you call
scrollEvents.change("foo", "height", "400px", "800px");
then that function call will establish the event handler.

How to pass a variable after setInterval completes?

I have the following code. A fiddle I started which is an isolated version of something I am trying to do.
var height;
var count = 0;
var setHeight = setInterval(function() {
count++;
console.log('count');
if ( count > 10)
{
console.log('done');
height = 20;
clearInterval(setHeight);
}
},100);
console.log('this is the height -> ' + height);
What I would expect (or want to happen) is for the value of height = 20; to be outputted in my console.log. The end goal would be to retrieve a variable from my setInterval function after the interval has been cleared.
Right now I get .. this is the height -> undefined
FIDDLE:
http://jsfiddle.net/GNvG6/8/
What I am trying to accomplish:
So the underlying issue is this. I have a function that runs before some elements are loaded in the DOM. So what I am trying to do is keep running the function until an instance of that element exists. Once that happens I then intend to get the height of that element and hand it off to another variable. I am not sure If this will resolve my issue, but I figure if I can get this to work I can at least test it out.
var height;
var count = 0;
var setHeight = setInterval(function() {
count++;
console.log('count');
if ( count > 10)
{
console.log('done');
height = 20;
reportHeight(height);
clearInterval(setHeight);
}
},100);
function reportHeight(height){
console.log('this is the height -> ' + height);
}
console output is
(11) count
done
this is the height -> 20
FIDDLE DEMO
var height = 0; // initial value
var count = 0;
var setHeight = setInterval(function() {
count++;
console.log('count and height is still:'+ height); // height is always 0
if ( count > 10){
height = 20;
console.log('done and height is:'+ height); // height is finally 20
clearInterval(setHeight);
}
},100);
As you're using jQuery, you could also use $.Deferred.
// wait for 3 + (0..2) seconds
setTimeout(function () {
$(document.body).append($("<strong>hello</strong>"));
}, 3000 + 2000 * Math.random());
function waitFor(test, interval) {
var dfd = $.Deferred();
var count = 0;
var id = setInterval(function () {
console.log(count++);
var val = test();
if (undefined !== val) {
clearInterval(id);
dfd.resolve(val);
}
}, interval);
return dfd.promise();
}
function waitForEl(selector, interval) {
return waitFor(function () {
var els = $(selector);
return (els.length > 0) ? els : undefined;
}, interval);
}
waitForEl("strong", 100).then(function (strong) {
console.log(strong, strong.height());
});
Example in this jsfiddle.

$ is not a function errors

I'm getting a few Javascript errors and was wondering if anyone could help me out with them. I'm fairly new to js and could really use the help. That being said here is the page with the errors. http://www.gotopeak.com .
Here is the error:
Uncaught TypeError: Property '$' of object [object DOMWindow] is not a function
error is on line 44
Here is the code:
var hoverButton = {
init : function() {
arrButtons = $$('.hover_button');
for (var i=0; i<arrButtons.length; i++) {
arrButtons[i].addEvent('mouseover', hoverButton.setOver);
arrButtons[i].addEvent('mouseout', hoverButton.setOff);
}
},
setOver : function() {
buttonImageSource = this.src;
this.src = buttonImageSource.replace('_off.', '_hover.');
},
setOff : function() {
buttonImageSource = this.src;
if (buttonImageSource.indexOf('_hover.') != -1) {
this.src = buttonImageSource.replace('_hover.', '_off.');
}
}
}
window.addEvent('domready', hoverButton.init);
var screenshots = {
numScreens : 0,
currScreen : 0,
screenContainerAnimation : null,
screenFadeSpeed : 200,
animating : false,
initialized: false,
init : function() {
var arrScreens = $$('#screen_container .screenshot');
screenshots.numScreens = arrScreens.length;
screenshots.screenContainerAnimation = new Fx.Tween('screen_container', {
duration: 300,
transition: Fx.Transitions.Quad.easeInOut
});
var indicatorMold = $('indicatorMold');
for(i=0; i<arrScreens.length; i++) {
var screenShot = arrScreens[i];
screenShot.id = 'screenshot' + (i+1);
var screenIndicator = indicatorMold.clone();
screenIndicator.id = 'indicator' + (i+1);
screenIndicator.inject('screen_indicators');
screenIndicator.href = 'javascript: screenshots.setActiveScreen('+ (i+1)*1 +')';
screenShot.removeClass('hidden');
if (i==0) {
var initialScreenHeight = screenShot.getCoordinates().height;
$('screen_container').setStyle('height', initialScreenHeight);
screenshots.currScreen = 1;
screenIndicator.addClass('active');
}
else {
screenShot.setStyle('opacity',0);
screenShot.setStyle('display','none');
}
} // loop
screenshots.initialized = true;
},
next : function() {
if (screenshots.initialized) {
var nextNum = screenshots.currScreen + 1;
if (nextNum > screenshots.numScreens) {
nextNum = 1;
}
screenshots.setActiveScreen(nextNum);
}
return false;
},
previous : function() {
if (screenshots.initialized) {
var prevNum = screenshots.currScreen - 1;
if (prevNum < 1) {
prevNum = screenshots.numScreens;
}
screenshots.setActiveScreen(prevNum);
}
return false;
},
setActiveScreen : function(screenNum) {
if(screenshots.animating == false) {
screenshots.animating = true;
var currScreen = $('screenshot' + screenshots.currScreen);
var currIndicator = $('indicator' + screenshots.currScreen);
var newScreen = $('screenshot' + screenNum);
var newIndicator = $('indicator' + screenNum);
currScreen.set('tween', {
duration: screenshots.screenFadeSpeed,
transition: Fx.Transitions.Quad.easeInOut,
onComplete: function() {
currIndicator.removeClass('active');
currScreen.setStyle('display','none') ;
}
});
currScreen.tween('opacity', 0);
function resizeScreen() {
newScreen.setStyle('display','block');
var newScreenSize = newScreen.getCoordinates().height;
screenshots.screenContainerAnimation.start('height', newScreenSize);
}
function fadeInNewScreen() {
newScreen.set('tween', {
duration: screenshots.screenFadeSpeed,
transition: Fx.Transitions.Quad.easeInOut,
onComplete: function() {
newIndicator.addClass('active');
screenshots.animating = false;
}
});
newScreen.tween('opacity', 1);
}
resizeScreen.delay(screenshots.screenFadeSpeed);
fadeInNewScreen.delay(screenshots.screenFadeSpeed + 400);
screenshots.currScreen = screenNum;
}
}
}
window.addEvent('load', screenshots.init) ;
I would be very grateful and appreciative of any help that I receive on this issue.
Your page is loading mootools once, jQuery twice and jQuery UI twice. Because both jQuery and mootools define a function named '$', this gives you conflicts.
You can fix this by using a self executing closure that maps the non-conflicted version of '$' to a local '$' variable you can actually use.
(function($) {
// your code
})(document.id);
More information on MooTools' "Dollar Safe Mode" can be found here.
Edit: please ignore. The above answer by igorw is the correct one. Sorry.
Try converting your $ symbols to "jQuery". $ is a shortcut to JQuery. $ is reserved for Prototype in Wordpress.
Edit: you can also try jQuery.noConflict(). It relinquishes control of $ back to JQuery (or the first library that implements it), so it does not cause conflict with other libraries that also implement $.
this is what I did and solved everything, Go to the index.php file, after calling jquery immediately, place <script type="text/javascript">jQuery.noConflict();</script>

Categories