Is it possible to create a mixin for a jQuery selector (please note, I don't need no plugins, they are just too bulky for what I'm doing)?
Here's the task I'm trying to accomplish:
// Given a div I need to paint it with green for which...
var $container = $("#id001");
// current solution
var do = function(e) {
var container = e.container;
container.css("backgroudColor", "green");
};
do({ container: $container }); // call
// desired solution
var do**Mixin** = function(e){
e.css("backgroudColor", "green");
};
container.do(); // call
I know you said you don't need a plugin, but a plugin for what you need is very simple:
function($){
$.fn.makeItGreen = function(){
return this.each(function() {
this.css({
'background-color': 'green'
});
});
}
)(jQuery));
Use:
$(yourSelector).makeItGreen();
Untested, but....pretty sure it should work as is.
Fiddle (courtesy of Jamiec):
http://jsfiddle.net/mPu6X/
Are you looking for something like this? http://jsfiddle.net/WDmjS/
jQuery.prototype.do = function(){
this.css("background-color","green");
return this;
};
$(".mydiv").do();
More concisely written:
$.fn.do = function(){
return this.css("background-color","green");
};
You can make a custom event:
$('selector').on('changeToGreen', function(){
$(this).css("backgroudColor", "green");
});
To "do" it:
$('selector').trigger('changeToGreen');
Related
I'm converting a mootools class to Jquery, but I'm with a problem at the moment.
I've the following code (mootools)
var ListaItens = new Class({
...
...
initialize: function(element){
....
this.btnAdd = this.tabela.getElement('.add_linha button');
if(this.btnAdd){
this.btnAdd.addEvent('click', this.addLinha.bindWithEvent(this));
this.checkAdd();
}
...
},
addLinha: function(){
}
});
Now in Jquery I've this
var ListaItens = function(element, maxLinhas){
...
this.btnAdd = this.tabela.find('.add_linha button')[0];
if(this.btnAdd){
//$(this.btnAdd).proxy('click', this.addLinha);
$(this.btnAdd).on("click", this.addLinha);
this.checkAdd;
}
...
this.addLinha = function(){
}
})
My problem is how to bind the addline function to btnAdd. My code isn't work because the element 'this' change. And I don't know how to convert the function bindWithEvent to jquery.
Any solution?
Thanks in advance
As far as I know, jQuery does not provide a similar concept of classes as mootools does, so one thing you can do is to use the »classic JS approach« to create classes like so:
function ListaItens () {
var that = this;
this.tabela = $(…);
this.btnAdd = this.tabela.find(…);
if (this.btnAdd) {
this.this.btnAdd.on('click', function (e) {
that.addLinha();
})
}
}
ListaItens.prototype.addLinha = function () {
}
var instance = new ListaItens();
So, to answer your question: What you basically need to do is to keep a reference to the »original this«
I'm trying to make a simple tumblr theme using the fluffy plugin (https://github.com/mzdr/fluffy.js) but I've ran into a problem. The plugin only executes once on page load. I'm trying to get it to work with the infinite scroll plugin (http://www.infinite-scroll.com/) and I need the fluffy plugin to trigger whenever new content loads.
I'm fairly new when it comes to JS so I appreciate any help I can get. Thanks.
Edit added code:
<script src="https://code.jquery.com/jquery-2.2.2.min.js"></script>
<script src="https://npmcdn.com/imagesloaded#4.1/imagesloaded.pkgd.min.js"></script>
<script src="http://static.tumblr.com/hpghjri/co2nfnr1j/infinitescroll.min.js"></script>
<script src="http://static.tumblr.com/nxwjyyg/XWUob8gtq/fluffy.min.js"></script>
<script>
$(function(){
app.initInfinite();
app.onImagesLoad();
}); //end document ready
var app = {
'initInfinite' : function() {
var $container = $('.page-index .posts');
$container.infinitescroll({
navSelector:".pagination",
nextSelector:".pagination-next",
itemSelector:".posts__container",
appendCallback:true,
loading:{
finishedMsg:" ",
img:"data:image/gif;base64,R0lGODlhAQABAHAAACH5BAUAAAAALAAAAAABAAEAAAICRAEAOw==",
msg:null,
msgText:" ",
selector:null,
finished:function() {
}
}
},
function(newElements) {
var $newElems = $(newElements).css({opacity:0});
var $newElemsIDs = $newElems.map(function() {
return this.id;
Tumblr.LikeButton.get_status_by_post_ids($newElemsIDs);
}).get();
$newElems.imagesLoaded(function() {
$newElems.animate({opacity: 1});
//what to do when new elems appended
// I need to trigger fluffy here
});
var $newElemsIDs = $newElems.map(function() {
return this.id;
}).get();
Tumblr.LikeButton.get_status_by_post_ids($newElemsIDs);
});
},
'onImagesLoad' : function() {
$('.content .posts').imagesLoaded()
.always( function( instance ) {
console.log('all images loaded');
$('.overlay').addClass('hide');
$('.overlay__preloader').attr('class', '');
})
.done( function( instance ) {
console.log('all images successfully loaded');
});
}
}
</script>
This is your lucky day! I just released v2.1.0 which fixes your problem. Now you can create Fluffy objects on the fly like that:
// Start automatic detection
Fluffy.detect();
// Or provide a DOM node for single creation
var myElement = document.querySelector('#what-ever-you-like');
Fluffy.create(myElement);
// Or use a selector to create one
Fluffy.create('[data-fluffy-container]');
Don't forget to check out the updated docs.
I'm using jquery 1.9.1 and I'm trying to develop a plugin. The problem is that the plugin isn't working. Here's the code:
;(function($) {
$.fn.single = function() {
return this.each(function(){
// Get the instance
var element = $(this);
// Resize the "data-target" divs
element.load(function(){
changeCSS(element);
});
// Bind the method to the resize window event
$(window).bind("resize", function(){
changeCSS(element);
});
});
};
// function to resize all the "data-target" divs
function changeCSS(element) {
// Grab the screen resolution
var windowWidth = $(window).width();
var windowHeight = $(window).height();
// Count how many targets the div has
var targetsSize = $("[data-target]").size();
// Resize the parent div
$(element).css({
"width" : windowWidth,
"height": windowHeight * targetsSize
});
// Resize all the targets div
$(element + "> div[data-target]").each(function(){
$(this).css({
"width" : windowWidth,
"height": windowHeight
});
});
}
})(jQuery);
And I'm calling it on the document like that:
<script src="js/jquery-1.9.1.min.js"></script>
<script src="js/single-0.1.0.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#single").single();
});
</script>
There's no problem in the console. What I'm doing wrong?
I'm assuming that it is because you are misusing the method .load. If you look at the jQuery docs, it is intended for:
.load() : Load data from the server and place the returned HTML
into the matched element.
http://api.jquery.com/load/
Remove the lines element.load(function ..., simply call your changeCSS function, you're already loading this extension on Document.Ready
return this.each(function () {
// ...
changeCSS(element); // <-- just run the function right away
// ... etc
});
Generally it is bad practice to call a function before it is declared. To get your plugin right, you will be better of starting structuring it correctly from the beginning. Besides that, as #mcpDESIGNS point out, you are using the .load method wrongly. Also, it would be useful if you explain what exactly it is you are trying to accomplice here.
To get a good start making jQuery plugins, try to look at the documentation at jQuery here or you can look at this tutorial.
This is the preferred structure:
(function($) {
// Declare your methods at the beginning of your plugin
var yourMethods = {
'methodOne' : function() {
},
'methodTwo' : function() {
}
};
$.fn.pluginName = function() {
return this.each(function() {
});
}
}(jQuery));
Instead of:
element.load(function(){
changeCSS(element);
});
I did:
changeCSS(element);
And... Instead of:
$(element + "> div[data-target]")
I did:
$(element).children('div[data-target]')
And now the plugin is being executed with no bugs or errors.
Thanks Guys!
I'm trying to do a simple show/hide transition for a message div using fx.reveal in mootools 1.4. The effect works the first time, but not on subsequent clicks.
Any hints as to where I'm going wrong?
http://jsfiddle.net/MYgH6/1/
var mytween = new Fx.Reveal(document.getElementById('mydiv'), {duration: 2500});
$('myclick').addEvent('click', function(){
mymessage();
});
function mymessage(){
var mymessage = document.getElementById('mydiv');
mymessage.set('html','YO!');
mytween.reveal();
mytween.dissolve();
}
var mytween = new Fx.Reveal(document.getElementById('mydiv'), {
duration: 1000,
onComplete:function(){
this.element.dissolve();
}
});
$('myclick').addEvent('click', function(){
mymessage();
});
function mymessage(){
var mymessage = document.getElementById('mydiv');
mymessage.set('html','YO!');
mytween.reveal();
}
I know it's not best answer, as you specified using Fx.Reveal, but I'd use wink command
http://mootools.net/docs/more/Fx/Fx.Reveal#Element:wink
Like here: http://jsfiddle.net/zalun/MYgH6/5/
var msg = document.getElementById('mydiv').hide();
$('myclick').addEvent('click', function() {
msg.wink();
});
You can certainly specify the message within the function as you did before.
I have an extension going like:
$.fn.crazything = function() {
var self = $(this);
// do some crazy stuff
return self;
}
And when I call it like:
$("div.crazydiv").crazything();
It works, but only on the first matching div. If I have more than one div on the page, I need to do:
$("div.crazydiv").each(function(i) { $(this).crazything (); });
Why is this, and how can I rewrite my extension to work on multiple divs?
Most jQuery plugins use this pattern which handles your crazy stuff:
(function($) {
$.fn.crazything = function() {
// allow setup on jQuery objects that conatin multiple elements:
return this.each(function() {
// this function is called once for each element in the jQuery object
var self = $(this);
// do some crazy stuff
});
};
})(jQuery);