How do I set the interval in a for loop? - javascript

I'm trying to create a menu of social media icons that slides into and out of the page. The following code works, but it is too fast. It doesn't look like sliding. I think I could adjust the timing using the setInterval() method, but I can't get it to work. This is the code so far:
var socialMedia = document.getElementById("socialmedia");
var stalkMe = document.getElementById("pleasestalkme");
function SM() {
socialMedia.style.position = "fixed";
socialMedia.style.right = "-330px";
}
SM();
stalkMe.addEventListener("click", function(){
if (socialMedia.style.right === "-330px") {
for (i = -330; i <= -30; i++) {
var j = i +"px";
socialMedia.style.right = j;
}
} else if (socialMedia.style.right === "-30px"){
for (i = -30; i >= -330; i--){
var j = i +"px";
socialMedia.style.right = j;
}
}
}, false);

You should have a look at CSS transitions. Basically you just need to change the right style from 300px to 0px and using transition: right 1s; you would see your element being animated
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
Otherwise, you could have a look at jQuery.... (I feel bad).

Prior to the solution, a word of warning: you actually should not use this code snippet. Instead heed the advice of floribon and look into css transitions.
However, if you absolutely must do it the outmoded way:
for (i = -330; i <= -30; i++) {
var j = i +"px";
socialMedia.style.right = j;
}
write
var hnd;
i = -330;
hnd = setInterval ( function () {
var j = i +"px";
socialMedia.style.right = j;
i++;
if (i > -30) {
clearInterval(hnd); // end activity
}
}, 50 ); // interval length in ms

Related

JQuery Letters fade in randomly

