Window resize undefined is not a function - javascript

I am trying to figure out why I get an error when I console.log a message on window resize in this jQuery plugin. Can I not reference the window from within the Plugin prototype?
;(function ( $, window, document, undefined ) {
"use strict";
var pluginName = "rigallery",
defaults = {
transition: "ease"
};
function Plugin ( element, options ) {
this.element = element;
this.settings = $.extend( {}, defaults, options );
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function() {
this.getHeight();
},
getHeight: function() {
$(window).resize(function() {
console.log('Yay!');
});
}
};
$.fn[ pluginName ] = function( options ) {
this.each(function() {
if ( !$.data( this, "plugin_" + pluginName ) ) {
$.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
}
});
return this;
};
})( jQuery, window, document );

Okay, I figured it out. I moved the window.resize call to the init method, and then added a var that = this and then called the getHeight using that.getHeight(). I would be interested to know if this is the correct way to do this.
;(function ( $, window, document, undefined ) {
"use strict";
var pluginName = "rigallery",
defaults = {
transition: "ease"
};
function Plugin ( element, options ) {
this.element = element;
this.settings = $.extend( {}, defaults, options );
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function() {
var that = this;
this.createGallery();
this.slidesTransition();
$(window).resize(function() {
console.log(that.getHeight());
});
},
getHeight: function() {
var height = $(this.element).find("li:first img").height();
return height;
}
};
$.fn[ pluginName ] = function( options ) {
this.each(function() {
if ( !$.data( this, "plugin_" + pluginName ) ) {
$.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
}
});
return this;
};
})( jQuery, window, document );

Related

jQuery Object Method Gets Called Multiple Times

I am trying to write a jQuery method which watches for changes of inputs inside a given form element:
(function($) {
$.fn.filter = function(options) {
console.log('Outside');
var self = this;
var settings = $.extend({}, options);
this.on('change', ':input', function(e) {
console.log('Inside');
$(self).serialize(); // Here is the problem
});
return this;
}
})(jQuery);
$('#filter-form').filter();
When I use $(self).serialize();, the function being called again. I expect that the 'Outside' part only runs once on initialization and not every time the input of the form changes.
I do not understand what is happening here. I'd appreciate if someone could explain to me why this is happening!
The issue is that you are redefining jQuery's filter method, which it internally uses in its serialize method. If you change the name, it will work. The definition of serialize is shown below:
jQuery.fn.extend( {
serialize: function() {
return jQuery.param( this.serializeArray() );
},
serializeArray: function() {
return this.map( function() {
// Can add propHook for "elements" to filter or add form elements
var elements = jQuery.prop( this, "elements" );
return elements ? jQuery.makeArray( elements ) : this;
} )
.filter( function() {
var type = this.type;
// Use .is( ":disabled" ) so that fieldset[disabled] works
return this.name && !jQuery( this ).is( ":disabled" ) &&
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
( this.checked || !rcheckableType.test( type ) );
} )
.map( function( _i, elem ) {
var val = jQuery( this ).val();
if ( val == null ) {
return null;
}
if ( Array.isArray( val ) ) {
return jQuery.map( val, function( val ) {
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
} );
}
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
} ).get();
}
} );
Working Example:
(function($) {
$.fn._filter = function(options) {
console.log('Outside');
var self = this;
var settings = $.extend({}, options);
this.on('change', ':input', function(e) {
console.log('Inside');
$(self).serialize();
});
return this;
}
})(jQuery);
$('#filter-form')._filter();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="filter-form">
<input type="text">
</form>

Slow rendering SVG animation on Chrome

