Lets say I have some element with id="circle" and some button with id="button". All I need to do is:
Circle is blinking by default;
When user presses the button, circle stops blinking;
When user presses the button once more, circle starts blinking;
And so on.
I am trying to do this with the following code:
var blinking = true;
function flash(elementId) {
var bl = document.getElementById(elementId);
bl.style.visibility = bl.style.visibility == "hidden" ? "visible" : "hidden";
}
function buttonClick() {
if (blinking) {
clearInterval(flash('circle'));
} else {
setInterval(flash('circle'), 200);
}
}
setInterval(flash('circle'), 200);
<!DOCTYPE html>
<html>
<body>
<strong id="circle">●</strong>
<br>
<button type="button" id="leftButton" onclick="buttonClick()">toggle</button>
</body>
</html>
but it doesnt work in desirable way. If the solution's code in pure JS will be too large, you can write it with jquery, it doesnt really matter.
You are calling the flash method, instead you need to provide a callback to setIterval. Also you should store an interval handler to some variable, and use it when calling clearInterval. Last thing that is missing in your code is toggling the blinking boolean value on each click.
var interval;
function buttonClick() {
if (blinking) {
clearInterval(interval);
} else {
interval = setInterval(flash.bind(null, 'circle'), 200);
}
blinking = !blinking;
}
buttonClick();
Or you could simply use function(){}, like this:
interval = setInterval(function() {
flash('circle');
}, 200);
var blinkingInter = null,
circle = document.querySelector('#circle');
//#param ele element object
function toggleCircle(ele) {
ele.classList.toggle('hidden');
}
// first parameter of setInterval is function
blinkingInter = setInterval(function() {toggleCircle(circle)},
200);
function buttonClick() {
if(blinkingInter !== null) {
clearInterval(blinkingInter);
// set blinkingInter to null
blinkingInter = null;
} else {
blinkingInter = setInterval(function() {
toggleCircle(circle)}, 200);
}
}
This code is used with both jquery and css:
the css:
#keyframes blink {
0%{opacity: 0.0;}
50%{opacity: 1.0;}
100%{opacity: 0.0;}
}
.circle {
display: inline-block;
background: #f00;
width:30px;
height:30px;
border-radius:15px;
margin:auto;
margin-top: 20px;
margin-bottom: 20px;
}
.circle.blinker {
animation: blink .3s infinite;
}
.jdhf {
background: blue;
}
And the jquery:
$("*").on("click","#button", function(e){
e.stopPropagation();
//verify if the div is blinking and then stop blinking
var f=$(".blinker").length;
if(f>0){
$("#circle").removeClass("blinker");
}
else {
$("#circle").addClass("blinker");
}
});
The html:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<div id="circle" class="circle blinker">
</div>
<button id="button" class="jdhf">
Toggle animation
</button>
Try it here: https://jsfiddle.net/amostk/ev5uusra/3/
Since toggle is not used for two functions anymore, you need to set a variable (either class or hidden tag) for switching. This example shows hidden input instead of a variable (since Boolean variable would not be flexible for multiple buttons, and using opacity blink as a cool option which I found somewhere else here on Stack.
<div id="circle">
text
</div>
<div id="button">
<input type="hidden" value=0 />
button
</div>
<script>
var circle = setInterval(function(){blink()}, 1000);
function blink() {
$("#circle").fadeTo(100, 0.1).fadeTo(200, 1.0);
}
$("#button").click(function() {
var a = $(this).find("input[type='hidden']").val() == 0 ? 1 : 0;
if ( a == 1 ) {
clearInterval(circle);
}else {
circle = setInterval(function(){blink()}, 1000);
}
$(this).find("input[type='hidden']").val(a);
});
</script>
Related
I can't seem to make the opening part of this transition work, only the closing part.
The reason I've structured my html the way that I have, is because I need to use display: none and display:block to actually remove the element from the document flow. Using display to show and hide elements is problematic generally speaking when combining with animation, so the idea is to have a container element be subject to the display rules, and have the child element animate.
See my code and/or JSBin:
<button id="gallery_menu__trigger">Click me now</button>
<div id="gallery_menu__list">
<div id="gallery_menu__list_items" class="gallery_menu__revealable">Hello!</div>
</div>
CSS:
#gallery_menu__list {
display:none;
}
.gallery_menu__revealable {
transform: translatey(-20px);
opacity: 0;
will-change: transform, opacity;
transition: all .3s ease;
}
.gallery_menu__revealable--visible {
transform: translateX(0);
opacity: 1;
}
.gallery_menu__revealable--animating {
transition: all .3s ease;
}
And JS:
function init () {
var galleryMenuTrigger = document.getElementById('gallery_menu__trigger');
var galleryMenuList = document.getElementById('gallery_menu__list');
var galleryMenuListItems = document.getElementById('gallery_menu__list_items');
galleryMenuTrigger.addEventListener('click', toggleGalleryMenu(galleryMenuList, galleryMenuListItems), false)
galleryMenuListItems.addEventListener('transitionend', onTransitionEnd(galleryMenuListItems), false)
}
function toggleGalleryMenu (galleryMenuList, galleryMenuListItems) {
return function () {
if (galleryMenuList.style.display === 'block') {
addAnimatingClass(galleryMenuListItems)
closeGalleryMenuListItems(galleryMenuListItems);
setTimeout(closeGalleryMenu(galleryMenuList), 300);
return;
}
displayGalleryMenu(galleryMenuList)
addAnimatingClass(galleryMenuListItems)
displayGalleryMenuListItems(galleryMenuListItems);
}
}
function addAnimatingClass (galleryMenuListItems) {
galleryMenuListItems.classList.add('gallery_menu__revealable--animating')
}
function onTransitionEnd (galleryMenuListItems) {
return function () {
return galleryMenuListItems.classList.remove('gallery_menu__revealable--animating');
}
}
function displayGalleryMenu (galleryMenuList) {
galleryMenuList.style.display = 'block'
}
function closeGalleryMenu (galleryMenuList) {
return function() {
return galleryMenuList.style.display = 'none'
}
}
function displayGalleryMenuListItems (galleryMenuListItems) {
return galleryMenuListItems.classList.add('gallery_menu__revealable--visible')
}
function closeGalleryMenuListItems (galleryMenuListItems) {
return galleryMenuListItems.classList.remove('gallery_menu__revealable--visible')
}
init();
You are close to solution, I've made a little changes, I've removed addAnimatingClass(galleryMenuListItems) and changed displayGalleryMenuListItems(galleryMenuListItems. Look:
function displayGalleryMenuListItems (galleryMenuListItems) {
return setTimeout(function(){
galleryMenuListItems.classList.add('gallery_menu__revealable--visible')
},300)
}
Here is a working fiddle: https://jsfiddle.net/xg5fhyst/
i am currently having a problem. I am using css to hide and display elements depending on the mouse function. One of my elements (a navigation arrow) depends on some other things. I now need a cancleable timer function which counts for lets say 2 seconds on mouseleave and then changes the class attribute. But it should have a timer which cancels on mouseover immediately. I dont want it to disappear too early.
Below my code with which i tried so far. I have no idea how to access the current timings of that setIntervall stuff. I alreasy experimented with Date.now(). But now i hope some of the geeks is able to help me.
Thanks in advance.
function hideElementOnMouseOut(el)
{
el.addEventListener("mouseleave", function( event )
{
mySlideAction = setInterval( function()
{
}, 1000 );
}
}
You can initialize interval on mouseleave function and clear this interval on mouseover function, which would prevent executing it's function.
Check the snippet below.
function hideElementOnMouseOut(el)
{
var interval;
el.addEventListener("mouseleave", function(event)
{
el.innerHTML = 'mouse out';
interval = setInterval(function()
{
el.innerHTML = 'time out';
el.className = 'out';
}, 1000);
});
el.addEventListener("mouseover", function(event)
{
el.innerHTML = 'mouse in';
el.className = '';
if(interval) {
clearInterval(interval);
}
});
}
hideElementOnMouseOut(document.getElementById("element"));
#element {
display: block;
width: 200px;
height: 200px;
background: red;
}
#element.out {
background: blue;
}
<div id="element"></div>
I need loop this script, but i don't know how to do this...
$(zaj).ready(function(){
$("#zaj1").fadeOut(6000);
$('#zaj2').delay(7000).fadeOut(6000);
$('#zaj1').delay(7000).fadeIn(6000);
});
And I want to loop this. This is changing background img for div.
Try:
$(zaj).ready(function(){
var flag = 1;
do{
$("#zaj1").fadeOut(6000function(){
$('#zaj2').delay(7000).fadeOut(6000, function(){
$('#zaj1').delay(7000).fadeIn(6000);
});
});
}while(flag ==1);
});
but again, it do what you ask but you could find better ways... like:
$(zaj).ready(function(){
setInterval(function(){
$("#zaj1").fadeOut(6000, function(){
$('#zaj2').fadeOut(6000, function(){
$('#zaj1').fadeIn(6000);
});
});
}, 19000);
});
Cleaner code so it has clean recursive loop
https://jsfiddle.net/egwmpsa7/
function start() {
$("#first").fadeOut(1000, function() {
$('#second').delay(1500).fadeOut(1000);
$('#first').delay(1500).fadeIn(1000, function() {
$('#second').delay(1500).fadeIn(1000, start);
setTimeout(start, 1500)
});
})
}
start();
<div id="first">first</div>
<div id="second">second</div>
my solution:
function() {
$('#zaj1').fadeIn(1000).delay(2000).fadeOut(1000, function() {
$('#zaj2').fadeIn(1000).delay(2000).fadeOut(1000);
})
}
$(document).ready(function(){
setInterval(fades, 8000);
fades();
});
HTML:
<p id='zaj1' style="display: none;">
zaj1
</p>
<p id='zaj2' style="display: none;">
zaj2
</p>
demo: https://jsfiddle.net/gjfg22bz/4/
This can be done for quick scaling as you add more possible images. All you have to do is customize the variables here at the top, and you're done. The function will handle the rest.
var images = ['#zaj1', '#zaj2']; // Add as many as you want
var delayTime = 1000; // The time the image shows before starting the fade process
var fadeTime = 6000; // How fast the fadein/out should happen
var currentIndex = 0;
function loopOverImages() {
$(images[currentIndex]).delay(delayTime).fadeOut(fadeTime, function () {
++currentIndex;
if (currentIndex == images.length) {
currentIndex = 0;
}
$(images[currentIndex]).fadeIn(fadeTime, loopOverImages);
});
}
loopOverImages(); // Call immediately to start the process
Check out the really simple code snippet to help illustrate how simple this can be:
var images = ['#zaj1', '#zaj2', '#zaj3'];
var currentIndex = 0;
var delayTime = 2000;
var fadeTime = 1000;
function loopOverImages() {
$(images[currentIndex]).delay(delayTime).fadeOut(fadeTime, function() {
++currentIndex;
if (currentIndex == images.length) {
currentIndex = 0;
}
$(images[currentIndex]).fadeIn(fadeTime, loopOverImages);
});
}
loopOverImages();
div {
width: 100px;
height: 100px;
display: none;
}
#zaj1 {
background-color: rebeccapurple;
display: block;
}
#zaj2 {
background-color: #f08e86;
}
#zaj3 {
background-color: aqua;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.min.js"></script>
<div id="zaj1"></div>
<div id="zaj2"></div>
<div id="zaj3"></div>
Select the elements to be looped through.
Initiate a variable for storing which element is visible now
Loop through using setInterval
update 'current' after each run
$("document").ready(function(){
var elements=$("#zaj1, #zaj2, #zaj3");
current=0;
elements.eq(current).fadeIn(6000);
setInterval(function(){
var next=current+1>elements.length-1?0:current+1;
elements.eq(current).fadeOut(6000);
elements.eq(next).fadeIn(6000);
current=next;
},7000);
});
[id^=zaj]{
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="zaj1">One</div>
<div id="zaj2">Two</div>
<div id="zaj3">Three</div>
I have this JavaScript to make the div flash every two seconds. I was wondering if I could add anything into this current function so that the div fades in and out instead of appearing and disappearing with no transition.
JavaScript
<script language = "javascript">
function flash()
{
var blinker = 2000
var timeIn = setInterval(function() {
var element = document.getElementById('sign');
element.style.visibility = (element.style.visibility == 'hidden' ? '' : 'hidden');
}, blinker);
}
</script>
HTML div
<div class = "sign" id = "sign">
<p> hello </p>
</div>
Since you've tagged jQuery, you can simplify it to:
$('#sign').fadeIn(2000); // fade-in in 2 seconds
and
$('#sign').fadeOut(2000); // fade-out in 2 seconds
or as pointed out by user: Bondye
function flash() {
$('#sign').fadeToggle(2000);
}
If you want it to continue fading in and out.. you could try something like this:
function keepFading($obj) {
$obj.fadeToggle(2000, function () {
keepFading($obj)
});
}
keepFading($("#sign"));
See working example in Fiddle
This function would then work on any jquery object you pass it. So if you have something else you want to do the same thing you can just call it like keepFading($("#someOtherEle"));
For this to work, you'll need to make sure that jquery is included. You can then put the above code at the bottom of your html... or in your head if you wrap in a $(document).ready( ... )
You can implement fadeIn and fadeOut on pure javascript:
function fadeOut(id,val){
if(isNaN(val)){
val = 9;
}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val>0){
val–;
setTimeout('fadeOut("'+id+'",'+val+')',90);
}else{
return;
}
}
function fadeIn(id,val){
// ID of the element to fade, Fade value[min value is 0]
if(isNaN(val)){
val = 0;
}
document.getElementById(id).style.opacity='0.'+val;
//For IE
document.getElementById(id).style.filter='alpha(opacity='+val+'0)';
if(val<9){
val++;
setTimeout('fadeIn("'+id+'",'+val+')',90);
}else{
return;
}
}
Here's a FIDDLE
setInterval(function() {
$('.sign').animate({ opacity: '0' }, 800).animate({ opacity: '1' }, 800);
}, 2000);
It is also possible to fadeToggle with jQuery. See details here:
http://api.jquery.com/fadeToggle/
<script>
function flash(id) {
$('#'+id).fadeToggle();
}
var blinker = 2000;
var timeIn = setInterval(function() {
flash('sign');
}, blinker);
</script>
I am trying to make an element 'vibrate' using JavaScript upon clicking it by repetitively changing the value of document.getElementById("ElementID").style.left. I change it a number of times in a particular function, but instead of moving each time I change it, it only moves at the end of the function i.e. the last time I make the change. Here is the HTML code:
<html>
<body>
<script>
function changePosition() {
if (document.getElementById("ElementID").style.left == "50%") {
document.getElementById("ElementID").style.left = "52%";
} else {
document.getElementById("ElementID").style.left = "50%";
}
}
function vibrate() {
changePosition();
setTimeout(changePosition, 50);
setTimeout(changePosition, 50);
setTimeout(changePosition, 50);
setTimeout(changePosition, 50);
}
</script>
<button id="ElementID" type="button" style="position:absolute; top:50%; left:50%;" onclick="vibrate()">Vibrate Me</button>
</body>
</html>
At the end I only see the position of the button as it should have been but I can't see the transition during the change. What am I doing wrong?
It seems that all timeouts will execute at the same time. Try changing to this
setTimeout(changePosition,100);
setTimeout(changePosition,200);
setTimeout(changePosition,300);
setTimeout(changePosition,400);
or
for (var i = 1; i < 5; i++) {
setTimeout(changePosition,100*i);
}
Heres an example using setInterval rather than timeout. Mess with the numbers and you should be able to get your desired result
http://jsbin.com/oSIXayun/4/
HTML:
<button id="ElementID" type="button" style="position:absolute; top:50%; left:50%;">Vibrate Me</button>
JS:
function changePosition() {
if (document.getElementById("ElementID").style.left=="50%") {
document.getElementById("ElementID").style.left="52%";
}
else {document.getElementById("ElementID").style.left="50%";}
}
function vibrate() {
changePosition();
setTimeout(changePosition,50);
setTimeout(changePosition,100);
setTimeout(changePosition,150);
setTimeout(changePosition,200);
}
document.getElementById("ElementID").onclick = vibrate;
:)
All the setTimeout calls within vibrate() are made at the same time. You can address this by calling changePosition() based on the number of vibrations you require and repeating the function using setTimeout.
(function () {
var vibrating = 0;
function changePosition() {
if (document.getElementById("ElementID").style.left == "50%") {
document.getElementById("ElementID").style.left = "52%";
} else {
document.getElementById("ElementID").style.left = "50%";
}
if (vibrating != 0) {
vibrating--;
var t = setTimeout(changePosition,50);
}
}
function vibrate() {
vibrating = 4;
changePosition();
}
document.getElementById('ElementID').onclick = vibrate;
})();