Use jQuery's switchClass method to fade in an element? - javascript

Is this possible? I've tried visibility:hidden/visibility:visible and display:none/display:block on the classes to switch between, but both result in the element popping in at the end.

When styling the two classes, use the opacity property. .swithClass will be able to transition smoothly between varying opacities.
Example:
.FadeFrom {
opacity: 0.0;
}
.FadeTo {
opacity: 1.0;
}

Look here on how to implement JQuery Fading
http://api.jquery.com/category/effects/fading/
You can handle other events in the fade in and out using the call back function like this:
$('.someClass').fadeIn('slow', function() {
// run extra code here
});
$('.someClass').fadeOut('slow', function() {
// run extra code here
});

Use .animate()
$("#myElement").animate({ opacity: 1, left: 0 }, 1000);
To get .switchClass() to work, you'll have to edit the jQuery code. Find function getElementStyles(). In the else, after if (typeof style[key] === 'string') { add this code:
if (key == "filter" && /^alpha\(opacity=(\d+)\)$/.test(style[key])) {
newStyle.opacity = parseFloat(RegExp.$1) / 100;
}
That should do it.

Related

successfully reverse the transition with js ,but why my another way doesn't work?

my demo jsfiddle
What I want is a reverse transition when I click the < li > again, but the commentted code didn`t work,and the code below works fine
let dbclickre = true;
function flipped() {
if (dbclickre) {
document.querySelector(".linkrec").setAttribute("Id", "flipped");
} else {
document.querySelector(".linkrec").removeAttribute("Id", "flipped")
}
dbclickre = !dbclickre;
}
below is the commentted code (I think when i firstly click the last < li > ,js will excute the if statement(and indeed it works fine),but when i click again , the else statement didn't excude(but i have set #flipped .reverse {background: whitesmoke} ) . why this happening???)
// const dbclickre = document.querySelector(".reverse");
// function flipped() {
// if (dbclickre.style.backgroundColor = 'white') {
// document.querySelector(".linkrec").setAttribute("Id", "flipped");
// } else {
// document.querySelector(".linkrec").removeAttribute("Id", "flipped")
// }
// }
Instead of relying on background color for checking the state of flip, you could check for existence of Id attribute. Here the the changed code:
const dbclickre = document.querySelector(".reverse");
function flipped() {
if ( document.querySelector(".linkrec").getAttribute("Id") == undefined ) {
document.querySelector(".linkrec").setAttribute("Id", "flipped");
} else {
document.querySelector(".linkrec").removeAttribute("Id", "flipped")
}
}
Edit:
Why element.style would not work?
From MDN Web Docs:
The style property is used to get as well as set the inline style of an element.
Hence, the style property would not work with embedded or external CSS.
Also, it may not be a good idea to use hard-coded colors as the condition, because changing colors in the respective CSS classes would completely break the functionality.

Toggling between two different Opacities

I have all 26 letters in the alphabet and I want to make it so that when you click on it will fade to a lower opacity but if you click on it again it will come back to 1.0 opacity. I have not a single clue on how I would go about specifically choosing the letter that was clicked on and I also cant seem to figure out how I would toggle it to a specific opacity.
$(document).ready(function() {
$(".alphabetLetter").click(function(event) {
var x = event.target||event.srcElement;
if(event.target.style.opacity == 1.0){
$(x).fadeTo('slow',0.5);
} else if(event.target.style.opacity == 0.5){
$(x).fadeTo('slow',1.0);
}
});
});
You can select for the currently clicked element by using $(this) inside the click event handler.
$(document).ready(function() {
$(".alphabetLetter").click(function(event) {
if ($(this).css('opacity') == '1')
$(this).animate({'opacity':0})
else
$(this).animate({'opacity':1})
});
});
Here's a full simple example:
HTML:
<p class="alphabet">abcdefghijklmnopqrstuvwxyz</p>
JavaScript:
// Your container
var $wrap = $('p.alphabet');
// Wrap all letters in <span>
$wrap.html(function(){
return $(this).text().replace(/./g, '<span class="letter">$&</span>');
});
// Attach the event
$wrap.find('.letter').click(function(){
var isHidden = $(this).css('opacity') == .5;
$(this).fadeTo(300, isHidden ? 1 : .5);
});
Demo: http://jsbin.com/eyajel/1/edit
The opacity can just be done with css transitions and regular old styles.
The CSS
.letter {
transition: opacity 1s;
color: red;
cursor: pointer;
}
.letter.active {
opacity: 0.2;
}
The Javascript
$('body').on('click', '.letter', function(e){
$(this).toggleClass('active');
});
Here is a JSFiddle as an example. It also includes a way to take a string of letters and turn them into markup that works with this: http://jsfiddle.net/PFjnB/1/

How do I show or hide div, based on position of another div

I have the following jquery that slides a div horizontally:
$('.nextcol').click(function() {
$('.innerslide').animate({'left': '-=711px'}, 1000);
});
$('.prevcol').click(function() {
$('.innerslide').animate({'left': '+=711px'}, 1000);
});
What I want to happen is this... if the div.innerslide has a position that is left: 0px then I want to hide div.backarrow. If the position is not left: 0px, then it shows it.
Any help would be greatly appreciated.
EDIT (added HTML Markup)
<div class="backarrow prevcol">
<div id="mainleft" class="overflowhidden">
<div class="innerslide">
<div class="col">my content including next</div>
<div class="col">my content including next</div>
<div class="col">my content including next</div>
</div>
</div>
Try this:
if ($('.innerslide').css("left") == 0) {
$('div.backarrow').hide();
} else {
$('div.backarrow').show();
}
Fix for Double-Click Issue:
From what you described in your comment about the issue when the visitor double-clicks, it sounds like the double-click is causing two of the animation events to fire. To keep this from happening, you can either disable the click handler while the animation is running and re-enable it once it is finished, or you can try to write a new thread to continually check the element's position. One of these solutions is not a good idea - I'll let you figure out which one :) - but the other actually has a very simple solution that requires little change to your existing code (and may actually reduce your overhead by a teeny weeny amount):
$('.nextcol').on("click.next", function() {
$('.innerslide').animate({'left': '-=711px'}, 1000, showHideBack());
$(this).off("click.next");
});
$('.prevcol').on("click.prev", function() {
$('.innerslide').animate({'left': '+=711px'}, 1000, showHideForward());
$(this).off("click.prev");
});
Then add this this line to showHideBack() (and a complementary one to showHideForward() if you are using that):
$('.nextcol').on("click.next".....
I suggest that you write a function to set each click handler and another to remove each one. This will make your live very easy and the whole solution should reduce overhead by removing unnecessary click handlers while the animation is running.
Note: the animation method often calls its callback before the animation finishes. As such, you may wish to use a delay before calling the showHide... method(s).
Let me know if you have any questions. Good luck! :)
UPDATE:
Here is the updated version of the fiddle you gave me with all bugs ironed out. It looks like I misunderstood part of your goal in my original solution, but I straightened it out here. I have also included the updated jQuery, here:
var speed = 1000;
var back = $("div.backarrow");
var next = $(".nextcol");
var prev = $(".prevcol");
var inner = $(".innerslide");
function clickNext(index) {
next.off("click.next");
inner.animate({
'left': '-=711px'
}, speed, function() {
back.show(); //this line will only be hit if there is a previous column to show
next.delay(speed).on("click.next", function() {
clickNext();
});
});
}
function clickPrev() {
prev.off("click.prev");
inner.animate({
'left': '+=711px'
}, speed, function() {
if (inner.css("left") == "0px") {
back.delay(speed).hide();
prev.delay(speed).on("click.prev", function() {
clickPrev();
});
} else {
back.delay(speed).show();
prev.delay(speed).on("click.prev", function() {
clickPrev();
});
}
});
}
next.on("click.next", function() {
clickNext();
});
prev.on("click.prev", function() {
clickPrev();
});​
I was going to also include a condition to check if you were viewing the last column, but, as I don't know what your final implementation will be, I didn't know if it would be applicable. As always, let me know if you need help or clarification on any of this. :)
You could try the step option — a callback function that is fired at each step of the animation:
$('.prevcol').click(function() {
$('.innerslide').animate({ left: '+=711px' },
{
duration: 1000,
step: function(now, fx) {
if (now === 0 ) {
$('div.backarrow').hide();
} else {
$('div.backarrow').show();
}
}
});
});
More examples of usage in this article The jQuery animate() step callback function

How to get timing & sequence right in jQuery

Assume we have three light bulbs, and I want to glow the first one, keep it on for a few milliseconds, turn it off, turn on the next and continue in the same way.
Turning the light bulbs on and off is done by adding and removing a class. How do I achieve this?
P.S. I used light bulbs just to make my question clearer. Basically what I need is, how to add a class to a div, keep it for some time, remove class, apply a class to another div, keep it for some time and remove it and so on...
*Edit
Clarification: The number of bulbs is dynamic
You can use a simple combination of setInterval and jquery selecors
Check this fiddle http://jsfiddle.net/aqXtL/1/
The Javascript function setInterval(code, interval) will repeatedly execute code with your interval. Just keep a variable with a counter, and use jquery's addClass and removeClass to turn the lights on and off.
you can use setTimeout like setTimeout(yourfuncname, 3000) == wait 3 seconds then run that function. If you need to use animations then the jquery animate method has a completed callback as a parameter.
very simplified example...
function startDimming(){
setTimeout(_interval,function(){
// Remove all "glowing" bulbs.
// Add class to first "bulb".
setTimeout(_interval,function(){
// Remove all "glowing" bulbs.
// Add class to second "bulb".
setTimeout(_interval,function(){
// Remove all "glowing" bulbs.
// Add class to last "bulb".
startDimming();
});
});
});
}
You can use the animation of jquery and use the complete function to do other tasks.
.animate( properties [, duration] [, easing] [, complete] )
$('#clickme').click(function() {
$('#book').animate({
opacity: 0.25,
left: '+=50',
height: 'toggle'
}, 5000, function() {
// Here you have animated the object and the animation is complete, so
// you can start a new animation here
});
});
HTML :
<div class="bulb"> </div>
<div class="bulb"> </div>
<div class="bulb"> </div>
CSS:
.bulb {
width: 50px;
height: 100px;
border: 2px #000 solid;
float: left;
margin: 10px;
}
.bulb.on {
background: #ff0;
}
Jquery :
var timer;
function light ( i ) {
i = i % $(".bulb").length;
$(".bulb").eq(i).addClass("on").siblings().removeClass("on");
timer = setTimeout(function(){
light( ++i );
}, 1000);
}
$(document).ready( function() {
light(0);
});
Edit : here's a working sample, http://jsfiddle.net/QdWgM/

Prevent another event from firing before a previous one is complete in jQuery?

http://jsfiddle.net/jmPCt/18/
I'm quite new to JS and jQuery. I've written all the code by hand in the link above. It works and does what I want it to save for but one thing. If you click rapidly on the 'next' link, you'll see either a flash of the next container to display or, if you click rapidly enough, the code will display two containers but I only want one to show only at a time. Is there some way of handling this in jQuery? I've tried using stops as discussed here: How to prevent jquery hover event from firing when not complete? but this does not solve the issue.
You are looking for .stop(). It's implementation changes with the desired behavior but the documentation should clear that up for you: http://api.jquery.com/stop
Here is a demo: http://jsfiddle.net/jmPCt/19/
Because of how .stop() works, when you use it with .fadeIn() or .fadeOut() you can chop-up your animations to the point where they no longer work. The best fix I've found is to always animate to absolute values with .fadeTo(): http://api.jquery.com/fadeTo
Here is the code I added to your JSFiddle, this overwrites the default .fadeIn() and .fadeOut() jQuery functions with ones that use .fadeTo() and .stop():
$.fn.fadeOut = function (duration, callback) {
$(this).stop().fadeTo(duration, 0, function () {
$(this).css('display', 'none');
if (typeof callback == 'function') {
callback();
}
});
};
$.fn.fadeIn = function (duration, callback) {
$(this).css('display', 'block').stop().fadeTo(duration, 1, function () {
if (typeof callback == 'function') {
callback();
}
});
};
Update
If you set the position property for the "slide" elements then they can animate on top of each other which will remove the jumpiness that your code exhibits:
HTML --
<div id="controls">
<div id="countah"></div>
<a href="#" id=prev>prev</a> |
<a href="#" id=next>next</a>
</div>
CSS --
.js .staceyPort {
display: none;
position : absolute;
top : 0;
left : 0;
}
#controls{
position : fixed;
bottom : 0;
left : 0;
z-index : 1000;
background : gold;
}​
Here is a demo: http://jsfiddle.net/jmPCt/21/

Categories