Hellou guys. In this example i have an SVG animation which simulates turn the sheet of the book.
In mozilla its work fine, but in Chrome and Opera its work horrible.
Can you helpme optimize this animation for Chrome?
EXAMPLE
.js Used on EXAMPLE link:
snap.svg-min.js
classie.js
( function( window ) {
'use strict';
// class helper functions from bonzo https://github.com/ded/bonzo
function classReg( className ) {
return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}
// classList support for class management
// altho to be fair, the api sucks because it won't accept multiple classes at once
var hasClass, addClass, removeClass;
if ( 'classList' in document.documentElement ) {
hasClass = function( elem, c ) {
return elem.classList.contains( c );
};
addClass = function( elem, c ) {
elem.classList.add( c );
};
removeClass = function( elem, c ) {
elem.classList.remove( c );
};
}
else {
hasClass = function( elem, c ) {
return classReg( c ).test( elem.className );
};
addClass = function( elem, c ) {
if ( !hasClass( elem, c ) ) {
elem.className = elem.className + ' ' + c;
}
};
removeClass = function( elem, c ) {
elem.className = elem.className.replace( classReg( c ), ' ' );
};
}
function toggleClass( elem, c ) {
var fn = hasClass( elem, c ) ? removeClass : addClass;
fn( elem, c );
}
var classie = {
// full names
hasClass: hasClass,
addClass: addClass,
removeClass: removeClass,
toggleClass: toggleClass,
// short names
has: hasClass,
add: addClass,
remove: removeClass,
toggle: toggleClass
};
// transport
if ( typeof define === 'function' && define.amd ) {
// AMD
define( classie );
} else {
// browser global
window.classie = classie;
}
})( window );
svgLoader.js
;( function( window ) {
'use strict';
function extend( a, b ) {
for( var key in b ) {
if( b.hasOwnProperty( key ) ) {
a[key] = b[key];
}
}
return a;
}
function SVGLoader( el, options ) {
this.el = el;
this.options = extend( {}, this.options );
extend( this.options, options );
this._init();
}
SVGLoader.prototype.options = {
speedIn : 500,
easingIn : mina.linear
}
SVGLoader.prototype._init = function() {
var s = Snap( this.el.querySelector( 'svg' ) );
this.path = s.select( 'path' );
this.initialPath = this.path.attr('d');
var openingStepsStr = this.el.getAttribute( 'data-opening' );
this.openingSteps = openingStepsStr ? openingStepsStr.split(';') : '';
this.openingStepsTotal = openingStepsStr ? this.openingSteps.length : 0;
if( this.openingStepsTotal === 0 ) return;
// if data-closing is not defined then the path will animate to its original shape
var closingStepsStr = this.el.getAttribute( 'data-closing' ) ? this.el.getAttribute( 'data-closing' ) : this.initialPath;
this.closingSteps = closingStepsStr ? closingStepsStr.split(';') : '';
this.closingStepsTotal = closingStepsStr ? this.closingSteps.length : 0;
this.isAnimating = false;
if( !this.options.speedOut ) {
this.options.speedOut = this.options.speedIn;
}
if( !this.options.easingOut ) {
this.options.easingOut = this.options.easingIn;
}
}
SVGLoader.prototype.show = function() {
if( this.isAnimating ) return false;
this.isAnimating = true;
// animate svg
var self = this,
onEndAnimation = function() {
classie.addClass( self.el, 'pageload-loading' );
};
this._animateSVG( 'in', onEndAnimation );
classie.add( this.el, 'show' );
}
SVGLoader.prototype.hide = function() {
var self = this;
classie.removeClass( this.el, 'pageload-loading' );
this._animateSVG( 'out', function() {
// reset path
self.path.attr( 'd', self.initialPath );
classie.removeClass( self.el, 'show' );
self.isAnimating = false;
} );
}
SVGLoader.prototype._animateSVG = function( dir, callback ) {
var self = this,
pos = 0,
steps = dir === 'out' ? this.closingSteps : this.openingSteps,
stepsTotal = dir === 'out' ? this.closingStepsTotal : this.openingStepsTotal,
speed = dir === 'out' ? self.options.speedOut : self.options.speedIn,
easing = dir === 'out' ? self.options.easingOut : self.options.easingIn,
nextStep = function( pos ) {
if( pos > stepsTotal - 1 ) {
if( callback && typeof callback == 'function' ) {
callback();
}
return;
}
self.path.animate( { 'path' : steps[pos] }, speed, easing, function() { nextStep(pos); } );
pos++;
};
nextStep(pos);
}
// add to global namespace
window.SVGLoader = SVGLoader;
})( window );
and this scrypt on html file:
(function() {
var pageWrap = document.getElementById( 'pagewrap' ),
pages = [].slice.call( pageWrap.querySelectorAll( 'div.container' ) ),
currentPage = 0,
triggerLoading = [].slice.call( pageWrap.querySelectorAll( 'a.pageload-link' ) ),
loader = new SVGLoader( document.getElementById( 'loader' ), { speedIn : 400, easingIn : mina.easeinout } );
function init() {
triggerLoading.forEach( function( trigger ) {
trigger.addEventListener( 'click', function( ev ) {
ev.preventDefault();
loader.show();
// after some time hide loader
setTimeout( function() {
loader.hide();
classie.removeClass( pages[ currentPage ], 'show' );
// update..
currentPage = currentPage ? 0 : 1;
classie.addClass( pages[ currentPage ], 'show' );
}, 2000 );
} );
} );
}
init();
})();

