Click Function on jQuery plugin only allows for single click - javascript

I've created this simple plugin to add multiple animations on click but the problem is that once the object is clicked it can not repeat the animation by clicking again, i can't figure out why the added class is not removing itself after the click function is complete to allow it to be clicked again and repeat.. any suggestions?
(function($) {
$.fn.vivify = function(options) {
var defaults = {
animation: 'bounce',
};
var options = $.extend(defaults, options);
return this.each(function() {
var o = options;
var obj = $(this);
var animation = o.animation;
obj.bind("click", function() {
obj.addClass(o.animation);
obj.addClass('vivify');
}, function() {
obj.removeClass(o.animation);
});
})
}
})(jQuery);​

Here's a working example (I guess, because I don't know exactly what's the intended effect of your plugin):
http://jsfiddle.net/gabrieleromanato/Fmr9g/

obj.bind("click", function() {
obj.addClass(o.animation);
obj.addClass('vivify');
},
// this callback is not valid
function() {
obj.removeClass(o.animation);
});
because .bind() accept parameters like following:
.bind(eventName, [eventData], [callback])
Read about .bind()
To remove class you can do:
obj.bind("click", function() {
obj.addClass(o.animation);
obj.addClass('vivify');
// you can removeClass here
obj.removeClass(o.animation);
// but you need some delay
setTimeou(function() {
obj.removeClass(o.animation);
}, 5000);
});
To increase the timeout you can do following:
return this.each(function(index, val) {
var o = options;
var obj = $(this);
var animation = o.animation;
obj.bind("click", function() {
obj.addClass(o.animation);
obj.addClass('vivify');
}, index * 2000);
});

Related

Preventing Jquery .click toggle function from running over and over with excess clicking

Im building a .clicktoggle function in jQuery and for the life of me i can't get a .stop like effect on it, basically i don't want it to play over and over if mash clicked.
I want it to be applied the the function so its self contained, that's where im stuck.
JS fiddle link
(function($) {
$.fn.clickToggle = function(func1, func2) {
var funcs = [func1, func2];
this.data('toggleclicked', 0);
this.click(function() {
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 2;
});
return this;
};
}(jQuery));
$('div').clickToggle(function() {
$('.testsubject').fadeOut(500);
}, function() {
$('.testsubject').fadeIn(500);
});
<div class="clickme">click me fast</div>
<div class="testsubject">how do i stop it playing over and over if you click alot</div>
Toggle .click seems like something alot of people would use so i thought it might be useful to ask it here
By adding a check to a boolean variable fadeInProgress, you can choose to only queue the animation if fadeInProgress is false. It then sets the value to true and executes the animation. When the animation is completed, set the value to false.
var fadeInProgress = false;
$('div').clickToggle(function() {
if (!fadeInProgress) {
fadeInProgress = true;
$('.testsubject').fadeOut(700, function(){fadeInProgress = false;});
}
}, function() {
if (!fadeInProgress) {
fadeInProgress = true;
$('.testsubject').fadeIn(700, function(){fadeInProgress = false;});
}
});
var clicked = false;
var doing = false;
$(".clickme").click(function(e) {
if (doing) {
return;
} else {
doing = true;
}
doing = true;
clicked = !clicked;
if (clicked) {
$('.testsubject').fadeOut(700, function() {
doing = false
});
} else {
$('.testsubject').fadeIn(700, function() {
doing = false;
});
}
});
This example is a simple toggle which only allows you to click when it is not doing anything. I explained on IRC, but as an example here, the function only runs when doing is set to false, which only happens when it's set after fadeIn() or fadeOut's callback function thingymajigger.

Magento Jquery Bootstrap and Prototype conflict? nav-tabs dont work

