P
petermichaux
Hi,
I've been reading the recent posts and older archives of
comp.lang.javascript and am surprised by the sentiments expressed about
the prototype.js library for a few reasons:
1) The library has been referred to as "junk" many times which is a
strong opinion against the relatively high popularity of the library. I
know popularity doesn't make something good.
2) People who use it are advised to "get a minimal clue". (Paraphrased.
Search archives "prototype.js minimal".)
3) Those who criticize so strongly must believe they know better but
the posts I saw containing the criticism did not indicate why the
library is so bad.
I have used the prototype.js library a bit with a mixed experience.
I had very little success with the Enumerable iterators. Constant
problems. They make for code that is bulky enough to match the size of
a JavaScript for loop. In Ruby these types of methods are great but I
don't think they work so well in JavaScript the way prototype.js
implements them.
I have enjoyed using the event parts of prototype.js without any
problems or even reading any of the code. It's usually the goal of a
library to make it so the user doesn't have to know the library's
internals. I'll count this as a success for prototype.js. However,
after reading such criticisms I decided to look at the code just in
case I got lucky so far. It turns out that for my application I was
able to take only about 90 lines of prototype.js's 1800 lines. These
lines are below. I've read them now. They seem ok to me. I would like
to know if anyone thinks this is a weak part of the prototype.js
library and why? Particularly comments regarding the browser
incompatibility workarounds as well as overcoming the IE problems of
the "this" keyword and bubbling (discussed on
http://www.quirksmode.org/js/events_advanced.html).
One thing I wish was that prototype.js used a namespace (discussed
http://blog.dreamprojections.com/archive/2004/12/27/450.aspx). This
would mean the code that uses the library would not look quite so cool
since it would not be possible to extend Event, Function, String, etc.
What do you like or dislike about prototype.js? Any reasons why
prototype.js is "junk"?
I think a critical discussion of this library would be very educational
for many people. I know that I am trying to "get a minimal clue".
Thanks,
Peter
// ------------------------------------------------------------
Function.prototype.bindAsEventListener = function(object) {
var __method = this;
return function(event) {
return __method.call(object, event || window.event);
}
};
function $() {
var elements = new Array();
for (var i = 0; i < arguments.length; i++) {
var element = arguments;
if (typeof element == 'string')
element = document.getElementById(element);
if (arguments.length == 1)
return element;
elements.push(element);
}
return elements;
};
// -------------------------------------------------------------------
Event.element = function(event) {
return event.target || event.srcElement;
};
Event.stop = function(event) {
if (event.preventDefault) {
event.preventDefault();
event.stopPropagation();
} else {
event.returnValue = false;
event.cancelBubble = true;
}
};
Event.observers = false;
Event._observeAndCache = function(element, name, observer, useCapture)
{
if (!this.observers) this.observers = new Array();
if (element.addEventListener) {
this.observers.push([element, name, observer, useCapture]);
element.addEventListener(name, observer, useCapture);
} else if (element.attachEvent) {
this.observers.push([element, name, observer, useCapture]);
element.attachEvent('on' + name, observer);
}
};
Event.unloadCache = function() {
if (!Event.observers) return;
for (var i = 0; i < Event.observers.length; i++) {
Event.stopObserving.apply(this, Event.observers);
Event.observers[0] = null;
}
Event.observers = false;
};
Event.observe = function(element, name, observer, useCapture) {
var element = $(element);
useCapture = useCapture || false;
if (name == 'keypress' &&
(navigator.appVersion.match(/Konqueror|Safari|KHTML/)
|| element.attachEvent))
name = 'keydown';
this._observeAndCache(element, name, observer, useCapture);
};
Event.stopObserving = function(element, name, observer, useCapture) {
var element = $(element);
useCapture = useCapture || false;
if (name == 'keypress' &&
(navigator.appVersion.match(/Konqueror|Safari|KHTML/)
|| element.detachEvent))
name = 'keydown';
if (element.removeEventListener) {
element.removeEventListener(name, observer, useCapture);
} else if (element.detachEvent) {
element.detachEvent('on' + name, observer);
}
};
/* prevent memory leaks in IE */
Event.observe(window, 'unload', Event.unloadCache, false);
I've been reading the recent posts and older archives of
comp.lang.javascript and am surprised by the sentiments expressed about
the prototype.js library for a few reasons:
1) The library has been referred to as "junk" many times which is a
strong opinion against the relatively high popularity of the library. I
know popularity doesn't make something good.
2) People who use it are advised to "get a minimal clue". (Paraphrased.
Search archives "prototype.js minimal".)
3) Those who criticize so strongly must believe they know better but
the posts I saw containing the criticism did not indicate why the
library is so bad.
I have used the prototype.js library a bit with a mixed experience.
I had very little success with the Enumerable iterators. Constant
problems. They make for code that is bulky enough to match the size of
a JavaScript for loop. In Ruby these types of methods are great but I
don't think they work so well in JavaScript the way prototype.js
implements them.
I have enjoyed using the event parts of prototype.js without any
problems or even reading any of the code. It's usually the goal of a
library to make it so the user doesn't have to know the library's
internals. I'll count this as a success for prototype.js. However,
after reading such criticisms I decided to look at the code just in
case I got lucky so far. It turns out that for my application I was
able to take only about 90 lines of prototype.js's 1800 lines. These
lines are below. I've read them now. They seem ok to me. I would like
to know if anyone thinks this is a weak part of the prototype.js
library and why? Particularly comments regarding the browser
incompatibility workarounds as well as overcoming the IE problems of
the "this" keyword and bubbling (discussed on
http://www.quirksmode.org/js/events_advanced.html).
One thing I wish was that prototype.js used a namespace (discussed
http://blog.dreamprojections.com/archive/2004/12/27/450.aspx). This
would mean the code that uses the library would not look quite so cool
since it would not be possible to extend Event, Function, String, etc.
What do you like or dislike about prototype.js? Any reasons why
prototype.js is "junk"?
I think a critical discussion of this library would be very educational
for many people. I know that I am trying to "get a minimal clue".
Thanks,
Peter
// ------------------------------------------------------------
Function.prototype.bindAsEventListener = function(object) {
var __method = this;
return function(event) {
return __method.call(object, event || window.event);
}
};
function $() {
var elements = new Array();
for (var i = 0; i < arguments.length; i++) {
var element = arguments;
if (typeof element == 'string')
element = document.getElementById(element);
if (arguments.length == 1)
return element;
elements.push(element);
}
return elements;
};
// -------------------------------------------------------------------
Event.element = function(event) {
return event.target || event.srcElement;
};
Event.stop = function(event) {
if (event.preventDefault) {
event.preventDefault();
event.stopPropagation();
} else {
event.returnValue = false;
event.cancelBubble = true;
}
};
Event.observers = false;
Event._observeAndCache = function(element, name, observer, useCapture)
{
if (!this.observers) this.observers = new Array();
if (element.addEventListener) {
this.observers.push([element, name, observer, useCapture]);
element.addEventListener(name, observer, useCapture);
} else if (element.attachEvent) {
this.observers.push([element, name, observer, useCapture]);
element.attachEvent('on' + name, observer);
}
};
Event.unloadCache = function() {
if (!Event.observers) return;
for (var i = 0; i < Event.observers.length; i++) {
Event.stopObserving.apply(this, Event.observers);
Event.observers[0] = null;
}
Event.observers = false;
};
Event.observe = function(element, name, observer, useCapture) {
var element = $(element);
useCapture = useCapture || false;
if (name == 'keypress' &&
(navigator.appVersion.match(/Konqueror|Safari|KHTML/)
|| element.attachEvent))
name = 'keydown';
this._observeAndCache(element, name, observer, useCapture);
};
Event.stopObserving = function(element, name, observer, useCapture) {
var element = $(element);
useCapture = useCapture || false;
if (name == 'keypress' &&
(navigator.appVersion.match(/Konqueror|Safari|KHTML/)
|| element.detachEvent))
name = 'keydown';
if (element.removeEventListener) {
element.removeEventListener(name, observer, useCapture);
} else if (element.detachEvent) {
element.detachEvent('on' + name, observer);
}
};
/* prevent memory leaks in IE */
Event.observe(window, 'unload', Event.unloadCache, false);