Responsive Multi-Level Menu - How to close menu when link is clicked?

I have a very simple menu, no sub menus and was curious how I would get the menu to close when I click on one of the links?
Plugin Home Page ->
Here is the code directly out of the .js file that comes in the zip when you download this menu. I really need to know what code to add and where to add it so that when I click a link it closes the menu.
;( function( $, window, undefined ) {
'use strict';
// global
var Modernizr = window.Modernizr, $body = $( 'body' );
$.DLMenu = function( options, element ) {
this.$el = $( element );
this._init( options );
};
// the options
$.DLMenu.defaults = {
// classes for the animation effects
animationClasses : { classin : 'dl-animate-in-1', classout : 'dl-animate-out-1' },
// callback: click a link that has a sub menu
// el is the link element (li); name is the level name
onLevelClick : function( el, name ) { return false; },
// callback: click a link that does not have a sub menu
// el is the link element (li); ev is the event obj
onLinkClick : function( el, ev ) { return false; }
};
$.DLMenu.prototype = {
_init : function( options ) {
// options
this.options = $.extend( true, {}, $.DLMenu.defaults, options );
// cache some elements and initialize some variables
this._config();
var animEndEventNames = {
'WebkitAnimation' : 'webkitAnimationEnd',
'OAnimation' : 'oAnimationEnd',
'msAnimation' : 'MSAnimationEnd',
'animation' : 'animationend'
},
transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
};
// animation end event name
this.animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ] + '.dlmenu';
// transition end event name
this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ] + '.dlmenu',
// support for css animations and css transitions
this.supportAnimations = Modernizr.cssanimations,
this.supportTransitions = Modernizr.csstransitions;
this._initEvents();
},
_config : function() {
this.open = false;
this.$trigger = this.$el.children( '.dl-trigger' );
this.$menu = this.$el.children( 'ul.dl-menu' );
this.$menuitems = this.$menu.find( 'li:not(.dl-back)' );
this.$el.find( 'ul.dl-submenu' ).prepend( '<li class="dl-back">BACK</li>' );
this.$back = this.$menu.find( 'li.dl-back' );
},
_initEvents : function() {
var self = this;
this.$trigger.on( 'click.dlmenu', function() {
if( self.open ) {
self._closeMenu();
}
else {
self._openMenu();
}
return false;
} );
this.$menuitems.on( 'click.dlmenu', function( event ) {
event.stopPropagation();
var $item = $(this),
$submenu = $item.children( 'ul.dl-submenu' );
if( $submenu.length > 0 ) {
var $flyin = $submenu.clone().css( 'opacity', 0 ).insertAfter( self.$menu ),
onAnimationEndFn = function() {
self.$menu.off( self.animEndEventName ).removeClass( self.options.animationClasses.classout ).addClass( 'dl-subview' );
$item.addClass( 'dl-subviewopen' ).parents( '.dl-subviewopen:first' ).removeClass( 'dl-subviewopen' ).addClass( 'dl-subview' );
$flyin.remove();
};
setTimeout( function() {
$flyin.addClass( self.options.animationClasses.classin );
self.$menu.addClass( self.options.animationClasses.classout );
if( self.supportAnimations ) {
self.$menu.on( self.animEndEventName, onAnimationEndFn );
}
else {
onAnimationEndFn.call();
}
self.options.onLevelClick( $item, $item.children( 'a:first' ).text() );
} );
return false;
}
var link = $item.find('a').attr('href');
var hash = link.substring(link.indexOf('#')+1);
if( hash != "" ){
var elem = jQuery('div[data-anchor="'+hash+'"]');
autoScroll(elem);
self._closeMenu();
}else{
self.options.onLinkClick( $item, event );
}
} );
this.$back.on( 'click.dlmenu', function( event ) {
var $this = $( this ),
$submenu = $this.parents( 'ul.dl-submenu:first' ),
$item = $submenu.parent(),
$flyin = $submenu.clone().insertAfter( self.$menu );
var onAnimationEndFn = function() {
self.$menu.off( self.animEndEventName ).removeClass( self.options.animationClasses.classin );
$flyin.remove();
};
setTimeout( function() {
$flyin.addClass( self.options.animationClasses.classout );
self.$menu.addClass( self.options.animationClasses.classin );
if( self.supportAnimations ) {
self.$menu.on( self.animEndEventName, onAnimationEndFn );
}
else {
onAnimationEndFn.call();
}
$item.removeClass( 'dl-subviewopen' );
var $subview = $this.parents( '.dl-subview:first' );
if( $subview.is( 'li' ) ) {
$subview.addClass( 'dl-subviewopen' );
}
$subview.removeClass( 'dl-subview' );
} );
return false;
} );
},
closeMenu : function() {
if( this.open ) {
this._closeMenu();
}
},
_closeMenu : function() {
var self = this,
onTransitionEndFn = function() {
self.$menu.off( self.transEndEventName );
self._resetMenu();
};
this.$menu.removeClass( 'dl-menuopen' );
this.$menu.addClass( 'dl-menu-toggle' );
this.$trigger.removeClass( 'dl-active' );
if( this.supportTransitions ) {
this.$menu.on( this.transEndEventName, onTransitionEndFn );
}
else {
onTransitionEndFn.call();
}
this.open = false;
},
openMenu : function() {
if( !this.open ) {
this._openMenu();
}
},
_openMenu : function() {
var self = this;
// clicking somewhere else makes the menu close
$body.off( 'click' ).on( 'click.dlmenu', function() {
self._closeMenu() ;
} );
this.$menu.addClass( 'dl-menuopen dl-menu-toggle' ).on( this.transEndEventName, function() {
$( this ).removeClass( 'dl-menu-toggle' );
} );
this.$trigger.addClass( 'dl-active' );
this.open = true;
},
// resets the menu to its original state (first level of options)
_resetMenu : function() {
this.$menu.removeClass( 'dl-subview' );
this.$menuitems.removeClass( 'dl-subview dl-subviewopen' );
}
};
var logError = function( message ) {
if ( window.console ) {
window.console.error( message );
}
};
$.fn.dlmenu = function( options ) {
if ( typeof options === 'string' ) {
var args = Array.prototype.slice.call( arguments, 1 );
this.each(function() {
var instance = $.data( this, 'dlmenu' );
if ( !instance ) {
logError( "cannot call methods on dlmenu prior to initialization; " +
"attempted to call method '" + options + "'" );
return;
}
if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
logError( "no such method '" + options + "' for dlmenu instance" );
return;
}
instance[ options ].apply( instance, args );
});
}
else {
this.each(function() {
var instance = $.data( this, 'dlmenu' );
if ( instance ) {
instance._init();
}
else {
instance = $.data( this, 'dlmenu', new $.DLMenu( options, this ) );
}
});
}
return this;
};
} )( jQuery, window );
After looking at their demo, it seems you can call method plugins. Replace dl-menu with the id of your menu.
$('#dl-menu a').click(function(e) {
$('#dl-menu').dlmenu('closeMenu');
});

