jQuery toggle alternative way? - javascript

Since toggle is deprecated I used this to toogle div:
$("#syndicates_showmore").on("click", function () {
if (!clicked) {
$('#syndicates').fadeTo('slow', 0.3, function () {
$(this).css(
{
'height': 'auto',
'overflow': 'none'
});
}).fadeTo('slow', 1);
setTimeout(function () {
$("#syndicates_showmore").text("Show less");
}, 500);
clicked = true;
}
else {
$('#syndicates').fadeTo('slow', 0.3, function () {
$(this).css(
{
'height': '290px',
'overflow': 'hidden'
});
}).fadeTo('slow', 1);
setTimeout(function () {
$("#syndicates_showmore").text("Show more");
}, 500);
clicked = false;
}
});
Is there any cleaner way to do this?

According to the jQuery 1.9 Upgrade Guide:
.toggle(function, function, ... ) removed
This is the "click an element to run the specified functions" signature of .toggle(). It should not be confused with the "change the visibility of an element" of .toggle() which is not deprecated. The former is being removed to reduce confusion and improve the potential for modularity in the library. The jQuery Migrate plugin can be used to restore the functionality.
In other words, you can still use .toggle like this:
var clicked = false;
$("#syndicates_showmore").on("click", function () {
clicked = !clicked;
var showText = "Show " + (clicked ? "more" : "less");
$('#syndicates').toggle(function () {
$("#syndicates_showmore").text(showText);
});
});

Taken from jQuery API
$("#clickme" ).click(function() {
$( "#book" ).toggle( "slow", function() {
// Animation complete.
});
});

The best alternative is to use .toggleClass():
$("#syndicates_showmore").on("click", function () {
$('#syndicates').toggleClass("newClass, 1000", "easeInOutBounce")
});
jQuery .toggleClass() API Documentation:
Description: Add or remove one or more classes from each element in the set of matched elements, depending on either the class's
presence or the value of the switch argument.
If using with jQuery UI you can easily animate it with using different easing options.
Easings:
Easing functions specify the speed at which an animation progresses at
different points within the animation. jQuery UI provides several additional
easing functions, ranging from variations on the swing behavior to
customized effects such as bouncing.
Example online

Related

Creating my custom tooltip using jquery plugin

