mootools 1.12 to 1.25 update script difficulties - javascript

hi i have a mootools script that works in version 1.12 but i want to update to 1.25 and it throws an error.
here is the script:
window.addEvent('load', function() {
Array.extend({
equalize: function(){
maxHeight = [];
this.each(function(el){
maxHeight.push(el.getSize().size.y);
});
this.setStyle('height', Math['max'].apply(Math, maxHeight));
}
});
$$('#col1,#col2,#col3,#col4,#col5').equalize();
$$('.column,.general').equalize();
});
pretty simple but i dont know what i need to do to update it for the newer version of mootools. the error in ie9 is the following:
Error Message: Object doesn't support property or method 'equalize'

You want to use implement instead of extend. Extend only adds a static method whereas implement alters the prototype of the Class.
That being said, you would probably want to use Elements instead of Array as equalize makes no sense for an untyped array (Elements can be considered an array that is only filled with Element items)
tl;dr: your code should read Elements.implement instead of Array.extend

In MooTools 1.2+ there's no size object of the getSize() method, so: el.getSize().size.y becomes el.getSize().y.
Example: http://jsfiddle.net/wagEJ/

Related

jQuery version of simple javascript doesnt work

I have this code in javascript
var greet;
greet = function() {
var textoNombre;
textoNombre = document.getElementById("textoNombre");
return alert(textoNombre.value);
};
what is working on the HTML document. But if I change document.getElementById("textoNombre") by the jQuery version $("#textoNombre") it just dont work. The alert says "undefined".
I have the jQuery script linked on the head of the HTML before to my custom js file.
This is a very basic question but I tried different things and no one work, can you help me please? Thank you in advance.
That's because jQuery objects don't have a value property, the equivelant is $('#someId').val().
To get the underlying DOM object, you can use $('#someId')[0]. This is because jQuery objects are actually like arrays, and their elements are the DOM objects themselves. That means $('#someId')[0].value would work as you'd expect.
jQuery objects are not DOM objects and don't share all their properties.
To get the current value of a form control, you would use the .val() method, not the .value property.

Why can't you call outerHTML on $(this)?

When you want to get the HTML of an entire DOM element (wrapper included), you can do the following (as explained here):
$('#myElementId')[0].outerHTML
But what you can't do is call outerHTML on $(this) inside e.g. a click listener or selector function body scope:
$(this).outerHTML //Doesn't complete in IntelliSense, returns undefined in browser
or
$(this)[0].outerHTML //Correction, this DOES work, but it doesn't complete in IntelliSense
because IntelliSense won't show innerHTML or outerHTML in those circumstances, although with vanilla JavaScript you can do:
document.getElementById($(this).attr('id')).outerHTML
So... what's up with that?
outerHTML is a DOM property; jQuery doesn't expose all DOM properties.
If you have a jQuery object, you can only directly access those properties and methods that jQuery exposes, and vice versa for DOM objects.
In object-oriented terms, jQuery objects don't inherit from DOM objects, they contain them.
Saying $x[0] gets you the DOM object for the first element represented by a jQuery object.
You can use directly this to access outerHTML of the current object instead of indirectly going through $(this) as this represents the DOM object (which has outerHTML property) whereas $(this) represents jQuery object.
this.outerHTML
jQuery selector returns an array-like jQuery object which has no outerHTML property.
However, the jQuery resulting array contains DOM elements.
It means that you can actually access it this way.
$(".someClass")[0].outerHTML // it works for me
Update:
It works for me in every browser.
I can access array-like jQuery object in a click event handler as well.
$(".someClass").click(function()
{
alert($(this)[0].outerHTML); // it works me too
});
Here is my JSFiddle: http://jsfiddle.net/13btf60p/
Update 2:
OK, now I get your question. It should have worked.
Do you really need an IntelliSense to complete such a plain and simple construction?
I will add what I found to be the correct solution to what ended up being a simple flaw in the default Visual Studio settings for future reference.
Since I didn't want to let this go, I searched further and found out that, by default, jQuery IntelliSense is somewhat deplorable out of the box in Visual Studio 2013.
Under
Tools > Options > Text Editor > Javascript > IntelliSense > References
I set
Reference Group: "Implicit (Web)"
and added an existing jQuery file. This solved all issues of my question and IntelliSense now suggests all members and methods correctly, although this should have simply worked out of the box instead of costing everyone a bunch of time.
this.outerHTML is enough.
If you use getElementById maybe you can use:
var table = document.getElementById('blablabla');