How to create function for custom jQuery plugin

I am creating one simple custom jQuery plugin using jquery.boilerplate.js. Now I want to create one function that will call like,
var div1 = $("#div1").changeBackgroundColor({
color: $('#colorCode').val().trim()
});
div1.getColor();
How to defined that getColor() method in jquery plugin.
Custom Plugin:
;(function($, window, document, undefined) {
var pluginName = "changeBackgroundColor", defaults = {
color : "black"
};
function Plugin(element, options) {
this.element = element;
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
$.extend(Plugin.prototype, {
init : function() {
console.log("Hello");
}
});
$.fn[pluginName] = function(options) {
this.each(function() {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin(this,
options));
}
console.log(options);
if(options===undefined){
$(this).css("background-color", defaults.color);
} else{
$(this).css("background-color", options.color);
}
});
return this;
};
})(jQuery, window, document);
Thank You....:)
You kinda missed the whole point of plugins and OOP.
$.fn[pluginName] - should play infrastructure role and delegate actual work to the Plugin instance.
Plugin instance should perform actual work with element.
If you want to call methods on Plugin instances you can make $.fn[pluginName] to handle special cases when options is a string. $(selector).changeBackgroundColor('methodToBeCalled' /*rest arguments*/)
Demo.
;(function($, window, document, undefined) {
var pluginName = "changeBackgroundColor",
defaults = {
color : "black"
},
//methods to be called via $().changeBackgroundColor(name)
publicMethods = {
getColor: function() {
return this.settings.color;
},
setColor: function(color) {
this.settings.color = color;
this.element.css('background-color', color);
}
},
privateMethods = { //internal methods
init : function() {
console.log('init');
this.setColor(this.getColor());
}
};
function Plugin(element, options) {
this.element = $(element);
this.settings = $.extend({}, defaults, options);
this.init();
}
//copy private and public methods
$.extend(Plugin.prototype, privateMethods, publicMethods);
$.fn[pluginName] = function(options) {
var out = [],
args = [].slice.call(arguments, 1);
this.each(function() {
var plugin = $.data(this, pluginName),
method;
if (!plugin) { //create new plugin
plugin = new Plugin(this, options)
return $.data(this, pluginName, plugin);
}
//handle method calls
if(typeof options === 'string' && publicMethods[options]) {
out.push(plugin[options].apply(plugin, args));
}
});
return out.length ? (out.length === 1 ? out[0] : out) : this;
};
})(jQuery, window, document);
Usage
$('#a').changeBackgroundColor();
$('#b').changeBackgroundColor({color: 'navy'});
$('#c').changeBackgroundColor({color: 'green'});
console.log($('#b').changeBackgroundColor('getColor'));
console.log($('#b, #c').changeBackgroundColor('getColor'));
$('#a').changeBackgroundColor('setColor', 'red');
console.log($('#a').changeBackgroundColor('getColor'));
Define your method like this
$.fn.getColor = function() {
alert('getColor called');
}
Basic Custom Plugin
Create your Plugin like this:
$.fn.highlight = function(){
this.css("background","yellow").css("color","black");
return this;
}
$(".highlight").highlight().fadeIn();
In the above example i had created a simple jQuery plugin which will highlight a element.I think you should check this http://mycodingtricks.com/jquery/how-to-create-your-own-jquery-plugin/