This is my first time coding in JQuery. Below is my code:
var div = document.getElementById('fadeletters1'),
letters = div.textContent.split('');
while(div.hasChildNodes()) div.removeChild(div.firstChild);
for(var i = 0; i < letters.length; i++) {
var letter = document.createElement('span'),
style = 'opacity ' + (Math.random() * 5 + 1) + 's linear';
letter.appendChild(document.createTextNode(letters[i]));
letter.style.WebKitTransition = letter.style.transition = style;
letter.style.opacity = 0;
div.appendChild(letter);
}
setTimeout(function() {
for(var i = 0; i < div.childNodes.length; i++) {
div.childNodes[i].style.opacity = 1;
}
}, 0);
<div id=fadeletters1>Helllooo This is a test for the website</div>
So the letters do fade in but then in the starting of the animation, letter are kinda visible and then fades in after couple seconds. I want it to pop up from 0 visibility to 100 visibility as its fades in.
I am trying to acheive something like this site does: http://method.digital/
You're changing the rate at which the transition takes place, instead you want to change the delay before the transition starting:
var div = document.getElementById('fadeletters1'),
letters = div.textContent.split('');
while(div.hasChildNodes()) div.removeChild(div.firstChild);
for(var i = 0; i < letters.length; i++) {
var letter = document.createElement('span'),
style = 'opacity 0.6s linear',
delay = (Math.random() * 4) + 's';
letter.appendChild(document.createTextNode(letters[i]));
letter.style.WebKitTransition = letter.style.transition = style;
letter.style.WebKitTransitionDelay = letter.style.transitionDelay = delay;
letter.style.opacity = 0;
div.appendChild(letter);
}
setTimeout(function() {
for(var i = 0; i < div.childNodes.length; i++) {
div.childNodes[i].style.opacity = 1;
}
}, 0);
<div id=fadeletters1>Helllooo This is a test for the website</div>
If you want to run it for multiple divs you can wait until the first is complete before moving onto the next (this example only appears to work sometimes, make sure to hit refresh before running):
function RunAnimation(target,delay) {
var div = document.getElementById(target),
letters = div.textContent.split('');
while (div.hasChildNodes()) div.removeChild(div.firstChild);
setTimeout(function(){
for (var i = 0; i < letters.length; i++) {
var letter = document.createElement('span'),
style = 'opacity 0.6s linear',
delay = (Math.random() * 4) + 's';
letter.appendChild(document.createTextNode(letters[i]));
letter.style.WebKitTransition = letter.style.transition = style;
letter.style.WebKitTransitionDelay = letter.style.transitionDelay = delay;
letter.style.opacity = 0;
div.appendChild(letter);
}
setTimeout(function() {
for (var i = 0; i < div.childNodes.length; i++) {
div.childNodes[i].style.opacity = 1;
}
}, 0);
}, delay);
}
RunAnimation('fadeletters1')
RunAnimation('fadeletters2', 5000);
RunAnimation('fadeletters3', 10000);
<div id="fadeletters1">Helllooo This is a test for the website</div>
<div id="fadeletters2">This is a second div which also fades in</div>
<div id="fadeletters3">And who knows maybe you want a third</div>
The thing is there is two delays...
One for the animation and one for a timeout. This is the timeout that really gives the effect you are looking for.
// Get the letters from the original string.
var letters = $("#fadeletters1").text().split("");
// Remove the original string.
$("#fadeletters1").text("");
// Create a span for each letters and append them to the document.
letters.forEach(function(item,index){
var span = $("<span class='fade'>").text(item);
$("#fadeletters1").append(span);
});
// Animate each spans
$(document).find(".fade").each(function(){
// Random delay
var delay = Math.random();
var letter = $(this);
// Set a timeout to animate the spans
setTimeout(function(){
letter.animate({"opacity":1},delay*1000);
},delay*3000);
});
.fade{
opacity:0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fadeletters1">Helllooo This is a test for the website</div>

Javascript Not Working When Tab Not Active

So, I have a code here that works perfectly fine when I am viewing it in the active browser tab. But, as soon as I minimize or switch between other tabs of the browser (which is chrome by the way) the code starts giving issues. Here is the code below:
var a = document.getElementById("slidermain");
var b = a.getElementsByTagName("IMG");
var len = b.length;
var noOpac = 0;
var fullOpac = 10;
var imgNumb = 0;
function initFade(count){
imgNumb = imgNumb + count;
if(imgNumb < 0){
imgNumb = len;
}
if(imgNumb > len){
imgNumb = 1;
}
elem = b[imgNumb-1];
startFadeEffect(elem);
}
function startFadeEffect(elem){
var opacSetting = noOpac / 10;
if(noOpac > 10){
opacSetting = 1;
}
elem.style.opacity = opacSetting;
elem.style.display = "block";
noOpac++;
var timer = setTimeout(function() { startFadeEffect(elem); }, 55);
if(opacSetting == 1){
clearTimeout(timer);
elem.style.opacity = 1;
noOpac = 0;
setTimeout(function() { endFadeEffect(elem); }, 2000);
}
}
function endFadeEffect(elem){
var opacSetting = fullOpac / 10;
if(fullOpac < 0){
opacSetting = 0;
}
elem.style.opacity = opacSetting;
fullOpac--;
var timer = setTimeout(function() { endFadeEffect(elem); }, 55);
if(opacSetting == 0){
clearTimeout(timer);
elem.style.opacity = 0;
elem.style.display = "none";
fullOpac = 10;
return false;
}
}
function autoFade(){
var loop = setInterval("initFade(1)", 4000);
}
Please not that I have been looking on this site for the answer, but mostly the ones I have found are JQuery based solutions; however, I am looking for a JavaScript only solution in which I might not have to use the get new date function. Please do not mark my question as duplicate as I have done good research. Thanks!
This is not a problem with your javascript, but with Chrome. Chrome does some weird things with your tabs when they aren't active. Add code to "fix the mess", or account for not the tab being active, to recover after tabbing out and back in.

Slide dynamically added content with jQuery

I'm trying to create a simple content slider that could handle dynamically added content to the slider. None of the "lightweight" plugins I found provided such functionality or, if it did, it didn't work correctly.
var $left = $('.left'),
$right = $('.right'),
$months = $('.sub ul');
$left.click(function(){
for(i = 0; i < 3; i++){
$months.find('li').first().before($.parseHTML('<li>xxx</li>'));
}
pos = $months.position();
$months.css('left', pos.left + 90);
});
$right.click(function(){
for(i = 0; i < 3; i++){
$months.find('li').last().after($.parseHTML('<li>xxx</li>'));
}
pos = $months.position();
$months.css('left', pos.left - 90);
});
This is the code I've got so far and here's a fiddle with an example - http://jsfiddle.net/kkr4zg0r/2/. It kind of works, but the problem is that since new content is added the navigation goes off (you can see what I mean by clicking left-right a couple of times).
I understand what's the problem for this - the newly added items "shift" the content and I need to do better calculations than substracting/adding 90px to the left position of the element but I can't figure out how to get the correct index of the elements and basically get this sliding by exactly (and correctly) by 3(or 6) elements at the time.
Currently the code is adding extra elements whenever a navigation button is pressed, if I could get the index of the currently visible first/last element, I could probably tell whether I need to add more elements and only add them then.
This is a basic illustration of what I'm trying to achieve
edit
I've changed the jsfiddle to the correct one.
The whole idea is to check when adding elements is necessary and when shift is enough:
Fiddle
$(document).ready(function()
{
var $main = $('.main'),
$left = $('.left'),
$right = $('.right'),
$months = $('.sub ul');
var addCount = 3;
var liWidth = 30;
var shiftX = addCount * liWidth;
$left.click(function()
{
var currentLeft = parseInt($months.css('left'));
var totalLength = $months.find('li').length * liWidth;
if (-currentLeft + $main.width() >= totalLength)
{
for (var i = 0; i < addCount; i++)
{
$months.find('li:last').after('<li>xxx</li>');
}
}
$months.css('left', currentLeft -= shiftX);
});
$right.click(function()
{
var currentLeft = parseInt($months.css('left'));
if (currentLeft < 0)
{
$months.css('left', currentLeft += shiftX);
}
else
{
for (var i = 0; i < addCount; i++)
{
$months.find('li:first').before('<li>xxx</li>');
}
}
});
});

jQueryrotate if else loop issue

I am trying to setup an element that will rotate 180 degrees when clicked and then back again when clicked again. The code I am using is as follows. Is obviously not right and feels like I need to use a for loop.
$('#hodgepodge').click(function(){
var i = 0;
if (i < 1) {
$('#hodgepodge').rotate(180);
var i = 1;
} else {
$('#hodgepodge').rotate(0);
var i = 0;
}
});
You can use jQuery's data() to keep track of the state, and then just toggle it :
$('#hodgepodge').on('click', function(){
$(this).rotate( !$(this).data('state') ? 180 : 0 );
$(this).data('state', !$(this).data('state'));
});
FIDDLE
Try to initialize before click event like
var i = 0;
$('#hodgepodge').click(function(){
if (i < 1) {
$('#hodgepodge').rotate(180);
i = 1;
} else {
$('#hodgepodge').rotate(0);
i = 0;
}
});

Javascript Click Function Broken in Gallery Script

I'm trying to create a gallery script with JS (I've only been learning for a week so please excuse if I've made any ridiculous mistakes!). When I run the code, I get an error for controlLeft.onclick = changeImage(--);, saying ( is an unexpected token.
By my untrained eye everything should be fine, but evidently not. What have I done wrong here:
//Javascript Image Changer
var currentImage = document.getElementById("currentImage");
var imageArray = ["img/1.jpg", "img/2.jpg", "img/3.jpg", "img/4.jpg"];
var imageIndex= 0;
function changeImage(param){
currentImage.setAttribute("src", imageArray[imageIndex]);
imageIndex[param];
if (imageIndex >= imageArray.length){
imageIndex = 0;
}else if(imageIndex <= -1){
imageIndex = imageArray.length + 1;
}
}
var controlLeft = document.getElementById("left");
var controlRight = document.getElementById("right");
controlLeft.onclick = changeImage(--);
controlRight.onclick = changeImage(++);
You can't just pass operators around like other things. Even in a programming language with higher-order functions the same thing usually does not apply to operators.
Besides that, onclick expects a function - not the result of a function call.
Here's a snippet that is likely to work:
function changeImage(mod){
currentImage.setAttribute("src", imageArray[imageIndex]);
imageIndex += mod;
if (imageIndex >= imageArray.length){
imageIndex = 0;
}else if(imageIndex <= -1){
imageIndex = imageArray.length + 1;
}
}
var controlLeft = document.getElementById("left");
var controlRight = document.getElementById("right");
controlLeft.onclick = function() { changeImage(-1); };
controlRight.onclick function() { changeImage(1); };
Just make a slight modification:
controlLeft.onclick = function() {
changeImage('back');
};
controlRight.onclick = function() {
changeImage('forward');
};

Categories