Using jquery plugin with mouse hide and show I am trying to create tool tip.I am facing two problem
Whether my code is correct for mouseout and mouseleave
When I am creating lot of tooltip it was not positioning correctly it was coming down actually it has to come to right side.
I have found so many from stack Overflow but nothing is working out.
Here is the jquery code
$(document).ready(function() {
$(".tooltip").hide();
$("#help").on({
mouseenter: function () {
$("#showtooltip").show();
},
mouseleave: function () {
$("#showtooltip").hide();
}
});
$("#help1").on({
mouseenter: function () {
$("#showtooltip1").show();
},
mouseleave: function () {
$("#showtooltip1").hide();
}
});
$("#help2").on({
mouseenter: function () {
$("#showtooltip2").show();
},
mouseleave: function () {
$("#showtooltip2").hide();
}
});
});
Third mouse over was not working. I am trying to creating I think missed something.
Here is the jsbin Link
Kindly help me
Thanks & Regards
Mahadevan
Just add this css rules to your .tooltip class:
position: absolute;
top: 40px; /* define how much space from tooltip to the top
and this javascript:
$(document).ready(function() {
$(".tooltip").hide();
$("#help").on({
mouseenter: function (e) {
$("#showtooltip").show();
$("#showtooltip").css('left', e.pageX); // added
},
mouseleave: function () {
$("#showtooltip").hide();
}
});
$("#help1").on({
mouseenter: function (e) {
$("#showtooltip1").show();
$("#showtooltip1").css('left', e.pageX); // added
},
mouseleave: function () {
$("#showtooltip1").hide();
}
});
$("#help2").on({
mouseenter: function (e) {
$("#showtooltip2").show();
$("#showtooltip2").css('left', e.pageX); // added
},
mouseleave: function () {
$("#showtooltip2").hide();
}
});
});
I added only this line in javascript mouseenter function:
$("#showtooltip").css('left', e.pageX);
It sets the tooltip left coordinate, in case you have many items, the tooltip will show exactly beneath the hovered item.
Customization
If you want the tooltip right of the hovered item, you will need to add this css:
var rightMargin = 20; // or whatever fits your needs
$("#showtooltip").css('left', e.pageX + rightMargin);
and change your css top property above.
Update
Since this code of yours is very coupled and you asked for a better solution, here it is jQuery code:
$(document).ready(function() {
$(".tooltip").hide();
$(".help").on({
mouseenter: function (e) {
var tooltip = $(this).next(); tooltip.show();
tooltip.css('left', e.pageX + 20);
},
mouseleave: function () {
$(this).next().hide();
}
});
});
to work this, you gonna have to remove your coupled ids and instead add to every anchor tag class help.
the code simply checks if the user is hovering a link, and if so, then just show the next element after it, which happens to be the tooltip.
Here is a FIDDLE
Cheers

Div animate disappears, rather than resizing

For some reason, when I try to toggle a div between two sizes using .animate, it simply disappears rather than scaling to the size I want it to. I have played with all of the the syntax and little things in so many ways, but nothing works. Here is the jquery that I have used and messed around with a bunch.
$("#expandable").click(
function() {
$("#expandable").toggle(
function() {
$("#expandable").animate(
{width:600, height:600}
)
},
function() {
$("#expandable").animate(
{width:400, height:200}
);
}
);
}
);
I have a jsfiddle here for you to look at.
http://jsfiddle.net/justinbc820/qt7GV/
Try it without using toggle
http://jsfiddle.net/qt7GV/9/
$(document).ready(function(){
$("#expandable").click(function(){
var divheight = $(this).height();
if (divheight == 400)
{
$(this).animate({height:'150px', width:'150px' });
}
else
{
$(this).animate({height:'400px', width:'400px' });
}
});
});
Take a look at this http://jsfiddle.net/qt7GV/4/
$("#expandable").click(function() {
if ($(this).width() < 600) {
$(this).animate(
{width:600, height:600}
)
} else {
$(this).animate(
{width:400, height:200}
);
}
});
http://api.jquery.com/toggle/
Description: Display or hide the matched elements.
var on = false;
var box = $("#expandable");
box.click(
function() {
if (on = !on) {
box.animate(
{width:600, height:600}
)
} else {
box.animate(
{width:400, height:200}
);
}
}
);
According to http://api.jquery.com/toggle-event/
Note: This method signature was deprecated in jQuery 1.8 and removed in jQuery 1.9. jQuery also provides an animation method named .toggle() that toggles the visibility of elements. Whether the animation or the event method is fired depends on the set of arguments passed.
Here is one way to do it
$('#expandable').data('flag', true);
$("#expandable").click(
function() {
$("#expandable").animate(
$(this).data('flag')
? {width:600, height:600}
: {width:400, height:200}
)
$(this).data('flag', !$(this).data('flag'));
}
);

menu fade in effect on mouseover

<ul style="#" class="hmenu">
<li class="active selected">Home</li>
<li>Facebook</li>
<li>Twitter</li>
</ul>
I have a menu with one link as active. I use this script to switch active class on hover
$('.hmenu li').on('mouseenter', function () {
$('.hmenu li').removeClass('active');
$(this).addClass('active');
});
$('.hmenu li').on('mouseleave', function () {
$(this).removeClass('active');
$('.hmenu li[class=selected]').addClass('active');
});
This work's but i want to change it so that when i hover any link, the link should fadeIn and fadeOut on mouseleave.
I can't get my head around this - How can i do this ?
Here is the fiddle : http://jsfiddle.net/GdSUg/
Add the:
transition: all 1s;
to the css code in the class .active
this is an example
See the reference for more information: Here
There you go
$('.hmenu li').hover(function () {
$(this).animate({
backgroundColor: "#89B908"
}, 300);
}, function () {
$(this).animate({
backgroundColor: "#FFF"
}, 1);
});
Fiddle
CSS transitions are one way. Another is to use jQuery UI's built in switchClass functionality. Using your demo:
$('.hmenu li').hover(function() {
if (!$(this).hasClass('active')) $(this).switchClass('','active', 200);
}, function () {
$(this).switchClass('active', '', 200);
});
Requires
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
Reference: http://jqueryui.com/switchClass/
You may notice weird behavior when quickly hovering over elements that require a delayed transition (i.e. - fade, slide) -- Consider using hoverIntent:
What is hoverIntent?
hoverIntent is a plug-in that attempts to
determine the user's intent... like a crystal ball, only with mouse
movement! It is similar to jQuery's hover method. However, instead of
calling the handlerIn function immediately, hoverIntent waits until
the user's mouse slows down enough before making the call. Why? To
delay or prevent the accidental firing of animations or ajax calls.
Simple timeouts work for small areas, but if your target area is large
it may execute regardless of intent. That's where hoverIntent comes
in...
To animate colours reliably with JQuery, you need to use the JQuery Color Plugin (https://github.com/jquery/jquery-color). You can then do something like the following:
var active = {
backgroundColor: '#89B908',
color: '#FFF'
},
inactive = {
backgroundColor: '#FFF',
color: '#000'
};
$('.hmenu li').on('mouseenter', function () {
$(this).animate(active, function () {
$('.hmenu li').removeClass('active').css(inactive);
$(this).addClass('active').css(active);
}).find('a').animate({
color: '#FFF'
});
});
$('.hmenu li').on('mouseleave', function () {
$(this).animate(inactive, function () {
$(this).removeClass('active');
$('.hmenu li.selected').addClass('active').css(active);
}).find('a').animate({
color: '#000'
});
});
You can find a working jsFiddle here: http://jsfiddle.net/GdSUg/28/

How to use jQuery to wait for the end of CSS3 transitions?

I'd like to fade out an element (transitioning its opacity to 0) and then when finished remove the element from the DOM.
In jQuery this is straight forward since you can specify the "Remove" to happen after an animation completes. But if I wish to animate using CSS3 transitions is there anyway to know when the transition/animation has completed?
For transitions you can use the following to detect the end of a transition via jQuery:
$("#someSelector").bind("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });
Mozilla has an excellent reference:
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#Detecting_the_start_and_completion_of_a_transition
For animations it's very similar:
$("#someSelector").bind("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function(){ ... });
Note that you can pass all of the browser prefixed event strings into the bind() method simultaneously to support the event firing on all browsers that support it.
Update:
Per the comment left by Duck: you use jQuery's .one() method to ensure the handler only fires once. For example:
$("#someSelector").one("transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd", function(){ ... });
$("#someSelector").one("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function(){ ... });
Update 2:
jQuery bind() method has been deprecated, and on() method is preferred as of jQuery 1.7. bind()
You can also use off() method on the callback function to ensure it will be fired only once. Here is an example which is equivalent to using one() method:
$("#someSelector")
.on("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
function(e){
// do something here
$(this).off(e);
});
References:
.off()
.one()
There is an animationend Event that can be observed see documentation here,
also for css transition animations you could use the transitionend event
There is no need for additional libraries these all work with vanilla JS
document.getElementById("myDIV").addEventListener("transitionend", myEndFunction);
function myEndFunction() {
this.innerHTML = "transition event ended";
}
#myDIV {transition: top 2s; position: relative; top: 0;}
div {background: #ede;cursor: pointer;padding: 20px;}
<div id="myDIV" onclick="this.style.top = '55px';">Click me to start animation.</div>
Another option would be to use the jQuery Transit Framework to handle your CSS3 transitions. The transitions/effects perform well on mobile devices and you don't have to add a single line of messy CSS3 transitions in your CSS file in order to do the animation effects.
Here is an example that will transition an element's opacity to 0 when you click on it and will be removed once the transition is complete:
$("#element").click( function () {
$('#element').transition({ opacity: 0 }, function () { $(this).remove(); });
});
JS Fiddle Demo
For anyone that this might be handy for, here is a jQuery dependent function I had success with for applying a CSS animation via a CSS class, then getting a callback from afterwards. It may not work perfectly since I had it being used in a Backbone.js App, but maybe useful.
var cssAnimate = function(cssClass, callback) {
var self = this;
// Checks if correct animation has ended
var setAnimationListener = function() {
self.one(
"webkitAnimationEnd oanimationend msAnimationEnd animationend",
function(e) {
if(
e.originalEvent.animationName == cssClass &&
e.target === e.currentTarget
) {
callback();
} else {
setAnimationListener();
}
}
);
}
self.addClass(cssClass);
setAnimationListener();
}
I used it kinda like this
cssAnimate.call($("#something"), "fadeIn", function() {
console.log("Animation is complete");
// Remove animation class name?
});
Original idea from http://mikefowler.me/2013/11/18/page-transitions-in-backbone/
And this seems handy: http://api.jqueryui.com/addClass/
Update
After struggling with the above code and other options, I would suggest being very cautious with any listening for CSS animation ends. With multiple animations going on, this can get messy very fast for event listening. I would strongly suggest an animation library like GSAP for every animation, even the small ones.
The accepted answer currently fires twice for animations in Chrome. Presumably this is because it recognizes webkitAnimationEnd as well as animationEnd. The following will definitely only fires once:
/* From Modernizr */
function whichTransitionEvent(){
var el = document.createElement('fakeelement');
var transitions = {
'animation':'animationend',
'OAnimation':'oAnimationEnd',
'MSAnimation':'MSAnimationEnd',
'WebkitAnimation':'webkitAnimationEnd'
};
for(var t in transitions){
if( transitions.hasOwnProperty(t) && el.style[t] !== undefined ){
return transitions[t];
}
}
}
$("#elementToListenTo")
.on(whichTransitionEvent(),
function(e){
console.log('Transition complete! This is the callback!');
$(this).off(e);
});
Chainable one-way events with promises
In case that you need one-way events just like JQuery's one(), I found this pattern handy:
function awaitTransitionEnd(transitionProperty, el, triggerFunction) {
return new Promise((resolve, reject) => {
const handler = (e) => {
if (e.propertyName !== transitionProperty) {
return;
}
el.removeEventListener('transitionend', handler);
resolve(e);
}
el.addEventListener('transitionend', handler);
triggerFunction(el);
});
}
You can then chain CSS transitions like in this example:
awaitTransitionEnd(
'background-color', myEl, () => myEl.classList.replace('bg-red', 'bg-green')
).then(() => awaitTransitionEnd(
'opacity', myEl, () => myEl.classList.add('opacity-0')
)).then(() => awaitTransitionEnd(
'opacity', myEl, () => myEl.classList.remove('opacity-0')
));
If you don't want to use arrow functions, you must pass the event + element like so:
awaitTransitionEnd('background-color', myEl, function(el) {
el.classList.replace('bg-red', 'bg-green');
}).then(function(e) {
return awaitTransitionEnd('opacity', e.target, function(el) {
el.classList.add('opacity-0');
});
}).then(function(e) {
return awaitTransitionEnd('opacity', e.target, function(el) {
el.classList.remove('opacity-0');
});
});
When awaitTransitionEnd is a class method and you don't want to use arrow functions, you must bind this to each then()-closure:
//[...]
.then(function(e) {
return this.awaitTransitionEnd('opacity', e.target, function(el) {
el.classList.add('opacity-0');
});
}.bind(this)).then(//[...]

jQuery Combine Functions

I have two similar functions that I would like to combine so that I can use anywhere throughout the site. It's a simple jquery slideUp / slideDown effect that finds the div with the class 'hidden' and on click, it shows and hides
$('.clicker1').click(function(){
// grab the hidden content
var desc = $(this).parent().find('.hidden');
// remove toggle class and slide up
if ($(this).hasClass('toggled')) {
$(this).removeClass('toggled');
$(desc).slideUp(400, 'linear');
}
// add toggle class, slide down, and move the page up
else {
var loc = this;
$(desc).slideDown(400, 'linear', function () {
$.scrollTo($(loc).offset().top - 60, 400);
});
$(this).addClass('toggled');
$('.clicker1').not(this).removeClass('toggled');
$('.hidden').not(desc).slideUp(400, 'linear');
}
});
$('.clicker2').click(function(){
// grab the hidden content
var desc = $(this).parent().find('.hidden2');
// remove toggle class and slide up
if ($(this).hasClass('toggled')) {
$(this).removeClass('toggled');
$(desc).slideUp(400, 'linear');
}
// add toggle class, slide down, and move the page up
else {
var loc = this;
$(desc).slideDown(400, 'linear', function () {
$.scrollTo($(loc).offset().top - 60, 400);
});
$(this).addClass('toggled');
$('.clicker2').not(this).removeClass('toggled');
$('.hidden').not(desc).slideUp(400, 'linear');
}
});
Can I create one function and put in my own 'clickerX' and 'hiddenX' ?
It looks like the handlers only differ by the class's they use as selectors. The easiest approach is to write a function which generates a click handler based on the class names. Try the following
var makeHandler = function(className, hiddenClassName, ) {
return function() {
// grab the hidden content
var desc = $(this).parent().find(hiddenClassName);
// remove toggle class and slide up
if ($(this).hasClass('toggled')) {
$(this).removeClass('toggled');
$(desc).slideUp(400, 'linear');
}
// add toggle class, slide down, and move the page up
else {
var loc = this;
$(desc).slideDown(400, 'linear', function () {
$.scrollTo($(loc).offset().top - 60, 400);
});
$(this).addClass('toggled');
$(className).not(this).removeClass('toggled');
$(hiddenClassName).not(desc).slideUp(400, 'linear');
};
};
$('.clicker1').click(makeHandler('.clicker1', '.hidden'));
$('.clicker2').click(makeHandler('.clicker2', '.hidden2'));
Absolutely. You want to write a plugin. There's tons of tutorials on making a jQuery plugin, but the official docs give a good start.

Categories