How to turn variables in to options? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How would you change this kind of code?
How would I pass these variables in to options through jQuery, so that when the user uses the plugin, they must initialize the plugin from the HTML like so:
<script>
$('.elem').pluginName({
theme: 'blue',
animSpeed: 200
});
</script>
Here's my jQuery code. Pretty messy, but have a look. How could I change the variables to options?
$(function () {
var theme = "sunburst";
var btnColor = "yellow";
var icon = "power";
var message = "Hello World";
var animSpeed = 300;
var animType = 'fadeIn';
var btnText = "Purchase";
var btnLink = 'http://www.google.com';
var closeStyle = "dark";
var content =
'<div id="mn_close" class="' + closeStyle + '"></div>' +
'<div id="mn_border"></div>' +
'<i class="icon-' + icon + '"></i>' +
'<span class="mn_message">' + message + '</span>';
// '' + btnText + '';
$("#mn_close").live("click", function () {
$('.mn_bar').animate({
height: '0'
}, animSpeed, function () {});
});
var mn_bar = $(".mn_bar");
mn_bar.append(content);
$(function () {
mn_bar.addClass("animated");
mn_bar.addClass(animType);
mn_bar.addClass(theme)
});
});
Or here is the jsfiddle. http://jsfiddle.net/LwGRV/6/
I've being trying to implement the code in to this standard type of jQuery code too, but failing to merge:
;(function ( $, window, document, undefined ) {
var pluginName = "defaultPluginName",
defaults = {
propertyName: "value"
};
function Plugin( element, options ) {
this.element = element;
this.options = $.extend( {}, defaults, options );
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function() {
},
yourOtherFunction: function(el, options) {
// some logic
}
};
$.fn[pluginName] = function ( options ) {
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin( this, options ));
}
});
};
})( jQuery, window, document );
Many thanks in advance if anyone can shed some light on to this.
You should have a look at this: http://api.jquery.com/jQuery.extend/
Your variables should be stored within an object.

Categories