I have code
$(function() {
// run the currently selected effect
function runEffect() {
// get effect type from
var selectedEffect = $( "#effectTypes" ).val();
// most effect types need no options passed by default
var options = {};
// some effects have required parameters
if ( selectedEffect === "scale" ) {
options = { percent: 100 };
} else if ( selectedEffect === "size" ) {
options = { to: { width: 280, height: 185 } };
}
// run the effect
$( "#effect" ).show( selectedEffect, options, 500, callback );
};
//callback function to bring a hidden box back
function callback() {
setTimeout(function() {
$( "#effect:visible" ).removeAttr( "style" ).fadeOut();
}, 1000 );
};
// set effect from select menu value
$( "#button" ).click(function() {
runEffect();
});
like dis i want to change dis on click function into on load function am a beginner so please help me
If I am understanding you correctly you want to run the runEffect function on page load?
You can do this by calling the function from within the jQuery ready event.
// This is shorthand for $(document).ready(function() { ... })
$(function() {
// Declare the runEffect function here
runEffect();
});
Related
I am writing a JQuery plugin for a project I'm working on which turns from tabbed content on desktop devices to an accordion on mobile devices. I've used JQuery Boilerplate (https://github.com/jquery-boilerplate/jquery-boilerplate/blob/master/dist/jquery.boilerplate.js) as an initial pattern for my plugin.
The plugin is called on any element with the class ".tabs2accordion" as shown here:
$(".tabs2accordion").tabs2Accordion({state:"desktop"});
The plugin works as expected if there is only one element with ".tabs2accordion" class on a page but starts to malfunction as soon as another element with the same class is added to the page. I've created a codepen of the basic code to demo the issue. To show the issue, on a window size of >768px try clicking any of the titles and observe how the content below changes as each title is clicked. Next uncomment the block of HTML and try clicking on the titles again.
http://codepen.io/decodedcreative/pen/MyjpRj
I have tried looping through each element with the class "tabs2accordion" like this:
$(".tabs2accordion").each(function(){
$(this).tabs2Accordion({state:"desktop"});
});
But this didn't fix the issue either.
Any ideas?
I have not used jQuery Boilerplate, but I believe the problem here is with your variable called plugin.
Nowhere in your code do you declare a variable called plugin. When I stop the debugger in Plugin.prototype.showTabContent, I can evaluate window.plugin and it returns the global value for plugin.
In the constructor for Plugin, the first line reads plugin= this;. Since plugin is not defined, it is declaring the variable at global scope on the window object.
The fix is to pass a reference to the plugin object when setting up the $().on() hook. The data passed is available in the event handlers via the event parameter that is passed in the data property.
Here is the solution (at http://codepen.io/shhQuiet/pen/JXEjMV)
(function($, window, document, undefined) {
var pluginName = "tabs2Accordion",
defaults = {
menuSelector: ".tabs2accordion-menu",
tabContentSelector: ".tabs2accordion-content"
};
function Plugin(element, options) {
this.element = element;
this.$element = $(this.element);
this.options = $.extend({}, defaults, options);
this.$menu = $(this.element).find(this.options.menuSelector),
this.$tabs = $(this.element).find(this.options.tabContentSelector),
this.$accordionTriggers = $(this.element).find(this.$tabs).find("h3");
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function() {
//Set all the tab states to inactive
this.$tabs.attr("data-active", false);
//Set the first tab to active
this.$tabs.first().attr("data-active", true);
//If you click on a tab, show the corresponding content
this.$menu.on("click", "li", this, this.showTabContent);
//Set the dimensions (height) of the plugin
this.resizeTabs2Accordion({
data: this
});
//If the browser resizes, adjust the dimensions (height) of the plugin
$(window).on("resize", this, this.resizeTabs2Accordion);
//Add a loaded class to the plugin which will fade in the plugin's content
this.$element.addClass("loaded");
console.log(this.$element);
},
resizeTabs2Accordion: function(event) {
var contentHeight;
var plugin = event.data;
if (!plugin.$element.is("[data-nested-menu]")) {
contentHeight = plugin.$tabs.filter("[data-active='true']").outerHeight() + plugin.$menu.outerHeight();
} else {
contentHeight = plugin.$tabs.filter("[data-active='true']").outerHeight();
}
plugin.$element.outerHeight(contentHeight);
},
showTabContent: function(event) {
var $target;
var plugin = event.data;
plugin.$menu.children().find("a").filter("[data-active='true']").attr("data-active", false);
plugin.$tabs.filter("[data-active='true']").attr("data-active", false);
$target = $($(this).children("a").attr("href"));
$(this).children("a").attr("data-active", true);
$target.attr("data-active", true);
plugin.resizeTabs2Accordion({data: plugin});
return false;
},
showAccordionContent: function(event) {
var plugin = event.data;
$("[data-active-mobile]").not($(this).parent()).attr("data-active-mobile", false);
if ($(this).parent().attr("data-active-mobile") === "false") {
$(this).parent().attr("data-active-mobile", true);
} else {
$(this).parent().attr("data-active-mobile", false);
}
}
};
$.fn[pluginName] = function(options) {
return this.each(function() {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new Plugin(this, options));
}
});
};
})(jQuery, window, document);
$(window).on("load", function() {
$(".tabs2accordion").tabs2Accordion({
state: "desktop"
});
});
I rewrote your code following jQuery's Plugin creation standard.
http://codepen.io/justinledouxmusique/pen/GZrMgB
Basically, I did two things:
Moved away from using data attributes for styling (switched to using an .active class instead)
Moved away from using this everywhere, as it bring a whole wave of binding issues...
$.fn.tabs2Accordion loops through all the selectors, and applies $.tabs2Accordion. It also returns the selector for chaining (it's a standard in jQuery).
Then, all the internal methods are function expressions which are in the same scope as all your old this "variables". This simplifies the code greatly as you can refer to those variables without passing them in as a parameter or without having to .bind( this ) somehow.
Finally, the old init() function is gone. Instead, I put the code at the end of the $.tabs2Accordion function.
Hope this helps!
(function ( window, $ ) {
$.tabs2Accordion = function ( node, options ) {
var options = $.extend({}, {
menuSelector: '.tabs2accordion-menu',
tabContentSelector: '.tabs2accordion-content'
}, options )
var $element = $( node ),
$menu = $element.find( options.menuSelector ),
$tabs = $element.find( options.tabContentSelector ),
$accordionTriggers = $tabs.find( 'h3' )
var resizeTabs2Accordion = function () {
$element.outerHeight( !$element.is( '[data-nested-menu]' )
? $element.find( 'div.active' ).outerHeight() + $menu.outerHeight()
: $element.find( 'div.active' ).outerHeight() )
}
var showTabContent = function () {
var $this = $( this ) // This will be the clicked element
$menu
.find( '.active' )
.removeClass( 'active' )
$element
.find( '.active' )
.removeClass( 'active' )
$( $this.find( 'a' ).attr( 'href' ) )
.addClass( 'active' )
$this
.find( 'a' )
.addClass( 'active' )
resizeTabs2Accordion()
return false
}
var showAccordionContent = function () {
var $this = $( this ),
$parent = $this.parent(),
mobileIsActive = $parent.data( 'active-mobile' )
$( '[data-active-mobile]' )
.not( $parent )
.data( 'active-mobile', false )
$parent
.data( 'active-mobile', mobileIsActive ? false : true )
}
// The equivalent of init()
$tabs
.removeClass( 'active' )
.first()
.addClass( 'active' )
$element.addClass( 'loaded' )
$menu.on( 'click', 'li', showTabContent )
$( window ).on( 'resize', resizeTabs2Accordion )
resizeTabs2Accordion()
console.log( $element )
}
$.fn.tabs2Accordion = function ( options ) {
this.each( function ( index, node ) {
$.tabs2Accordion( node, options )
})
return this
}
})( window, jQuery )
$( window ).on( 'load', function () {
$( '.tabs2accordion' ).tabs2Accordion({
state: 'desktop'
})
})
I have the following js code:
This code is used on a FAQ toggle page.
It works basically as every toogle code, but I would like to add the auto-close function when clicking to an other question.
Hide the prev question content, then show the next one.
Any ideas?
if ( 'function' !== typeof(window[ 'vc_toggleBehaviour' ] ) ) {
window.vc_toggleBehaviour = function ( $el ) {
function event( e ) {
e && e.preventDefault && e.preventDefault();
var title = jQuery( this );
var element = title.closest( '.vc_toggle' );
var content = element.find( '.vc_toggle_content' );
if ( element.hasClass( 'vc_toggle_active' ) ) {
content.slideUp( {
duration: 300,
complete: function () {
element.removeClass( 'vc_toggle_active' );
}
} );
} else {
content.slideDown( {
duration: 300,
complete: function () {
element.addClass( 'vc_toggle_active' );
}
} );
}
}
if ( $el ) {
if ( $el.hasClass( 'vc_toggle_title' ) ) {
$el.unbind( 'click' ).click( event );
} else {
$el.find( ".vc_toggle_title" ).unbind( 'click' ).click( event );
}
} else {
jQuery( ".vc_toggle_title" ).unbind( 'click' ).on( 'click', event );
}
}
}
Whenever any of the questions are clicked, if you were to hide all active questions you won't have to worry about which one -if any- are currently active.
(on question click):
$('.vc_toggle_active').each(function(){
$(this)slideUp( {
duration: 300,
complete: function () {
$(this).removeClass( 'vc_toggle_active' );
}
});
});
After sliding up any currently active question, go ahead and show the clicked one.
NB. Code not tested, since you have no fiddle and no html. Hope you get the concept though.
I've used simple jQuery UI tooltip on form-fields of my webpage(viz responsive), its working perfectly on desktop on every browser, but on iPad its get distorted when I tap on form-fields as keypad swipe-up. Also header section of my webpage gets fixed on scroll.
I've used below code for the custom jQuery Tooltip.
$(function () {
$('.form-control').tooltip({
disabled: true,
position: {
my: "left top",
at: "left top-50",
using: function( position, feedback ) {
$( this ).css( position );
$( "<div>" )
.addClass( "arrow" )
.addClass( feedback.vertical )
.addClass( feedback.horizontal )
.appendTo( this );
}
}
}).on("focusin", function () {
$(this)
.tooltip("enable")
.tooltip("open");
}).on("focusout", function () {
$(this)
.tooltip("close")
.tooltip("disable");
});
});
I've written this code to re-initialize the tooltip for the focused field by calling its focusin trigger manually when document size changed. It is working as expected on Desktop browsers but on iPad tooltip is being re-initialized at same place again viz incorrect.
var toolTipEl;
$('#inputSuccess, #inputWarning').tooltip({
open: function (event, ui) {
toolTipEl = event.target;
}
});
function checkDocumentHeight(callback){
var lastHeight = document.body.clientHeight, newHeight, timer;
(function run(){
newHeight = document.body.clientHeight;
if( lastHeight != newHeight )
callback();
lastHeight = newHeight;
timer = setTimeout(run, 100);
})();
}
function doSomthing(){
console.log('document resized');
setTimeout(function() {
if ($(toolTipEl).is(':focus')) {
$(toolTipEl).trigger('focusout').trigger('focusin');
}
}, 500);
}
checkDocumentHeight(doSomthing);
Please help me to find out the solution for this.
You will need to reinitialize active Tooltip after completion of any event which cause change in the content (actually height) of your document affecting your Tooltip position.
First keep reference of the element for which the tooltip is active by listening to its events by adding following codes in your tooltip initialization (Keep your existing code as it is. Just add these additional statements).
var toolTipEl = undefined;
$(function () {
$('.form-control').tooltip({
open: function (event, ui) {
toolTipEl = event.target;
}
}).on("focusin", function () {
toolTipEl = undefined;
}).on("focusout", function () {
toolTipEl = undefined;
}).on("mouseleave", function () {
toolTipEl = undefined;
});
});
Please note, as you are displaying tooltip on focusin event as well. So, you will also need to release the variable if you do not want tooltip pop-upped if focus has changed/left.
And then create a function for resetting tooltip like below.
function resetTooltip() {
if (toolTipEl) {
$(toolTipEl).trigger('focusout').trigger('focusin');
};
}
Call this function in any events which is causing change in the document height. For example if content is coming from an ajax request. You can call restTooltip function by listing to the gloab ajax events. See example below.
$( document ).ajaxComplete(function() {
resetTooltip();
});
I hope it will help you. Ask me if you need any further clarification.
I don't understand the use of stop() element in jquery.
In this example, i try to open a div when the user launch the myfunction function (for example by clicking on a trigger)
But if you click several time, #mydiv desapears anyway, without waiting 3 seconds, because it close 3 second after your first click.
function myfunction(hello)
{
$( "#mycontener" ).html( hello );
$( "#mydiv" ).stop( true, true ).slideDown( 250, function() {
setTimeout(function() {
$("#mydiv").slideUp( 250 );
}, 3000);
});
};
Is it clear enough ?
Thanks
You will need to clear the timeout to prevent it from happening on future calls. Something like this:
(function () {
var handle;
function myfunction(hello) {
clearTimeout(handle);
$("#mycontener").html(hello);
$("#mydiv").stop(true, true).slideDown(250, function () {
handle = setTimeout(function () {
$("#mydiv").slideUp(250);
}, 3000);
});
}
window.myfunction = myfunction;
})();
Here I have a widget and I want to call a function once #slider.slider();. what is the code?
$( "#slider" ).slider({
//initial function here.
alert("A");
value: 50,
slide: function(event, ui) {
displaySlideValue();
}
});
Why not just do
$('#slider').slider({ ... }).each(function() { /* your code here */ });
Alternatively you could wrap the .slider() call in your own mini-extension:
$.fn.sliderWithInit = function(params, init) {
return this.slider(params).each(init);
});
then you could say
$('#slider').sliderWithInit({ /* params */ }, function() { /* init code */ });
Obviously "slider" could be made generic:
$.wrapWithInit = function(widgetName) {
$.fn[widgetName + 'WithInit'] = function(params, init) {
return this[widgetName](params).each(init);
});
});
Then you can do it for "dialog" for example:
$.wrapWithInit('dialog');
$('#dialog').dialogWithInit({ /* dialog params */ }, function() { /* init code */ });
As #mikerobi points out, it's not 100% clear when you want your initialization function to be called. Most widgets have an "onFoo" type callback that's called when the widget is activated (whatever that means for the given widget). If you just want to initialize on the first call, you could just make the callback be a closure that keeps track of whether it's ever done the initialization work. If it detects it's already done it, it would just return.