I use Magento 1.9.2.4 and the following Theme
https://github.com/webcomm/magento-boilerplate
The description of it is "HTML5 Twitter Bootstrap 3.1 Magento Boilerplate Template"
It works fine with everything else of "Bootstrap responsive".
My problem is, that all of the following on this Site did not work on my
Installation:
http://www.w3schools.com/bootstrap/bootstrap_tabs_pills.asp
And "did not work" means you can click on next tab but the border and highlighting and so on is still on the first tab.
Same thing on "nav-pills" of Bootstrap.
In this Boilerplate there is a Workaround for Bootstrap dropdown:
jQuery.noConflict();
;(function ($) {
'use strict';
function Site(settings) {
this.windowLoaded = false;
}
Site.prototype = {
constructor: Site,
start: function () {
var me = this;
$(window).load(function () {
me.windowLoaded = true;
});
this.attach();
},
attach: function () {
this.attachBootstrapPrototypeCompatibility();
this.attachMedia();
},
attachBootstrapPrototypeCompatibility: function () {
/*// Bootstrap and Prototype don't play nice, in the sense that
// prototype is a really wacky horrible library. It'll
// hard-code CSS to hide an element when a hide() event
// is fired. See http://stackoverflow.com/q/19139063
// To overcome this with dropdowns that are both
// toggle style and hover style, we'll add a CSS
// class which has "display: block !important"
$('*').on('show.bs.dropdown show.bs.collapse active nav-tabs.active', function (e) {
$(e.target).addClass('bs-prototype-override');
});
$('*').on('hidden.bs.collapse nav-tabs', function (e) {
$(e.target).removeClass('bs-prototype-override');
});*/
var isBootstrapEvent = false;
if (window.jQuery) {
var all = jQuery('*');
jQuery.each(['hide.bs.dropdown',
'hide.bs.collapse',
'hide.bs.modal',
'hide.bs.tooltip',
'hide.bs.popover',
'hide.bs.tab'], function (index, eventName) {
all.on(eventName, function (event) {
isBootstrapEvent = true;
});
});
}
var originalHide = Element.hide;
Element.addMethods({
hide: function (element) {
if (isBootstrapEvent) {
isBootstrapEvent = false;
return element;
}
return originalHide(element);
}
});
},
attachMedia: function () {
var $links = $('[data-toggle="media"]');
if (!$links.length) return;
// When somebody clicks on a link, slide the
// carousel to the slide which matches the
// image index and show the modal
$links.on('click', function (e) {
e.preventDefault();
var $link = $(this),
$modal = $($link.attr('href')),
$carousel = $modal.find('.carousel'),
index = parseInt($link.data('index'));
$carousel.carousel(index);
$modal.modal('show');
return false;
});
}
};
jQuery(document).ready(function ($) {
var site = new Site();
site.start();
});
})(jQuery);
I already asked on github with no response question on github
So the Dropdown of Bootstrap is working.
My Question am i doing anything wrong or am i missing something?
Why does the nav-tabs not work in here?
Adding the "'bower_components/bootstrap/js/tab.js'," tab.js to the gulpfile.js AND
adding the tab class to the script.js solved my Problem with Bootstrap Nav Pills and Tabs.
$('*').on('show.bs.dropdown show.bs. hide.bs.tab hidden.bs.tab', function(e) {
$(e.target).addClass('bs-prototype-override');
});
$('*').on('hidden.bs.collapse', function(e) {
$(e.target).removeClass('bs-prototype-override');
});
At the end the code looks just like this:
jQuery.noConflict();
;(function($) {
'use strict';
function Site(settings) {
this.windowLoaded = false;
}
Site.prototype = {
constructor: Site,
start: function() {
var me = this;
$(window).load(function() {
me.windowLoaded = true;
});
this.attach();
},
attach: function() {
this.attachBootstrapPrototypeCompatibility();
this.attachMedia();
},
attachBootstrapPrototypeCompatibility: function() {
// Bootstrap and Prototype don't play nice, in the sense that
// prototype is a really wacky horrible library. It'll
// hard-code CSS to hide an element when a hide() event
// is fired. See http://stackoverflow.com/q/19139063
// To overcome this with dropdowns that are both
// toggle style and hover style, we'll add a CSS
// class which has "display: block !important"
$('*').on('show.bs.dropdown show.bs. hide.bs.tab hidden.bs.tab', function(e) {
$(e.target).addClass('bs-prototype-override');
});
$('*').on('hidden.bs.collapse', function(e) {
$(e.target).removeClass('bs-prototype-override');
});
},
attachMedia: function() {
var $links = $('[data-toggle="media"]');
if ( ! $links.length) return;
// When somebody clicks on a link, slide the
// carousel to the slide which matches the
// image index and show the modal
$links.on('click', function(e) {
e.preventDefault();
var $link = $(this),
$modal = $($link.attr('href')),
$carousel = $modal.find('.carousel'),
index = parseInt($link.data('index'));
$carousel.carousel(index);
$modal.modal('show');
return false;
});
}
};
jQuery(document).ready(function($) {
var site = new Site();
site.start();
});
})(jQuery);

