I have list of projects with images that have hover effect. Hover effect shows project description. I made a loop that shows for 3 seconds every project description.
The problem is when you mouse enter some element it shows text, but when loop catches it hides project text. And you need leave and enter the element to show text again. I want to prevent from text to hide if element is already hovered.
var index = 0;
var duration = 3000;
function loopProjects() {
$('.port-hov').each(function(index,item) {
index = index + 1;
//console.log(index);
setTimeout(function(){
$(item).mouseenter();},duration);
duration = duration + 3000;
setTimeout(function(){
$(item).mouseleave();},duration);
});
}
setInterval(loopProjects, index * 4000);
Solution!
function loopProjects() {
$('.port-hov').each(function(index,item) {
index = index + 1;
setTimeout(function(){
$(item).mouseenter();},duration);
duration = duration + 3000;
setTimeout(function(){
if (!$(item).is(":hover")){
$(item).mouseleave();}},duration);
});
}
Related
Now I want my text to flicker jus like a tube light. This means there should be some noise in its blinking. it should not be a set definite interval in which opacity changes.
Here is what I came up with:
//find the text i want to flicker
text = document.getElementById("flicker");
console.log(text);
//initialise with 0
text.style.opacity=0;
//logic of wait function
function wait(ms){
var start = new Date().getTime();
var end = start;
while(end < start + ms) {
end = new Date().getTime();
}
}
while(true){
//logic to invert the opacity
if(text.style.opacity=1)
text.style.opacity=0;
else if (text.style.opacity=0)
text.style.opacity=1;
//find a random time interval b/w 0 to 0.5 sec
randVal = Math.random()*500+1;
//wait of that time and repeat the process for ever
wait(randVal);
}
Now the problem comes when I load the web page.
IT DOES NOT LOAD
MY GUESS: the infinite while loop is the problem and is running even before the DOM loads
but I have added the script at the end of my HTML file
Use a setTimeout and toggle a class instead.
//find the text i want to flicker
const text = document.getElementById("flicker");
console.log(text);
const getDuration = () => {
//find a random time interval b/w 0 to 0.5 sec
const randVal = Math.random()*500+1;
console.log(randVal);
return randVal;
};
const doFlicker = () => {
//logic to invert the opacity
text.classList.toggle('clear');
setTimeout(doFlicker, getDuration());
};
setTimeout(doFlicker, getDuration());
.clear {
color: #00000000;
}
<div id="flicker" class="clear">Flicker</div>
First let me describe the project I'm stuggeling with. English is not my foreign language so I do not know the exact name of the effect I am looking for.
Basicly I am creating a bingo type of game where the host can press on a button to start the bingo wheel. Eventually the wheel will stop and the word it has landed on is the chosen word for that round. After that, this word get removed from the game and the game starts over and over untill someone calls a bingo.
I started playing a bit around with some JSON data and how to remove the items from the array etc which is pretty easy to do. But now comes the part where I am struggeling the most. I have to create a kind of function that scrolls through all options like a wheel at a certain speed that eventually decreased in speed so it will land on the chosen word for this round. I created a fiddle with the code I currently have. Note that it's purely created for functionality instead of looks!
var json = {
"titles": [
"PLACEHOLDER_1",
"PLACEHOLDER_2",
"PLACEHOLDER_3",
"PLACEHOLDER_4",
"PLACEHOLDER_5",
"PLACEHOLDER_6",
"PLACEHOLDER_7",
"PLACEHOLDER_8",
"PLACEHOLDER_9",
"PLACEHOLDER_10",
"PLACEHOLDER_11",
"PLACEHOLDER_12",
"PLACEHOLDER_13",
"PLACEHOLDER_14",
"PLACEHOLDER_15"
]
}
$(document).ready(function() {
var app = new Bingo.init();
})
var Bingo = {
viewport: {
isMobile: 0,
isTablet: 0,
isDesktop: 1,
device: 'desktop',
browser: null
}
}
Bingo.init = function() {
Bingo.gameController.init();
};
Bingo.gameController = {
gameNames: {},
init: function() {
Bingo.gameController.general.saveJson();
$('.test').on('click', Bingo.gameController.array.pickRandomNumber)
},
general: {
saveJson: function() {
Bingo.gameController.gameNames = json.titles;
},
//General reset function
resetGame: function() {
Bingo.gameController.general.saveJson;
}
},
array: {
pickRandomNumber: function() {
//reset gamefield
Bingo.gameController.game.buildGame();
var gameNames = Bingo.gameController.gameNames;
var totalNames = gameNames.length;
//Pick a random number
var chosenNumber = Math.floor(Math.random() * totalNames);
Bingo.gameController.array.remove(chosenNumber)
},
remove: function(id) {
//remove chosen name from array
var gameNames = Bingo.gameController.gameNames;
var check = gameNames.indexOf(gameNames[id]);
Bingo.gameController.game.highlightName(id);
if (check != -1) {
gameNames.splice(check, 1);
Bingo.gameController.gameNames = gameNames;
}
}
},
game: {
buildGame: function() {
//build all the array entry's into the div
$('.page.main-game').empty();
var gameNames = Bingo.gameController.gameNames;
for (var i = 0; i < gameNames.length; i++) {
var item = '<div class="name-item" data-id="' + i + '">' + gameNames[i] + '</div>';
$('.page.main-game').append(item);
}
},
highlightName: function(id) {
//highlight the chosen number red
$('.name-item[data-id="' + id + '"]').css('color', 'red');
}
}
}
Fiddle link here
(I hope the link is correct, not using fiddle that much)
So now when you click on the 'play again' button you see that it wil highlight a word. What has to happen is when I press the play again button the red highlight has to go from the first div to the last and so forth untill it eventually stops at a div (which is chosen with the random number or something).
If someone can help me with this or could give me a hint in the right direction please let me know!
EXTRA: The app will eventually get a look like a scrollwheel that the iphone gets when you open a select box (hope you know what I am referring to). So thats why its a wheel of fortune-ish effect. If someone could provide me with the correct name for this let me know so I can adjust the title!
If any information is missing please let me know, i'd be happy to provide it! Thanks in regard!!
The basic ideas are (1) to keep the current index, so you can start the spin every time from that index, where 'spining' is just increasing that index or set to zero when reaching the maximal index; and (2) set a timeout for the next painting, and reduce that timeout everytime, until it's low enough.
JsFiddle Demo
HTML
<p><button onclick="w.spin(w.randomNext(), 8)">SPIN</button></p>
<ul id='wheel'>
<li>$100</li>
<li>$250,000</li>
<li>$25,000</li>
<li>$10,000</li>
<li>$1,000</li>
<li>$5</li>
<li>$2,000</li>
<li>30,000</li>
<li>$40</li>
</ul>
JavaScript
var wheelEl = document.getElementById('wheel');
function Wheel () {
this.current = 4;
}
Wheel.prototype.init = function () {
this.onItem();
}
Wheel.prototype.randomNext = function () {
return Math.floor(Math.random() * wheelEl.children.length);
}
Wheel.prototype.spin = function (next, itemsPerSecond) {
var timeout = setTimeout(onItem.bind(this), (1 / itemsPerSecond) * 1000);
function onItem () {
// stop if speed is low enough
if (itemsPerSecond < 1)
return;
// spin to next item
this.current ++;
if (this.current >= wheelEl.children.length)
this.current = 0;
// paint text
this.onItem();
// reduce speed
clearTimeout(timeout);
itemsPerSecond--;
timeout = setTimeout(onItem.bind(this), (1 / itemsPerSecond) * 1000);
}
}
// paints the index of this.current
Wheel.prototype.onItem = function () {
for (var i = 0 ; i < wheelEl.children.length ; i++)
wheelEl.children[i].style.color = (i == this.current) ? '#6d4321' : '#000000';
}
var w = new Wheel();
w.init();
I have created a page where I have multiple functionality done but stuck with timing of it, if you see the page example here in JSFiddle.
When you open the page, it will first run a loader and when the loader is complete there are multiple boxes, which is showing one by one but in currently its not happening, Loader is loading fine and then in the next step where centered columns has to appear one by one, the first four columns loads by default and then other div loads one by one.
My question is, how can I execute a function and execute another another function once the previous is complete.
For loader I have the following:
//--------- process bar animation
var showText = function (target, message, index, interval) {
if (index < message.length) {
$(target).append(message[index++]);
setTimeout(function () { showText(target, message, index, interval); }, interval);
}
}
var width = 100,
perfData = window.performance.timing, // The PerformanceTiming interface represents timing-related performance information for the given page.
EstimatedTime = -(perfData.loadEventEnd - perfData.navigationStart),
time = parseInt((EstimatedTime/1000)%60)*100;
showText("#msg", "Welcome to the Company Group", 0, width);
// Loadbar Animation
$(".loadbar").animate({
width: width + "%"
}, time);
// Loadbar Glow Animation
$(".glow").animate({
width: width + "%"
}, time);
// Percentage Increment Animation
var PercentageID = $("#precent"),
start = 0,
end = 100,
durataion = time;
animateValue(PercentageID, start, end, durataion);
function animateValue(id, start, end, duration) {
var range = end - start,
current = start,
increment = end > start? 1 : -1,
stepTime = Math.abs(Math.floor(duration / range)),
obj = $(id);
var timer = setInterval(function() {
current += increment;
$(obj).text(current + "%");
//obj.innerHTML = current;
if (current == end) {
clearInterval(timer);
}
}, stepTime);
}
// Fading Out Loadbar on Finised
setTimeout(function(){
$('.preloader-wrap').fadeOut(300);
$('.loader-wrap').fadeOut(300);
$('.main-wrapper').fadeIn(300);
$('body').addClass('bg');
}, time);
For showing div one by one in next step I have the following code:
$(".column-wrapper").each(function(index) {
var $this = $(this);
setTimeout(function () { $this.addClass("show"); }, index * 1000);
});
I use trigger and on for those kind of things. You had a lot of code, so sorry, I didn't want to read all of that but this is a simplified example.
https://jsfiddle.net/2d6p4L6k/1/
$(document).ready(function(){
var action = function(){
$('div.one').css('background-color', 'green');
/* do whatever you want to do */
/* then trigger(call) another function */
$(document).trigger('hello-action');
};
var hello = function() {
$('div.two').css('background-color', 'fuchsia');
};
/* just listen if anything triggers/calls "hello-action" */
/* if so call function named hello */
$(document).on('hello-action', hello);
setTimeout(action, 1500);
});
div {
width: 50px;
height: 50px;
background-color: orange;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="one">one</div>
<div class="two">two</div>
Note: To keep it simple we trigger and listen on $(document) which is really just to keep it simple. A better approach would be to have a wrapper element, and then you can do exactly the same (trigger and listen) just on that element and not on the entire document. You can find more details on the jQuery API .trigger()
Good Afternoon All
We've been able to get a basic version of this working with a single time interval in javascript
time = 10000; // 10 Seconds
var counter = 0;
divs = $('#div1, #div2, #div3, #div4, #div5');
function showDiv () {
divs.hide() // hide all divs
.filter(function (index) { return index == counter % 5; })
// figure out correct div to show
.fadeIn(300, "linear"); // and show it
counter++;
if (counter > 5 ){
counter = 1; //Reset Counter
}
}; // function to loop through divs and show correct div
showDiv(); // show first div
setInterval(function(){ showDiv(); }, time); // do this every 10 seconds
});
What I'd like to do is cause the intervals to be different on each of the div times
Like div1 & div2 play for 10 seconds and the others play for 5 seconds
I was able to get the logic working to see if the time had changed based upon which div was displaying but could not get "time" to update from one value to another
I've been reading that using setInterval() does not allow for changing of a variable value once it's been loaded.
There were some suggestions to use setTimeout() but I could not figure it out
Anyone with a suggestion?
Thanks~
Instead of using setInterval you can do the same thing using setTimeout() to call the function again from within itself. This allows determining intervals per instance based on counter
time = 10000; // 10 Seconds
var counter = 0;
divs = $('#div1, #div2, #div3, #div4, #div5');
function showDiv() {
// hide all divs, filter current index, and fadeIn
divs.hide().eq(counter).fadeIn(300, "linear");
counter++;
if (counter > 5) {
counter = 1; //Reset Counter
}
// do it again
var delay = counter > 1 ? time / 2 : time
setTimeout(showDiv, delay);
}; // function to loop through divs and show correct div
showDiv(); // show first div
Also streamlined using filter(fn) and replaced with eq()
Correct, the interval for setInterval cannot be changed once it is started. You'll need to use setTimeout to make the interval different each time. The idea is to call setTimeout again in the callback passed to setTimeout, thereby creating a chain of calls. This is a common pattern.
// Different timeouts for each div
var times = [10000, 10000, 5000, 5000, 5000];
var counter = 0;
function showDiv() {
// Show the div immediately
divs.hide().eq(counter).fadeIn(300, 'linear');
// Cycle the counter
counter = (counter + 1) % divs.length;
// Set the delay for the next callback
setTimeout(showDiv, times[counter]);
}
// Start the chain of calls
showDiv();
A hearty thank you and a brewski to both...
I ended up taking the best of both and here's what I'm now using
<script type="text/javascript">
$(function () {
// Different timeouts for each div
var times = [30000, 30000, 10000, 10000, 5000];
var counter = 0;
divs = $('#div1, #div2, #div3, #div4, #div5');
function showDiv() {
// hide all divs, filter current index, and fadeIn
divs.hide().eq(counter).fadeIn(300, "linear");
// set time out duration from array of times
setTimeout(showDiv, times[counter]);
// cycle the counter
counter = (counter + 1) % divs.length;
};
showDiv(); // show first div
});
</script>
I am making an info screen, and for that, it needs to show reviews from their customers pulled from Trustpilot.
I got the reviews and everything formatted in HTML showing the 20 latest, but I want to present it very sweet. I am not a JavaScript guru, but I thought i would do it using jQuery and its fadein function.
What is want, is have 20 unique divs fading in with X milliseconds difference popping randomly up. By unique I mean, that each div must have unique content. And by randomly popping up, I mean that if box 1 spawns first, then the next should be 5, then 14 etc, and then another cycle the next time around.
Just like what I made here;
$(function() {
var box = $('.box');
var delay = 100;
for (i = 0; i < 30; i++) {
setTimeout(function() {
var new_box = box.clone();
$('.container').append(new_box);
new_box.fadeIn();
}, delay);
delay += 500; // Delay the next box by an extra 500ms
}
});
http://jsfiddle.net/CCawh/5/
Is this even possible, and how would this be done?
I am very new to JavaScript, so please bear with me if I ask to much
Thanks in advance.
EDIT:
The HTML i want to spawn will all be wrapped in divs, so it would go like this;
<div id="one">content</div>
<div id="two">content</div>
<div id="three">content</div>
<div id="four">content</div>
etc.
Made up a nice function for you. I believe this may be what you are looking for
Here's a rundown of how it works :
Populate an array with numbers randomly generated 1-10 in this case.
Run through that array with a set interval, and when everything has
been added stop the interval
pretty straightforward from there. Set the visibility etc. You should be able to change up the function to dynamically add HTML elements and what-not, but just giving you something to start with.
var usedNum = [];
var i, j, y;
i = 0;
for(y = 0; y < 10; y++){
var x = Math.floor((Math.random() * 10) + 1);
if(!isUsed(x)) usedNum.push(x);
else y--;
}
var showInterval = setInterval ( function(){
if(i == 10){
clearInterval(showInterval);
}
$(".container div[data-line='" + usedNum[i] + "']").css({opacity: 0.0, visibility: "visible"}).animate({opacity: 1.0});
i++;
}, 500);
function isUsed(num) {
var used = false;
for(j = 0; j < usedNum.length; j++){
if(usedNum[j] == num){
used = true;
}
}
return used;
}
Demo fiddle : http://jsfiddle.net/xS39F/3/
Edit:
You can also mess around with the speed of the animation. In this demo (http://jsfiddle.net/adjit/XYU34/1/) I set the speed to 1000 so the next element starts fading in before the last element was done fading in. Makes it look a little smoother.
Instead of using a for loop and setTimeout, would setInterval work better for what you need? Some HTML might help better understand what you're trying to achieve.
$(function() {
var box = $('.box');
var delay = 100;
var interval = setInterval(function() {
var new_box = box.clone();
$('.container').append(new_box);
new_box.fadeIn();
}, delay);
delay += 500; // Delay the next box by an extra 500ms
}, delay);
});