What does $($(this)) mean?

I saw some code around the web that uses the following statement
if ($($(this)).hasClass("footer_default")) {
$('#abc')
.appendTo($(this))
.toolbar({position: "fixed"});
}
What is the use of $($(this)) and why is that necessary here?
Yes, $($(this)) is the same as $(this), the jQuery() or $() function is wonderfully idempotent. There is no reason for that particular construction (double wrapping of this), however, something I use as a shortcut for grabbing the first element only from a group, which involves similar double wrapping, is
$($('selector')[0])
Which amounts to, grab every element that matches selector, (which returns a jQuery object), then use [0] to grab the first one on the list (which returns a DOM object), then wrap it in $() again to turn it back into a jQuery object, which this time only contains a single element instead of a collection. It is roughly equivalent to
document.querySelectorAll('selector')[0];, which is pretty much
document.querySelector('selector');
You can wrap $ as many times as you want, it won't change anything.
If foo is a DOM element, $(foo) will return the corresponding jQuery object.
If foo is a jQuery object, $(foo) will return the same object.
That's why $($(this)) will return exactly the same as $(this).
There is no specific need for double-wrapping and $($(this)) is exactly the same as $(this).
That said, I once found this double-wrapping in one file in my project, committed by another developer. Tracking the changes through revision, turned out that it started as $($(this).find('selector').first()) - that is, the result of some selector was wrapped to create a new object. Then for whatever reasons, the selector was removed and only the double-wrapping of this remained. Needless to say, on the next commit it was changed to $(this).
As explained before me, $($(this)) and $(this) are absolutely identical. jQuery returns the same jQuery object if you try to wrap it more than once.
Additionally, for performance considerations it is a good practice to reuse jQuery objects - it is quite expensive to create jQuery objects, especially the ones with complex selectors. Example:
var $this = $(this);
if ($this.hasClass("footer_default")) {
$('#abc')
.appendTo($this)
.toolbar({position: "fixed"});
}
Just google for 'jQuery best practices' - it will take a 30 min for you to learn these basics and you will use jQuery way more effectively.
There is no meainig of doing that.
The following code return the same:
console.log($($(this)).hasClass("footer_default"))
console.log($(this).hasClass("footer_default"))
a boolean value depenging on if the selected element has or not the class footer_default:
.hasClass( className )Returns: Boolean
Demo: http://jsfiddle.net/IrvinDominin/aSzFn/
$(this) and $($(this)) both return jquery object.
There is no difference between these two.

jQuery object html() doesn't work ... but innerHtml does

I have an object that should be a valid jQuery object. When I look at the variable in FireBug it contains all the jQuery functions I'd expect (clone, remove, removeat, etc.). However, I don't see html() as a valid function and when I do this:
stringValue = myjQueryObject.html();
It does fail, saying html() is not a function. However if I do something like this:
stringValue = myjQueryObject[0].innerHTML;
It will correctly pass back the object, minus the parent div and text (which I would expect, seeing as how it is just getting the innerHtml). What do am I missing here?
As noted below, it was an external library that was generating myjQueryObject that had previously returning a valid jQuery object and was updated ... incorrectly. For posterity's sake, I've updated my unit tests to verify that the external library returns a correct jQuery object, make sure this doesn't return null or undefined:
myjQueryObject.jquery
Thanks all! Had a bit of a freakout when my code suddenly broke this morning.
Either something is modifying the jQuery object prototype, or you have a different library loaded.
Take your object, and test for the jQuery version like this:
alert( myjQueryObject.jquery ); // should give the jQuery version number
EDIT:
Additionally, you state that there's a removeAt method. jQuery doesn't have one of those, unless you mean removeAttr().
Are you sure it's a jquery object? Wrap it in $() again and .html() should exist.
it's [0].innerHTML or .get(0).innerHTML, in that innerHTML is a property not a method.
You should make sure that jquery exists by doing alert( jQuery == $) and you can check for the .jquery property.
That's odd; try $(myjQueryObject).html();. If that works, the object isn't really a jQuery node.
If you still can't figure out why the object lost the html() method, post the code which creates it. Then, we might be able to help.
How are you setting myjQueryObject?
<div id='myElement'></div>
//Good Javascript, Incorrect jQuery
myjQueryObject = document.getElementById('myElement');
myjQueryObject.innerHTML = '<b>My HTML Here</b>';
//Correct jQuery
myjQueryObject = $('#myElement');
myjQueryObject.html('<b>My HTML Here</b>');
//Compact Version of Correct jQuery
$('#myElement').html('<b>My HTML Here</b>');

