According to this jQuery UI documentation, there is a toggleClass method which takes an options object. However, looking in the source, I don't see this version of the method being supported. When I try to the following, no animation occurs:
$("#element").toggleClass("fixed", showOrHide, {
duration: animationDuration,
easing: "swing",
queue: false,
children: true
});
I'm using jQuery 1.10.2 and jQuery UI 1.11.0. Am I missing something here?
Please view this jsfiddle example and here is a version without Bootstrap to show that it is not a conflict issue.
Note: .addClass( className [, options ] ) does not work either!
jQuery UI Snippet
toggleClass: (function( orig ) {
return function( classNames, force, speed, easing, callback ) {
if ( typeof force === "boolean" || force === undefined ) {
if ( !speed ) {
// without speed parameter
return orig.apply( this, arguments );
} else {
return $.effects.animateClass.call( this,
(force ? { add: classNames } : { remove: classNames }),
speed, easing, callback );
}
} else {
// without force parameter
return $.effects.animateClass.call( this,
{ toggle: classNames }, force, speed, easing );
}
};
})( $.fn.toggleClass )
Try like this
var animationDuration=1000;
var t=true;
function showOrHide()
{
if(t)
t=false
else
t=true
return t;
}
$("#element").toggleClass( "fixed",showOrHide(),{duration:animationDuration, easing:"swing",queue: true});
you can also use like this
$("#element").toggleClass( "fixed",{switch:showOrHide,duration:animationDuration, easing:"swing",queue: true});
Related
I'm trying to implement smoothState.js into a custom WordPress theme. I'm flummoxed. I feel like my code is correct according to the smoothState documentation, but it's still producing an error. But I'm still a beginner at JS/JQuery and scripting in general so I'm probably missing something.
Using JQMigrate version 1.4.1 and JQuery 1.12.4 in noConflict mode. WordPress is 4.6.1.
jQuery(document).ready(function($){ // WordPress doesn't release $ so we need this line
$(function() {
var $body = $('html, body'),
content = $('#wrapper').smoothState({
prefetch: true,
pageCacheSize: 4,
debug: true,
// onStart is for when a link is clicked
onStart: {
duration: 2500, // animation duration in ms
render: function (url, $container) {
$container.addClass('is-exiting');
$body.animate({
scrollTop: 0
});
smoothState.restartCSSAnimations();
}
},
onEnd : {
duration: 1500, \
render: function (url, $container, $content) {
$container.removeClass('is-exiting');
$body.css('cursor', 'auto');
$body.find('a').css('cursor', 'auto');
$container.html($content);
// Trigger document.ready and window.load
$(document).ready();
$(window).trigger('load');
}
},
onAfter : function(url, $container, $content) {
}
}).data('smoothState');
});
(function($, undefined) {
var isFired = false;
var oldReady = jQuery.fn.ready;
$(function() {
isFired = true;
$(document).ready();
});
jQuery.fn.ready = function(fn) {
if(fn === undefined) {
$(document).trigger('_is_ready');
return;
}
if(isFired) {
window.setTimeout(fn, 1);
}
$(document).bind('_is_ready', fn);
};
})(jQuery);
});
Clicking any hyperlink inside #wrapper throws the following console error...
Uncaught TypeError: Cannot read property 'addClass' of undefined
w # jquery.smoothState.min.js:9
b # jquery.smoothState.min.js:9
dispatch # jquery.js?ver=1.12.4:3
r.handle # jquery.js?ver=1.12.4:3
I've checked for any potential plugin or theme conflicts and found none. I've even tried explicitly declaring the container like var $container = $("#wrapper"); but still get the same results. Any ideas?
After looking over the smoothState onStart documentation it seems the render function only accepts a single argument like so:
$('#main').smoothState({
onStart: {
// How long this animation takes
duration: 0,
// A function that dictates the animations that take place
render: function ($container) {}
}
});
Your code has two:
render: function (url, $container) {
This would likely cause your render function url argument to be set to $container as it is the first argument passed, and the $container argument to be undefined, as the argument is never passed/set. Thus, when you call:
$container.addClass('is-exiting');
You receive the error:
Cannot read property 'addClass' of undefined
Because $container is not an object.
I have the same problem as in this question here, which is the conflict between jQuery UI and Bootstrap. The given answer from Darkseal
$.widget.bridge('uibutton', $.ui.button);
completely solved my problem for the "button"-widget. But it seems to me, that also the "buttonset"-widget reveals a conflict between the two libraries but
$.widget.bridge('uibuttonset', $.ui.buttonset);
does not do the trick for me. Am I doing something wrong?
This is an older question but I thought I'd share my fix for this.
You don't need the..
$.widget.bridge('uibuttonset', $.ui.buttonset);
There isn't any conflict there with Bootstrap (v3.3.6). The issue is $.ui.buttonset makes calls to .button() which isn't the the new name you declared so the conflict lives on. To fix this, I updated the calls to .button() inside .buttonset() to match the new name, "uibutton" or whatever you declare it as.
Below is my code for version jQuery UI 1.11.4. Perhaps there is an easier fix, but I've not come across it.
$.widget( "ui.buttonset", {
version: "1.11.4",
options: {
items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
},
_create: function() {
this.element.addClass( "ui-buttonset" );
},
_init: function() {
this.refresh();
},
_setOption: function( key, value ) {
if ( key === "disabled" ) {
this.buttons.uibutton( "option", key, value );
}
this._super( key, value );
},
refresh: function() {
var rtl = this.element.css( "direction" ) === "rtl",
allButtons = this.element.find( this.options.items ),
existingButtons = allButtons.filter( ":ui-button" );
// Initialize new buttons
allButtons.not( ":ui-button" ).uibutton();
// Refresh existing buttons
existingButtons.uibutton( "refresh" );
this.buttons = allButtons
.map(function() {
return $( this ).uibutton( "widget" )[ 0 ];
})
.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
.filter( ":first" )
.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
.end()
.filter( ":last" )
.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
.end()
.end();
},
_destroy: function() {
this.element.removeClass( "ui-buttonset" );
this.buttons
.map(function() {
return $( this ).uibutton( "widget" )[ 0 ];
})
.removeClass( "ui-corner-left ui-corner-right" )
.end()
.uibutton( "destroy" );
}
});
I hope that helps you and everyone else.
I want to implement a jQuery animation callback method progress or step,
but in either case I'm getting the following error:
NS_ERROR_IN_PROGRESS: Component returned failure code: 0x804b000f (NS_ERROR_IN_PROGRESS) [nsICacheEntry.dataSize]
I searched a lot but not able to find anything in context, I am kind of stuck here, please suggest what could cause this error?
In fiddle i tried with step and progress and its working there , but not able to get it worked in my code, I am just looking, has some one faced such kind of error in jquery animation?
The sample code is:
this.taskHandle.find('img').stop(true, true).animate({
//todo//
top: vtop, // this.taskHandle.outerHeight(),
//'top': 0 - $('.target.upper').height(),
width: 0,
opacity: 0
}, {
duration: 2000,
step: function(){
console.log('I am called');
}
},
$.proxy(function() {
// some css clearing method
}, {
// some further actions after animation completes
})
);
You have some semantic errors going on here. I'm going to repost your code, formatted for easier reading:
this.taskHandle.find('img')
.stop(true, true)
.animate(
{
//todo//
top: vtop , // this.taskHandle.outerHeight(),
//'top' : 0 - $('.target.upper').height(),
width : 0,
opacity : 0
},
{
duration:2000,
step: function() {
console.log('I am called');
}
},
$.proxy(
function() {
// some css clearing method
},
{
// some further actions after animation completes
}
)
);
First: animate() doesn't accept 3 parameters (at least not those 3 parameters). I'm not sure what you are trying to do with your css clearing method, but anything you wan't to happen after the animation is complete should be in the complete method that you add right next to the step method.
Second: $.proxy() needs to have the context in which you want it to run as the second parameter, not some other"complete"-function.
So here is a slightly modified example which works. You can try it yourself in this fiddle.
var vtop = 100;
$('div')
.stop(true, true)
.animate(
{
top: vtop,
width: 0,
opacity : 0
},
{
duration: 2000,
step: function() {
console.log('I am called');
},
complete: function () {
alert('complete');// some further actions after animation completes
}
}
);
You could use Julian Shapiro's Velocity.js, which animations are (arguable) faster than jQuery and CSS (read this for more)
It allows you to use callbacks such as :
begin
progress
complete
like :
var vtop = 100;
jQuery(document).ready(function ($) {
$('div').find("img").velocity({
top: vtop,
width: 0,
opacity: 0
}, {
duration: 2000,
begin: function (elements) {
console.log('begin');
},
progress: function (elements, percentComplete, timeRemaining, timeStart) {
$("#log").html("<p>Progress: " + (percentComplete * 100) + "% - " + timeRemaining + "ms remaining!</p>");
},
complete: function (elements) {
// some further actions after animation completes
console.log('completed');
$.proxy( ... ); // some css clearing method
}
});
}); // ready
Notice that you just need to replace .animate() by .velocity()
See JSFIDDLE
I have the following code:
var isOn = false;
$('.switch').on("click",function(){
if (isOn){
$('.toggle').animate({
left:"18px"
},10,"linear",
{
complete: function(){
$('#label').text("ON");
}
});
isOn = false;
} else {
$('.toggle').animate({
left:"4px"
}, 10,"linear",
{
complete: function(){
$('#label').text("OFF");
}
});
isOn = true;
}
});
http://codepen.io/pietrofxq/pen/LpzDE?editors=001
It is a switch on/off made with jquery. It was working without the animate() method.
I was doing the animation with css, but it was buggy in Internet Explorer.
Here is the original effect: http://codepen.io/anon/pen/iwatp
Why the complete function in the first link isn't working?
EDIT: This code is working but still doesnt work properly on IE
You seem to be mixing the two different signatures of the .animate function. If you pass the duration and the easing directly as arguments, you have to do the same for the callback function:
$('.toggle').animate({left: "18px"}, 10, "linear", function(){
$('#label').text("ON");
});
OR you have to pass two objects:
$('.toggle').animate(
{
left:"18px"
},
{
duration: 10,
easing: "linear",
complete: function(){
$('#label').text("ON");
}
}
);
now it will work. please check the jsfiddle link
http://jsfiddle.net/banded_krait/da2kE/
I removed some brackets and complete: array key from your code and hope this will work for you.
I have a jQuery plugin that uses namespacing (methods) and also has options, with defaults, that can be overridden on initialization.
I'm wondering what the best way to define and use options is with this plugin in the namespaces.
I was originally using a $.fn.dropIt.settings within the wrapper function to define the settings, but then switched to defining them inside of the init method. This is very limiting in terms of scope however..
Here is the relevant code in my plugin
(function($, window, document, undefined){
var methods = {
init: function(options)
{
var settings = $.extend({
trigger: "hover",
animation: 'slide', /* none, slide, fade, grow */
easing: 'swing', /* swing, linear, bounce */
speedIn: 400,
speedOut: 400,
delayIn: 0,
delayOut: 0,
initCallback: function(){},
showCallback: function(){},
hideCallback: function(){}
}, options);
$(this).each(function(index, ele){
$ele = $(ele);
$ele.addClass('dropit');
//Attach event handlers to each list-item
$('li', $ele).dropIt('attach', settings);
//If list is displayed veritcally, add extra left padding to all sub-menus
if($(ele).hasClass('vertical'))
{
$('li', $ele).find('ul').addClass('nested sub-menu');
} else {
$('li ul', $ele).addClass('nested').find('ul').addClass('sub-menu');
}
});
//Call custom callback
settings.initCallback.call();
//Return jQuery collection of lists
return $(this);
},
attach: ...
_trigger: ...
_hide: ...
}
};
$.fn.dropIt = function(method){
//Variables and Options
var $this = $(this);
// Method calling logic
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.dropIt' );
}
};
})(jQuery, window, document);
After reading the jQuery Plugins/Authoring page, I structured by plugin basically like this:
(function ($) {
var defaults = {
// set default options
}
// internal functions
var methods = {
// plugin methods
}
$.fn.pluginName = function (method) {
}
})(jQuery);
And, like you have, $.extend the defaults within the init method, but I like to keep the defaults declared separately, personally, for clarity. It's been working well for me.
I always set the settings object as a global var to the plugin scope, like this:
(function($, window, document, undefined){
var settings; //NOTE THIS LINE
var methods = {
init: function(options)
{
settings = $.extend({ //AND THIS LINE
trigger: "hover",
animation: 'slide', /* none, slide, fade, grow */
easing: 'swing', /* swing, linear, bounce */
speedIn: 400,
speedOut: 400,
delayIn: 0,
delayOut: 0,
initCallback: function(){},
showCallback: function(){},
hideCallback: function(){}
}, options);
$(this).each(function(index, ele){
$ele = $(ele);
$ele.addClass('dropit');
//Attach event handlers to each list-item
$('li', $ele).dropIt('attach', settings);
//If list is displayed veritcally, add extra left padding to all sub-menus
if($(ele).hasClass('vertical'))
{
$('li', $ele).find('ul').addClass('nested sub-menu');
} else {
$('li ul', $ele).addClass('nested').find('ul').addClass('sub-menu');
}
});
//Call custom callback
settings.initCallback.call();
//Return jQuery collection of lists
return $(this);
},
attach: ...
_trigger: ...
_hide: ...
}
};
$.fn.dropIt = function(method){
//Variables and Options
var $this = $(this);
// Method calling logic
if ( methods[method] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.dropIt' );
}
};
})(jQuery, window, document);
EDIT:
You can also do $(this).data('youPlugInName', settings), then if you want to change it latter you can retrieve this from data('yourPlugInName'), and update whatever property you want.