I am using both jQuery and Zepto.
I want to conditionally invoke Zepto methods on a jQuery collection. Anyone have an eloquent solution? My code currently looks something like this:
// Obtain jQuery Object
var $selector = jQuery('.selector');
// Desktop
$selector.click( ... );
// Mobile
if (window.Zepto){
$selector.slideLeft( ... );
}
It is very brittle, but you can use Function.call to apply Zepto functions to jQuery objects. I did a proof-of-concept fiddle (http://jsfiddle.net/STnUQ/1/) and obviously it works for the simple css function.
var div = jQuery('.test');
Zepto().css.call(div, 'color', 'red');
So long as the underlying data structure of the jQuery object matches Zepto, it will work just fine. But this is not guaranteed (or even probable) and you should do extensive testing with your specific use.
Related
Say I have a map on an array of elements. The callback function takes the index and the value at that position in the array.
If I wrap the array element that the callback receives in $(), it behaves as I expect. If I use it without wrapping it in $(), it gives an error.
var nonHiddenElements = $( "form :input" ).not(':hidden');
nonHiddenElements.map(function(index, element){
input_id = $(element).attr('id'); // this works
input_id = element.attr('id') ; // this gives an error
})
Can someone explain how this works.
Is this a jQuery quirk, or a JavScript thing?
What type of objects does my nonHiddenElements array contain exactly?
What is element that gets passed to the callback?
And mainly what is the $() doing?
You need to understand how jQuery actually works. I will try to explain it briefly.
$ is nothing but a normal javascript function. jQuery === $, is just a function with a fancy name. This function does a lot of different things, depending on what you pass in it. For example if you pass a string it will be treated as CSS selector and jQuery internals will try to find corresponding DOM elements. Or if you pass a string starting with < and ending with > jQuery will create a new DOM element by provided HTML string.
Now if you pass a DOM element or NodeCollection of DOM elements, it/they will be wrapped into jQuery instances so that they can have a jQuery prototype methods. There are many prototype methods jQuery offers. For example text, css, append, attr - those are all methods of jQuery prototype. They are defined basically like this (simplified):
jQuery.prototype.text = function() { ... }
Normal DOM elements don't have those convenient methods jQuery provides. And inside of methods like map or each if you check this value or element parameter like you do, you will see that they are actually not jQuery instances:
element instanceof jQuery // => false
and of course you can't use instance methods with not an instance.
So in order to use jQuery prototype methods you need have a jQuery instance, which you can obtain if you call jQuery function with DOM element passed in it:
$(element) instanceof jQuery // true
Javascript is a programming language.
jQuery is a JavaScript Library.
With jQuery:
$("some element")
In native JavaScript you would have to do something like this.
getElementById('elementByID')
Explained in detail here: https://developer.mozilla.org/en-US/docs/Web/API/document.getElementById
MDN is a great resource for beginners. https://developer.mozilla.org/en-US/docs/Web/JavaScript
I've got a jQuery plugin that starts a setInterval when initialized on an element; something like this:
(function($){
$.fn.myPlugin = function(options){
/* snip */
var interval = setInterval(recurringFunction, options.interval);
/* snip */
};
})(jQuery);
I'd like to be able to do the general equivalent of jQuery UI's .destroy() function, where my plugin would clean up after itself and restore its target element (without removing it) to its original state (in my case, stopping that timeout). However, plain jQuery doesn't seem to have any standard convention for defining something like this. I don't use, need, or want jQuery UI. Is there a convention for cleaning up after a jQuery plugin, or do I just need to roll my own?
To clarify: I'm looking for a generic, common convention to define logic that cleans up after a plugin; I'm not asking how to clear a timeout.
You need to roll your own destroy method unless you are using the jQueryUI widget factory.
So I have a set of jQuery plugins, really basic stuff, but I split the code into plugins because I don't like having a huge jQuery(document).ready() function where I store the entire application logic.
Each plugin has a "destructor", which is basically a function that I defined in the plugin prototype object. This function unbinds events used by the plugin, removes DOM elements that were added by the plugin etc.
Plugins are initialized like this:
$('.element').plugin();
Is there any way I can get all the elements that have my plugins attached to them, from another plugin which is supposed to replace the body HTML, so I can call the destructor function?
I was thinking to store each plugin instance inside a global array, then I can access that array from any plugin. But maybe there is a better way that doesn't use the global state?
I don't think there is a ready made method for it... but as a hack you can add a class to the target elements in your plugin and then use that class to get all elements with the widget initialized lke
$.fn.plugin = function(){
this.addClass('my-plugin-class');
}
then to initialize
$(element).plugin()
to get all elements with the plugin
$('.my-plugin-class')....
But if it is a jQuery UI widget then you can use the selector $(':ui-widgetname'), see this answer
Arun P Johny wrote the rigth idea -- just delete 'footprint' of your job by marking the affected DOM elements with some specific class name.
I want just add an idea. Plugins are the methods of the library and nothing more. If you need the destroyer for constructor -- just make another plugin for it:
$.fn.overture = function (){...};// construct
$.fn.crescendo = function (){...};// more construct
$.fn.quietFarewell = function (){...};// destructor for everything above
$(...).overture().crescendo().quietFarewell();
I am using the jQuery-File-Upload widget (although I believe this question can generalize to any jQuery widget). The API instructs the user to initialize the the widget using the fileupload method, thus:
$('#fileupload').fileupload();
My question is: Without knowing IDs, how can I find #fileupload (and any other elements which have had .fileupload() called upon them?
jQuery File Upload uses the jQuery UI widget factory under the hood, and that factory is known to register the widgets instances with the elements they extend using data().
Therefore, you can use filter() and write something like:
// Restrict ancestor if you can, $("*") is expensive.
var uploadified = $("#yourAncestor *").filter(function() {
return $(this).data("fileupload");
});
Update: From jQuery UI 1.9 onwards, the data() key becomes the widget's fully qualified name, with dots replaced by dashes. Therefore, the code above becomes:
var uploadified = $("#yourAncestor *").filter(function() {
return $(this).data("blueimp-fileupload");
});
Using the unqualified name is still supported in 1.9 but is deprecated, and support will be dropped in 1.10.
On mootools I'm used to declare once and reuse often. An FX example would go like this:
myEffect1 = new Fx.Slide($('myElement1'));
How should I go on jQuery? Meaning, the docs make it straightfoward to use:
$('myElement1').click(function(e){
this.slideToggle();
});
But if I want to call this effect somewhere else on my code will I have to re-declare it? And isn't this approach more resource hungry than the one above? How would this be properly done on jQuery?
Just manually cache the result set in a variable before calling the function, then reuse the function as needed:
var $el_one = $("#path .to > .selection"), // Stores jQuery object
$el_two = $("#path .to > .second"); // Stores jQuery object
var effect = function(){
$el_one.fadeIn();
$el_two.fadeOut();
}
Now you can call effect any time without reselecting the items. They instead use the cached jQuery selection to animate correctly.
If you need more clarity, let me know.
var slideToggleEffect = function(e){
this.slideToggle();
};
$('myElement1').click(slideToggleEffect);
$('myElement2').click(slideToggleEffect);
...
I'd go with a plugin in this case. For example here's a plugin that I use often - a very simple slide and fade toggle effect.
$.fn.slideFadeToggle = function(easing, callback) {
return this.animate({opacity: 'toggle', height: 'toggle'}, "fast", easing, callback);
};
Now you can call slideFadeToggle on any selector like this:
$("#somedom").slideFadeToggle();
Since every command acts on a jQuery object (the object returned by calling $() on a selector), the example you've given is the nearest comparison to what you're used to in MooTools, as far as I can see.
Is it more resource hungry? Well, that's a complex question to answer as instantiating objects is only one piece of client side code. Some framework methods for performing certain operations are better in some situations and worse in others.