Call the same instance of jQuery plugin

I have written a jQuery plugin below and would like to be able to call it again for the same instance on an element.
The plugin goes...
(function($) {
$.fn.myPlugin = function(options){
var settings = {
color: null
};
if (options) {
$.extend(settings, options);
}
return this.each(function(){
var self = this;
var pics = $('li', self);
function refresh() {
pics = $('li', self);
};
$('a', self).click(function(){
pics.filter(':last').remove();
alert(settings.color);
refresh();
return false;
});
});
}
})(jQuery);
In the page this is called...
$('#test').myPlugin({ color: 'blue' });
Now I want to call the same plugin for the same instance but pass the string refresh as the option whilst all the other variables are the same (so color would still be blue) e.g...
$('#test').myPlugin('refresh');
This would then execute the refresh() function.
How could I achieve that with the above?
Edit: To make it clearer I am thinking of how jQuery UI does their plugins. In the sortable plugin you can do $("#sortable").sortable(); and then $("#sortable").sortable('refresh'); on the same element. This is what I am trying to achieve.
You can store your instance with .data() and check for it when creating an instance.
Something like:
$.fn.doStuff = function () {
var ob = $(this);
var data = ob.data();
if (data.doStuff !== undefined) {
return data.doStuff;
}
doStuff;
});
(function($) {
$.fn.myPlugin = function(options){
var init = function($self, ops){
$self.find("a").click(function(){
pics.filter(':last').remove();
alert(settings.color);
refresh();
return false;
});
};
this.refresh = function(){
//your code here
};
return this.each(function(){
var self = this;
var pics = $('li', self);
var settings = {
color: null
};
var ops = $.extend(true, settings, options);
init($(this), ops);
});
}
})(jQuery);
try something like this. and you can call refresh() like $().myPlugin().refresh();

Building simple jQuery plugin, need assistance