What jQuery annoyances should I be aware of as a Prototype user?

We're considering switching our site from Prototype to jQuery. Being all-too-familiar with Prototype, I'm well aware of the things about Prototype that I find limiting or annoying.
My question for jQuery users is: After working with jQuery for a while, what do you find frustrating? Are there things about jQuery that make you think about switching (back) to Prototype?
I think the only that gets me is that when I do a selection query for a single element I have to remember that it returns an array of elements even though I know there is only one. Normally, this doesn't make any difference unless you want to interact with the element directly instead of through jQuery methods.
Probably the only real issue I've ever ran into is $(this) scope problems. For example, if you're doing a nested for loop over elements and sub elements using the built in JQuery .each() function, what does $(this) refer to? In that case it refers to the inner-most scope, as it should be, but its not always expected.
The simple solution is to just cache $(this) to a variable before drilling further into a chain:
$("li").each(function() {
// cache this
var list_item = $(this);
// get all child a tags
list_item.find("a").each(function() {
// scope of this now relates to a tags
$(this).hide("slow");
});
});
My two pain points have been the bracket hell, can get very confusing
$('.myDiv').append($('<ul />').append($('<li />').text('content')));
My other common issue has to do with the use of JSON in jQuery, I always miss the last comma,
$('.myDiv').tabs({ option1:true, options2:false(, woops)});
Finally, I've been using jQuery for about 6 months now and I don't think I'll ever go back to prototypes. I absolutely love jQuery, and a lot of the tricks they use have helped me learn a lot. one cool trick that I like is using string literals for method calls, I never really did that too much with prototypes.
$('.myDiv')[(add ? 'add' : 'remove') + 'Class']('redText');
(The only thing I can think of is that this is the element instead of a jQuery object in $("...").each(function)-calls, as $(element) is more often used then just the element. And that extremly minor thing is just about it.
Example of the above (simplified and I know that there are other much better ways to do this, I just couldn't think of a better example now):
// Make all divs that has foo=bar pink.
$("div").each(function(){
if($(this).attr("foo") == "bar"){
$(this).css("background", "pink");
}
});
each is a function that takes a function as parameter, that function is called once for each matching element. In the function passed, this refers to the actual browser DOM-element, but I find that you often will want to use some jQuery function on each element, thus having to use $(this). If this had been set to what $(this) is, you'd get shorter code, and you could still access the DOM element object using this.get(0). Now I see the reason for things being as they are, namely that writing $(this) instead of this, is hardly that cumbersome, and in case you can do what you want to do with the DOM element the way it is is faster than the way it could have been, and the other way wouldn't be faster in the case you want $(this).)
I don't think there are any real gotchas, or even any lingering annoyances. The other answers here seem to confirm this - issues are caused simply by the slightly different API and different JavaScript coding style that jQuery encourages.
I started using Prototype a couple of years ago and found it a revelation. So powerful, so elegant. After a few months I tried out jQuery and discovered what power and elegance really are. I don't remember any annoyances. Now I am back working on a project using Prototype and it feels like a step back (to be fair, we're using Prototype 1.5.1).
If you reversed the question - "What Prototype annoyances should I be aware of as a jQuery user?" - you would get a lot more answers.
Nope. Nada. Nyet.
.each:
jQuery (you need Index, even if you're not using it):
$.each(collection, function(index, item) {
item.hide();
});
Prototype (you're usually using the item, so you can omit the index):
collection.each(function(item) {
item.hide();
});
This is really only an annoyance if you're doing a lot of DOM manipulation. PrototypeJs automatically adds its API to DOM Elements, so this works in prototypejs (jQuery of course doesn't do this):
var el = document.createElement("div");
el.addClassName("hello"); // addClassName is a prototypejs method implemented on the native HTMLElement
Even without running the native element through the $() function.
PS: Should note that this doesn't work in IE.

Categories

Resources