I'm building my first ever jQuery plugin (it's just a simple experiment). Here's what I have so far:
(function($){
$.fn.extend({
auchieFader: function(options) {
var defaults = {
mask: '',
topImg : '',
}
var options = $.extend(defaults, options);
return this.each(function() {
var o = options;
var obj = $(this);
var masker = $(o.mask, obj);
masker.hover(function () {
$(o.topImg).stop().animate({
"opacity": "0"
}, "slow");
}, function () {
$(o.topImg).stop().animate({
"opacity": "1"
}, "slow");
});
});
}
});
})(jQuery);
I'm then calling the plugin using:
$('.fader').auchieFader({mask: ".mask", topImg: ".top"});
If I then add another request say:
$('.fader2').auchieFader({mask: ".mask", topImg: ".top"});
Then no matter what instance of my 2 faders I hover both of them will trigger. I know this is because my mask mask and topImg options have the same class - but how can I modify the plugin to allow for these items to have the same class? I know it's probably something really simple, but I'm still finding my way with jQuery and Javascript in general. Any other tips on improving my code would also be greatly appreciated!
Cheers,
Chris
You seem to already have the answer to your question in the code. For the masker you wrote this:
var masker = $(o.mask, obj);
Which scopes the class in o.mask inside of the dom element obj
I think you just need to do the same thing for o.topImg.
Try changing
masker.hover(function () {
$(o.topImg)
into
masker.hover(function () {
$(o.topImg, obj)
try this:
(function($){
$.fn.extend({
auchieFader: function(options) {
var
// defaults options
defaults = {
mask: null,
topImg: null
},
// extend options in defaults
o = $.extend(defaults, options);
if (!o.mask || !o.topImg) return this;
return this.each(function() {
var
masker = $(o.mask, this),
topImg = $(o.topImg, this);
if (masker.length == 0 || topImg.length == 0) return;
masker.hover(
function () { topImg.stop().animate({ "opacity": "0" }, "slow"); },
function () { topImg.stop().animate({ "opacity": "1" }, "slow"); }
);
});
};
});
})(jQuery);

How can I listen for a click-and-hold in jQuery?

I want to be able to fire an event when a user clicks on a button, then holds that click down for 1000 to 1500 ms.
Is there jQuery core functionality or a plugin that already enables this?
Should I roll my own? Where should I start?
var timeoutId = 0;
$('#myElement').on('mousedown', function() {
timeoutId = setTimeout(myFunction, 1000);
}).on('mouseup mouseleave', function() {
clearTimeout(timeoutId);
});
Edit: correction per AndyE...thanks!
Edit 2: using bind now for two events with same handler per gnarf
Aircoded (but tested on this fiddle)
(function($) {
function startTrigger(e) {
var $elem = $(this);
$elem.data('mouseheld_timeout', setTimeout(function() {
$elem.trigger('mouseheld');
}, e.data));
}
function stopTrigger() {
var $elem = $(this);
clearTimeout($elem.data('mouseheld_timeout'));
}
var mouseheld = $.event.special.mouseheld = {
setup: function(data) {
// the first binding of a mouseheld event on an element will trigger this
// lets bind our event handlers
var $this = $(this);
$this.bind('mousedown', +data || mouseheld.time, startTrigger);
$this.bind('mouseleave mouseup', stopTrigger);
},
teardown: function() {
var $this = $(this);
$this.unbind('mousedown', startTrigger);
$this.unbind('mouseleave mouseup', stopTrigger);
},
time: 750 // default to 750ms
};
})(jQuery);
// usage
$("div").bind('mouseheld', function(e) {
console.log('Held', e);
})
I made a simple JQuery plugin for this if anyone is interested.
http://plugins.jquery.com/pressAndHold/
Presumably you could kick off a setTimeout call in mousedown, and then cancel it in mouseup (if mouseup happens before your timeout completes).
However, looks like there is a plugin: longclick.
var _timeoutId = 0;
var _startHoldEvent = function(e) {
_timeoutId = setInterval(function() {
myFunction.call(e.target);
}, 1000);
};
var _stopHoldEvent = function() {
clearInterval(_timeoutId );
};
$('#myElement').on('mousedown', _startHoldEvent).on('mouseup mouseleave', _stopHoldEvent);
Here's my current implementation:
$.liveClickHold = function(selector, fn) {
$(selector).live("mousedown", function(evt) {
var $this = $(this).data("mousedown", true);
setTimeout(function() {
if ($this.data("mousedown") === true) {
fn(evt);
}
}, 500);
});
$(selector).live("mouseup", function(evt) {
$(this).data("mousedown", false);
});
}
I wrote some code to make it easy
//Add custom event listener
$(':root').on('mousedown', '*', function() {
var el = $(this),
events = $._data(this, 'events');
if (events && events.clickHold) {
el.data(
'clickHoldTimer',
setTimeout(
function() {
el.trigger('clickHold')
},
el.data('clickHoldTimeout')
)
);
}
}).on('mouseup mouseleave mousemove', '*', function() {
clearTimeout($(this).data('clickHoldTimer'));
});
//Attach it to the element
$('#HoldListener').data('clickHoldTimeout', 2000); //Time to hold
$('#HoldListener').on('clickHold', function() {
console.log('Worked!');
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<img src="http://lorempixel.com/400/200/" id="HoldListener">
See on JSFiddle
Now you need just to set the time of holding and add clickHold event on your element
Try this:
var thumbnailHold;
$(".image_thumb").mousedown(function() {
thumbnailHold = setTimeout(function(){
checkboxOn(); // Your action Here
} , 1000);
return false;
});
$(".image_thumb").mouseup(function() {
clearTimeout(thumbnailHold);
});

Categories

Resources