Nützliche JavaScript-Schnipsel
Christoph
- javascript
Moin.
Diejenigen von euch, die sich seit längerem mit JavaScript herumschlagen mussten, habe sich mit der Zeit eventuell eine eigene Bibliothek von Skripten zugelegt.
Ich würde gerne sehen, was sich bei anderen so angesammelt hat. Dabei sollten die Skripte
- nützlich
- kurz
- browserübergreifend funktionstüchtig
sein. Zwei von drei Punkten sollten mindestens erfüllt sein.
Ich mache mal den Anfang:
--- clone() ---
Echte prototypische Vererbung mit der von Mozilla bekannten \_\_proto\_\_
Eigenschaft. Anders als in Geckos ist diese browserübergreifend jedoch nur bei Objekterzeugung setzbar.
function clone(obj) {
if(obj.isPrototypeOf(this))
this.__proto__ = obj;
else return new arguments.callee(arguments.callee.prototype = obj);
}
--- hash() ---
Hashfunktion für beliebige Datentypen. Erlaubt es, Objekte als Maps mit beliebigen Schlüsseln zu verwenden - unterscheidet '5' und 5 und versieht Objekte mit eindeutiger Id.
function hash(value) {
return (typeof value) + ' ' + (value instanceof Object ?
(value.__hash || (value.__hash = ++arguments.callee.current)) :
value.toString());
}
hash.current = 0;
--- each() ---
Iteration über die objekteigenen Eigenschaften.
function each(obj, func) {
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
func.call(obj, prop, obj[prop]);
}
}
--- XMLHttpRequest() ---
Erlaubt es, Request-Objekte auch im IE über new XMLHttpRequest()
zu erzeugen.
if(typeof window.XMLHttpRequest !== 'function' &&
typeof window.ActiveXObject === 'function') {
window.XMLHttpRequest = function() {
try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
return null;
};
}
--- onready() ---
Browserübergreifender Ersatz für das DOMContentLoaded-Ereignis. Erwartet eine Liste von Funktionen als Argumente.
function onready() {
var args = arguments;
var timeout = arguments.callee.timeout;
(function() {
if(document.body && document.body.lastChild) {
for(var i = 0; i < args.length; ++i)
args[i]();
}
else setTimeout(arguments.callee, timeout);
})();
}
onready.timeout = 100;
--- capture() ---
Nicht wirklich kurz, aber dafür äußerst nützlich: Vereinfacht die Ereignis-Behandlung enorm. Erwartet als Argmente:
1. den Ereignis-Typ (z.B. 'click')
2. eine Auswahlregel, welche Elemente als Ereignis-Quellen in Frage kommen
3. die Funktion, die das Ereignis verarbeitet
Erlaubte Werte für die Auswahlregel sind
- true
:
Das Ereignis wird immer abgefangen
- eine Zeichenkette:
Beginnt diese mit '#', werden Elemente mit entsprechender Id behandelt. Beginnt sie mit '.', werden Elemente mit entsprechender Klasse behandelt. Ansonsten wird die Zeichenkette als Element-Name interpretiert.
- ein regulärer Ausdruck:
Der Ausdruck wird gegen die className
-Eigenschaft eines Elements geprüft.
- eine beliebige Funktion:
Das zu überprüfende Element wird als this
übergeben; die Funktion muss einen Wahrheitswert zurückgeben.
Sowohl in standardkonformen Browsern als auch im IE wird der Verarbeitungsfunktion die Ereignis-Quelle als this
und das Ereignis-Objekt als erstes Argument übergeben. Liefert die Funktion false
zurück, wird die Standard-Behandlung des Ereignisses (Formular absenden, Link verfolgen, ...) ausgesetzt.
var capture = (function() {
function noCapture() {
throw new Error('event capture unsupported');
}
function returnTrue() {
return true;
}
function createChecker(condition) {
if(condition === true)
return returnTrue;
if(typeof condition === 'string') {
switch(condition.charAt(0)) {
case '#': {
var id = condition.substring(1);
return function() {
return this.id === id;
}
}
case '.': {
return createChecker(eval('/(^|\s)' +
condition.substring(1) + '(\s|$)/'));
}
default: {
var tagName = condition.toLowerCase();
return function() {
return this.nodeName.toLowerCase() === tagName;
};
}
}
}
if(condition instanceof RegExp) {
return function() {
return condition.test(this.className);
};
}
if(typeof condition === 'function')
return condition;
throw new Error('unsupported capture condition: ' + condition);
}
function addCapture(type, condition, handler) {
var checker = createChecker(condition);
document.addEventListener(type, function(event) {
if(checker.apply(event.target) &&
handler.call(event.target, event) === false) {
event.preventDefault();
}
}, false);
}
function attachCapture(type, condition, handler) {
var checker = createChecker(condition);
document.attachEvent('on' + type, function() {
if(checker.apply(event.srcElement) &&
handler.call(event.srcElement, event) === false) {
event.returnValue = false;
}
});
}
return document.addEventListener ? addCapture :
document.attachEvent ? attachCapture :
noCapture;
})();
Und jetzt ihr ;)
Christoph
PS: Der Name der Funktion capture()
ist irreführend, da sie am Ende der 'bubbling'- Phase und nicht zu Beginn der 'capture'-Phase greift (vgl. w3c Spezifikation).
Irgendwelche Namensvorschläge?
Christoph
Hi,
keine Ahnung ob das Forum jetzt hier ein Scriptarchiv zulässt, ich fände es nicht verkehrt.
Meinen Senf kann ich allerdings nicht dazugeben, weil meine JS-Schnipsel dir wohl zu trivial erscheinen würden, wenn ich deine proffesionellen Dinger sehe.
Aber ich schreibe dennoch mal aus einem anderen Grund. Bei deinem Nick fällt mir auf, das ein schreibfreudiger Stammposter namens "Christoph Schnauß" seit einem halben Jahr nichts mehr schreibt, weiss Jemand warum?
Paul
Moin!
keine Ahnung ob das Forum jetzt hier ein Scriptarchiv zulässt, ich fände es nicht verkehrt.
Ich halte es für eine schlechte Idee. Das Archiv ist riesig und nicht so wahnsinnig gut durchsuchbar - jedenfalls im Vergleich zu viel besser geeigneteren Orten wie z.B. den Artikeln.
Meinen Senf kann ich allerdings nicht dazugeben, weil meine JS-Schnipsel dir wohl zu trivial erscheinen würden, wenn ich deine proffesionellen Dinger sehe.
Aber ich schreibe dennoch mal aus einem anderen Grund. Bei deinem Nick fällt mir auf, das ein schreibfreudiger Stammposter namens "Christoph Schnauß" seit einem halben Jahr nichts mehr schreibt, weiss Jemand warum?
Nein, keiner weiß das. Denk dir einfach irgendeinen der vielen möglichen Gründe dafür: Keine Lust, keine Zeit, kein Internet, keine Möglichkeit mehr weil verstorben etc...
- Sven Rautenberg
Moin.
keine Ahnung ob das Forum jetzt hier ein Scriptarchiv zulässt, ich fände es nicht verkehrt.
Ich halte es für eine schlechte Idee. Das Archiv ist riesig und nicht so wahnsinnig gut durchsuchbar - jedenfalls im Vergleich zu viel besser geeigneteren Orten wie z.B. den Artikeln.
Aber das Forum ist eine gute Anlaufstelle, um Ideen für einen eventuellen Artikel zu sammeln (das soll jetzt noch keine Zusage sein, aber wer weiß - ich spiele derzeit mit dem Gedanken, etwas über Maps in JavaScript zu schreiben - eine englische Version gibt es bereits).
Christoph
PS: Gibt es eigentlich Pläne, die SELFHTML-Artikel (eventuell zur Veröffentlichung von SELFHTML9) neu zu organisieren?
Falls sich die Zahl der JavaScript-Artikel weiter erhöht, ist eine reine Auflistung nach Erscheinungsdatum nicht wirklich benutzerfreundlich...
Christoph
Moin!
PS: Gibt es eigentlich Pläne, die SELFHTML-Artikel (eventuell zur Veröffentlichung von SELFHTML9) neu zu organisieren?
Falls sich die Zahl der JavaScript-Artikel weiter erhöht, ist eine reine Auflistung nach Erscheinungsdatum nicht wirklich benutzerfreundlich...
Vorschläge? Nicht, dass ich irgendwas versprechen würde ;) - aber konkrete Verbesserungsvorschläge helfen meist mehr, als nur "macht das doch mal 'anders'". :)
- Sven Rautenberg
Moin.
Falls sich die Zahl der JavaScript-Artikel weiter erhöht, ist eine reine Auflistung nach Erscheinungsdatum nicht wirklich benutzerfreundlich...
Vorschläge? Nicht, dass ich irgendwas versprechen würde ;) - aber konkrete Verbesserungsvorschläge helfen meist mehr, als nur "macht das doch mal 'anders'". :)
Solange die Zahl der Artikel nicht überhand nimmt, würde ich alle auf einer Seite belassen, aber weitere Kategorien per Überschriften hinzufügen.
Am Anfang des Dokuments sollte eine (ebenfalls in Kategorien unterteilte) Link-Liste zu den entsprechenden Detaileinträgen stehen.
Eine konkrete Kategorisierung der JavaScript-Artikel erweist sich auf Grund der Diversität der Artikel als nicht einfach. Der folgende Vorschlag hat daher eher den Charakter eines 'proof-of-concept':
Sprache
Objekt-Handling in JavaScript
Objektabfragen und Fallunterscheidungen in JavaScript
Tabellen
Eigenes table-Objekt in JavaScript
Datensatzauswahl aus Tabelle mit Fullrowselect
Tabellen dynamisch sortieren
Übergroße Tabellen in koordiniert scrollenden Frames
Frames & Fenster
Datei dynamisch in Frameset laden
Fenster- und Frameszugriff
"Auflösungsweiche": Weiterleitung in Abhängigkeit der Fenstergröße
Formulare
Formulare: Text an Cursorposition einfügen
E-Mail-Syntax überprüfen
Formularauswertung
Algorithmen & Datenstrukturen
MD5-Hashing mit JavaScript
Datumsüberprüfung
Verkettete Auswahllisten
Gleichverteilte Zufallszahlen erzeugen
DHTML
Positionierung von Layern (DHTML)
Drag and Drop
Aufklappbare Menüs
Typographische Korrekturen
Text automatisch markieren
spezielle Anwendungen
Sitemap mit JavaScript und Layers
Auf Dateien mit JavaScript zugreifen
JavaScript Diagram Builder
Datenbanken mittels JavaScript nutzen
Javascript-Wertübergabe zwischen HTML-Dokumenten
Helferlein
HelferleinScript "Debug-Infos"
Bookmarklets
Komfortable Timer-Funktion
Bibliotheken
JavaScript Square Matrix Library
Lehrgänge
Fader-Framework - kleiner Lehrgang zum vernünftigen Schreiben eines JavaScripts
Organisation von JavaScripten
Christoph
Am Anfang des Dokuments sollte eine (ebenfalls in Kategorien unterteilte) Link-Liste zu den entsprechenden Detaileinträgen stehen.
Wenn ich es mir recht überlege, sollte die Link-Liste eventuell doch nur Verweise zu den Kategorien enthalten - die Liste wird sonst zu lang, um wirklich nützlich zu sein...
Christoph
Moin!
Falls sich die Zahl der JavaScript-Artikel weiter erhöht, ist eine reine Auflistung nach Erscheinungsdatum nicht wirklich benutzerfreundlich...
Vorschläge? Nicht, dass ich irgendwas versprechen würde ;) - aber konkrete Verbesserungsvorschläge helfen meist mehr, als nur "macht das doch mal 'anders'". :)
Solange die Zahl der Artikel nicht überhand nimmt, würde ich alle auf einer Seite belassen, aber weitere Kategorien per Überschriften hinzufügen.
Tja, ein Gegenargument wäre halt: Das Erscheinungsdatum eines Artikels ist schon durchaus relevant zur Bewertung, wie sinnvoll der dargestellte Inhalt sich heutzutage noch anwenden läßt.
Zweites Argument: Die Artikel lassen sich mit unserer Suchmaschine auch ganz rasch durchsuchen, wenn man das Feld links unter dem Logo ausfüllt. -- Das allerdings ist zurecht als absolut unintuitiv kritisierbar, und das Resultat auf der Ergebnisseite hat Probleme mit UTF-8 vs. ISO-8859-1 (jaja, so viele Dinge zu tun, so wenig Zeit...).
Am Anfang des Dokuments sollte eine (ebenfalls in Kategorien unterteilte) Link-Liste zu den entsprechenden Detaileinträgen stehen.
Eine konkrete Kategorisierung der JavaScript-Artikel erweist sich auf Grund der Diversität der Artikel als nicht einfach. Der folgende Vorschlag hat daher eher den Charakter eines 'proof-of-concept':
Ganz ehrlich: Im Moment fühle ich nicht, dass sich jemand vom Redaktionsteam berufen fühlt und die Zeit aufbringen kann, in den Quelldateien und dem die Übersichten generierenden PHP-Skript derart einzugreifen, dass so eine alternative Übersicht entsteht.
Allerdings heißt das ja nicht, dass deshalb niemand die Arbeit machen kann. Deshalb: Wer sich in das Problem reinfuchsen will, kriegt gerne die Quelldateien von mir als ZIP zum werkeln (PHP läuft als Kommandozeilenskript), kann seine Änderungen zurückschicken, und ich check' kurz durch, ob das auch alles auf dem Server funktioniert. Bei Interesse: Mail an svenr@selfhtml.org.
- Sven Rautenberg
Hi,
Falls sich die Zahl der JavaScript-Artikel weiter erhöht, ist eine reine Auflistung nach Erscheinungsdatum nicht wirklich benutzerfreundlich...
Vorschläge?
Tagging :-)
SELFHTML-9.0-ZweiPunktNull.
MfG ChrisB
Hallo,
Vorschläge?
Die Einträge baumartig sortieren
mfg, Flo
Hi Sven,
Aber ich schreibe dennoch mal aus einem anderen Grund. Bei deinem Nick fällt mir auf, das ein schreibfreudiger Stammposter namens "Christoph Schnauß" seit einem halben Jahr nichts mehr schreibt, weiss Jemand warum?
Nein, keiner weiß das. Denk dir einfach irgendeinen der vielen möglichen Gründe dafür: Keine Lust, keine Zeit, kein Internet, keine Möglichkeit mehr weil verstorben etc...
brrrrr, was ist das denn? Ich muss zugeben, das meine Frage nicht unbegründet kommt, ich hatte den Eindruck bei diversen Postings von Christoph einen leisen Hilferuf nach Aufmerksamkeit zu vernehmen, und dacht schon sowas kann leicht suizidgefärdet gelten. Falls ich micht irre und du liest das Christoph, nichts für ungut, ist ja nur Theorie.
Aber das von euch keiner etwas weiss und auch offensichtlich nicht interessiert, verstehe ich nicht. Ihr unternehmt Sachen zusammen(Selftreffen) kennt euch schon jahrelang und dann interessiert euch sowas nicht besonders?
Paul
Moin,
Aber das von euch keiner etwas weiss und auch offensichtlich nicht interessiert, verstehe ich nicht. Ihr unternehmt Sachen zusammen(Selftreffen) kennt euch schon jahrelang und dann interessiert euch sowas nicht besonders?
Christophs hat eine sehr eigene Art, zu sein. Das macht es sicher nicht leicht, dauerhaft mit ihm "auf einer Welle" zu sein. Ich sage das ganz wertfrei; ich bin nie mit ihm "zusammengerasselt".
Er hat übrigens einen Telefonbucheintrag.
Grüße
Swen
Hi,
Er hat übrigens einen Telefonbucheintrag.
ja nur stand ich nie, im Gegensatz zu vielen anderen hier, im Kontakt zu Ihm. Aber wenn es kein anderer versucht, habe ich angerufen und es kam nur der AB. Ich habe drauf gesprochen er möchte doch mal bitte kurz etwas dazu schreiben. Bin gespannt.
Paul
Hi,
Nein, keiner weiß das. Denk dir einfach irgendeinen der vielen möglichen Gründe dafür: Keine Lust, keine Zeit, kein Internet, keine Möglichkeit mehr weil verstorben etc...
noch viel wahrscheinlicher: weil bei der Herstellung von Hollunderwein oder bei dessen artgerechter Vernichtung ;-)
cu,
Andreas
noch viel wahrscheinlicher: weil bei der Herstellung von Hollunderwein
blausäurevergiftung? :p
[latex]Mae govannen![/latex]
Diejenigen von euch, die sich seit längerem mit JavaScript herumschlagen mussten, habe sich mit der Zeit eventuell eine eigene Bibliothek von Skripten zugelegt.
Ich würde gerne sehen, was sich bei anderen so angesammelt hat. Dabei sollten die Skripte
Ich fange trivial an:
Aufgrund der fehlerhaften Arbeitsweise von typeof nutze ich folgende Funktionen:
function isObject(o) {
return (typeof o === 'object' && !(o instanceof Array) && o !== null);
}
function isArray(a) {
return (typeof a === 'object' && a instanceof Array);
}
Dann eine Array-Mischfunktion hier aus dem Forum
Array shuffle
Funktionen, um events hinzuzufügen / entfernen (glaube von molily im forum gepostet, leicht angepasst; habe leider keinen Thread-Verweis gespeichert)
function addEvent(obj, ev_type, fn) {
if (!obj || typeof ev_type !== "string" || typeof fn !== "function") {
return;
}
if (obj.addEventListener) {
obj.addEventListener(ev_type, fn, false);
}
else if (obj.attachEvent) {
obj.attachEvent('on' + ev_type, function() {
return fn.call(obj, window.event);
});
}
}
function removeEvent(obj, ev_type, fn) {
if (!obj || typeof ev_type !== "string" || typeof fn !== "function") {
return;
}
if (obj.removeEventListener) {
obj.removeEventListener(ev_type, fn, false);
}
else if (obj.detachEvent) {
obj.detachEvent('on' + ev_type, obj[ev_type + fn]);
obj[ev_type + fn] = null;
}
}
Ladefunktion, die eine Funktion auszuführt, sobald das Dokument verfügbar ist oder auf window.onload zurückfällt
function ondomcontent(func) {
/* Inspiriert von Dean Edwards/Matthias Miller/John Resig
http://dean.edwards.name/weblog/2006/06/again/#comment5338 */
var wol = window.onload;
/* Mozilla/Opera/... */
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", func, false);
}
/* Internet Explorer */
/*@cc_on @*/
if (/*@_win32 !== @*/false) {
document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
var script = document.getElementById("__ie_onload");
script.onreadystatechange = function () {
if (this.readyState === "complete") {
func(); // call the onload handler
}
};
}
/* Safari */
if (/WebKit/i.test(navigator.userAgent)) { /* sniff WebKit */
wk_timer = setInterval(function () {
if (/loaded|complete/.test(document.readyState)) {
func(); /* call the onload handler */
}
}, 10);
}
/* for other browsers */
if (typeof wol == "function") {
window.onload = function() {
wol();
func();
}
}
else {
window.onload = func;
}
}
Inhalt des Value-Attributes ermitteln
/** getElementValue(el)
* Internet-Explorer gibt z.B. bei Buttons nicht den Wert des Value-Attributes zurück, wenn das
* Button-Element einen Inhalt hat. In diesem Fall wird versucht, über eine RegExp den Inhalt des
* Value-Attributes aus outerHTML zu ermitteln.
* @param object el Referenz auf das Element, dessen Value-Wert ermittelt werden soll
* @return mixed Wert des Value-Attributes oder bei Mißerfolg der ursprüngliche Wert
*/
function getElementValue(el) {
if (el && el.value) {
if (el.value == el.innerHTML) {
var v = el.outerHTML.match(/value=\"(.+?)\"/i);
if (v && v[1]) return v[1];
}
return el.value;
}
return null;
}
Kai
Aufgrund der fehlerhaften Arbeitsweise von typeof nutze ich folgende Funktionen:
function isObject(o) {
return (typeof o === 'object' && !(o instanceof Array) && o !== null);
}
function isArray(a) {
return (typeof a === 'object' && a instanceof Array);
}
Warum ist das `typeof a` in `isArray()` notwendig? Meiner Meinung nach könnte man auch `typeof o === 'object' && o !== null` zu `o instanceof Object` zusammenfassen.
> Funktionen, um events hinzuzufügen / entfernen (glaube von molily im forum gepostet, leicht angepasst; habe leider keinen Thread-Verweis gespeichert)
> [...]
Habe ich auch (fast genauso) im Einsatz als Alternative zur `capture()`-Funktion. Diese ist vom Performance-Standpunkt aus ein Alptraum, aber einfach zu praktisch, um darauf zu verzichten. Statt auf das Laden des DOM-Baums zu warten, passende Elemente zu suchen und jedem einzeln Ereignis-Handler hinzuzufügen, erlaubt es `capture()`, eine kleine Testfunktion zu schreiben und den Handler einmalig global bekanntzumachen.
> Ladefunktion, die eine Funktion auszuführt, sobald das Dokument verfügbar ist oder auf window.onload zurückfällt
> [...]
Siehe `onready()`. Ich habe auch eine Version, die zunächst versucht, ein 'DOMContentLoaded' Ereignis zu setzen und im IE auf 'onreadystatechange' zurückgreift. Das garantiert, dass die Funktionen /vor/ allen 'onload'-Handlern ausgeführt werden. In der Praxis war das aber nicht wirklich nötig, daher die verkürzte Variante.
> Inhalt des Value-Attributes ermitteln
> [...]
Über diese Problematik bin ich bisher noch nicht gestolpert. Gut zu wissen!
Christoph
[latex]Mae govannen![/latex]
function isObject(o) {
return (typeof o === 'object' && !(o instanceof Array) && o !== null);
}
function isArray(a) {
return (typeof a === 'object' && a instanceof Array);
}
>
> Warum ist das `typeof a` in `isArray()` notwendig?
Nicht. Kommt, weil ich die Objekt-Funktion "ge-c&p't" habe und nur den hinteren Bereich angepasst habe :(
> Meiner Meinung nach könnte man auch `typeof o === 'object' && o !== null` zu `o instanceof Object` zusammenfassen.
Prinzipiell schon, aber:
~~~javascript
var c = {
a: 2,
b: 3
}
function T1() {
this.a = 4;
}
b = new T1()
alert( c instanceof Object)
alert( b instanceof Object)
alert( window instanceof Object)
alert(isObject(c))
alert(isObject(b))
alert(isObject(window))
~~~ ergibt im IE6 true true false true true true , im FF/Opera 6 \* true
Cü,
Kai
--
Ash nazg durbatulûk, ash nazg gimbatul,ash nazg thrakatulûk, agh burzum-ishi krimpatul
selfcode sh:( fo:| ch:? rl:( br:< n4:# ie:{ mo:| va:) js:) de:> zu:) fl:( ss:| ls:?
Moin.
> alert( c instanceof Object)
> alert( b instanceof Object)
> alert( window instanceof Object)
> alert(isObject(c))
> alert(isObject(b))
> alert(isObject(window))
ergibt im IE6 true true false true true true , im FF/Opera 6 * true
Sicher?
javascript:void(alert((typeof window) + ' ' + (window instanceof Object)))
in der Adresszeile gibt in meinem FF3.0.5 'object false'...
Christoph
PS: Was der typeof des Host-Objekts ist, ist übrigens 'implementation-dependent'
[latex]Mae govannen![/latex]
Sicher?
javascript:void(alert((typeof window) + ' ' + (window instanceof Object)))
in der Adresszeile gibt in meinem FF3.0.5 'object false'...
Im FF 2.0.0.20 'object true'
Cü,
Kai
Moin.
Dass window instanceof Object === false
scheint ein Bug zu sein, denn window.\_\_proto\_\_ instanceof Object === true
.
Genauer:
alert(window.\_\_proto\_\_)
ergibt '[xpconnect wrapped native prototype]'
alert(window.\_\_proto\_\_.\_\_proto\_\_)
ergibt '[object Global Scope Polluter]'
alert(window.\_\_proto\_\_.\_\_proto\_\_.\_\_proto\_\_)
ergibt '[object Object]'
Und window.\_\_proto\_\_.\_\_proto\_\_.\_\_proto\_\_ === Object.prototype
ist true
. Also ist Object.prototype
Teil der [[Prototype]]-Kette von window
.
Blöder Firefox ;)
Christoph
[latex]Mae govannen![/latex]
Dann eine Array-Mischfunktion hier aus dem Forum
Array shuffle
… die mich gerade _extrem_ geärgert hat, da sie keine Referenz auf das Array zurückgibt. Aber bis ich mal auf die Idee gekommen bin, daß es an shuffle liegt und nicht an meinem Code! Wenn man etwas voraussetzt, ist man manchmal blind. *koppschüttel*
function getRandoms(a, num) {
// hier ggf. Validitätsprüfung der Parameter
return a.shuffle().slice(0,num);
}
funktioniert so natürlich nicht.
ein einfaches return this;
am Ende der shuffle-Funktion eingefügt und schon geht's
Cü,
Kai
Hallo Kai345,
Dann eine Array-Mischfunktion hier aus dem Forum
Array shuffle… die mich gerade _extrem_ geärgert hat, da sie keine Referenz auf das Array zurückgibt. ...
so ist das, wenn man Codeschnipsel aus dem Internet benutzt, ohne sie zu verstehen. Ein Blick in den Quellcode hätte dir gezeigt, dass da nichts "returnt" wird. Warum auch, die Funktion wirkt auf das Array.
Gruß, Jürgen
Lieber JürgenB,
dass da nichts "returnt" wird. Warum auch, die Funktion wirkt auf das Array.
ist es nicht bei anderen (nativen) Array-Funktionen so, dass sie ein Array als Rückgabewert liefern? Insofern wäre es nur recht und billig, eine entsprechende Rückgabe zu erwarten. Von daher hätte ich auch ein return this
erwartet oder dann selbst ergänzt.
Wieso genügt es Dir in diesem Falle, gerade keinen Rückgabewert zu erhalten? Wie verwendest Du denn diese Funktion?
Liebe Grüße,
Felix Riesterer.
Moin.
Wieso genügt es Dir in diesem Falle, gerade keinen Rückgabewert zu erhalten? Wie verwendest Du denn diese Funktion?
Die verlinkte shuffle-Funktion vertauscht die Elemente des als this
zur Verfügung gestellten Arrays, erzeugt also keinerlei neue Objekte. Die Rückgabe irgendeinen Werts ist damit nicht erforderlich.
Der einzige Grund, warum ein return this
sinnvoll sein könnte, ist, die Verkettung von Methodenaufrufen zu ermöglichen...
Christoph
[latex]Mae govannen![/latex]
ist es nicht bei anderen (nativen) Array-Funktionen so, dass sie ein Array als Rückgabewert liefern? Insofern wäre es nur recht und billig, eine entsprechende Rückgabe zu erwarten. Von daher hätte ich auch ein
return this
erwartet oder dann selbst ergänzt.
Leider nicht alle Funktionen. Am ähnlichsten zu shuffle() wäre wohl reverse(), dort gibt es auch keinen Rückgabewert. Man muß dort auch [1,2,3,4,5].reverse();
schreiben und nicht var newArray = [1,2,3,4,5].reverse();
Insofern ist es schon verständlich, die Funktion ohne Rückgabewert zu schreiben. Die Verwirrung kam durch etwas anderes, siehe anderer Beitrag meinerseits
Cü,
Kai
Hallo Felix,
Wieso genügt es Dir in diesem Falle, gerade keinen Rückgabewert zu erhalten? Wie verwendest Du denn diese Funktion?
ich mische die Arrays (in einem Spiel) sehr oft und spare mir so das Anlegen von immer neuen Arrays. Das Originalarray benötige ich nicht. Das "oberste" Entwicklungsziel war neben der Funktionalität die Geschwindigkeit.
Gruß, Jürgen
[latex]Mae govannen![/latex]
so ist das, wenn man Codeschnipsel aus dem Internet benutzt, ohne sie zu verstehen.
Wie nett. Aber es wäre natürlich viel zu einfach gewesen, sich erst einmal über den konkreten Hintergrund zu informieren, bevor man Anderen etwas unterstellt.
Ein Blick in den Quellcode hätte dir gezeigt, dass da nichts "returnt" wird.
Und die shuffle-Funktion, die ich früher benutzt habe, tut genau dieses. Insofern bestand eine implizite, wenn auch falsche Erwartungshaltung. Natürlich hätte ich nachsehen sollen, da ich aber aus dieser Gewohnheit fest davon überzeugt war, daß eine Rückgabe stattfinden wird, habe ich es nicht getan. Kein Grund, beleidigend zu werden.
Warum auch, die Funktion wirkt auf das Array.
Ach.
Kai
Aufgrund der fehlerhaften Arbeitsweise von typeof nutze ich folgende Funktionen:
function isObject(o) {
return (typeof o === 'object' && !(o instanceof Array) && o !== null);
}
function isArray(a) {
return (typeof a === 'object' && a instanceof Array);
}
Bei diesen Funktionen solltest du aber bedenken, dass sie nicht funktionieren, wenn die Arrays aus anderen Frames, Tabs oder Fenstern stammen, `a instanceof Array`{:.language-javascript} ist dann `false`{:.language-javascript}.
--
Reden ist Silber, Schweigen ist Gold, meine Ausführungen sind Platin.
Self-Code: sh:( ch:? rl:( br:> n4:( ie:{ mo:) va:) de:> zu:} fl:| ss:| ls:~ js:|
Moin.
Die jeweils aktuelle Version der JavaScript-Schnipsel gibt es jetzt als Mercurial-Repository.
Christoph
Moin.
Es gibt jetzt auch die Möglichkeit, sich aus den Schnipsels komfortabel eine eigene Bibliothek zusammenzustückeln.
Der Link zeigt auf die derzeit aktuelle Version. Für neuere Versionen muss der Weg über die Portalseite genommen werden (files->libmaker.html->raw).
Christoph
gruss Christoph, hallo Kai,
... Und jetzt ihr ;)
ich poste mal nur die fuer mich zur zeit immer noch praxisrelevanten eigenloesungen:
unverzichtbar:
* [jsApi.Array.mozExtensions.revisioned.dev-03.js]
* [jsApi.Array.mozExtensions.revisioned.dev-04.js]
Array.prototype.indexOf basierend auf der aelteren [jsApi.Array.mozExtensions.dev.js]
Array.prototype.lastIndexOf
Array.prototype.contains
Array.prototype.forEach
Array.prototype.every
Array.prototype.some
Array.prototype.map
Array.prototype.filter
Array.prototype.reduce
Array.prototype.reduceRight
Array.prototype.defragment
Array.prototype.getDefragmented
Array.prototype.normalize basierend auf der aelteren [jsApi.Array.normalize.dev.js]
Array.prototype.getNormalized
Array.prototype.remove
Array.prototype.indexOfFilter
Array.prototype.lastIndexOfFilter
Array.indexOf basierend auf der aelteren [jsApi.Array.mozGenerics.dev.js]
Array.lastIndexOf
Array.contains
Array.forEach
Array.every
Array.some
Array.map
Array.filter
Array.reduce
Array.reduceRight
Array.getDefragmented
Array.getNormalized
Array.indexOfFilter
Array.lastIndexOfFilter
ebenfalls unverzichtbar:
* [jsApi.EventDispatcher.new.js]
* extrahiert aus [jsApi.EventDispatcher.dev.new.js], der wiederum auf
* dem aelteren [jsApi.EventDispatcher.dev.js] aufsetzt.
... ein immer noch ganz passabler code-steinbruch:
* [jsApi.Object.typeDetection.new.dev.js].
isUndefined
isNull
isValue
isObject
isNative
isAlien
isBoolean
isNumber
isString
isBooleanValue
isNumberValue
isStringValue
isBooleanObject
isNumberObject
isStringObject
isInteger
isFraction
isError
isEvalError ...
...
isURIError
isDate
isRegExp
isFunction
isArray
isArrayLike
isObjectObject
isConstructedObject
isEmpty
...
Object.prototype.isEmpty
... ein bischen spielkram:
* [jsApi.Boolean.ifTrue.ifFalse.dev.js]
fuer alles andere (Node/Element, DOM, DOM-Events) greife ich mittlerweile auf
richtig professionell entwickelte/getestete bibliotheken und frameworks zurueck.
so long - peterS. - pseliger@gmx.net
* [jsApi.Boolean.ifTrue.ifFalse.dev.js]
- Boolean.prototype.ifTrue
- Boolean.prototype.ifFalse
Zu diesen beiden Methoden hätte ich direkt einen Verbesserungsvorschlag: Füge ihnen einen weiteren optionalen Parameter hinzu, der ein Objekt beinhalten kann, in dessen Kontext die übergebene Funktion ausgeführt wird. Also so:
(function (fct, obj){
/* ... */
fct.call(obj);
/* ... */}
gruss "God's Boss",
- Boolean.prototype.ifTrue
- Boolean.prototype.ifFalse
hey, das war doch nur ein 5-minuten spass ...
...
Zu diesen beiden Methoden hätte ich direkt einen Verbesserungsvorschlag:
Füge ihnen einen weiteren optionalen Parameter hinzu, der ein Objekt
beinhalten kann, in dessen Kontext die übergebene Funktion ausgeführt wird.
...
na gut, Du hast ja recht. es liegt tatsaechlich auf der hand, dies zu tun.
done:
/*
[link:http://de.wikipedia.org/wiki/Smalltalk-80_(Programmiersprache)#IF-Anweisung]
*/
[link:http://www.pseliger.de/jsExtendedApi/jsApi.Boolean.ifTrue.ifFalse.dev.js@title=Boolean.prototype.ifTrue] = (function (fct, target/*optional:[object|function]*/) { // [caseTrue], [ifTrue], [ifTrueDo]
var isTrue = this.valueOf();
if (isTrue && (typeof fct == "function")) {
fct.call(((typeof target == "undefined") || ((typeof target == "obj") && !target)) ? (null) : (target));
}
return isTrue;
});
Boolean.prototype.ifFalse = (function (fct, target/*optional:[object|function]*/) { // [caseFalse], [ifFalse], [ifFalseDo]
var isTrue = this.valueOf();
if (!isTrue && (typeof fct == "function")) {
fct.call(((typeof target == "undefined") || ((typeof target == "obj") && !target)) ? (null) : (target));
}
return isTrue;
});
/*
[link:http://jconsole.com]
*/
(7 < 6).ifTrue(function () {
print(" ... is true.");
}).ifFalse(function () {
print(" ... is false.");
});
(7 > 6).ifTrue(function () {
print(" ... is true.");
}).ifFalse(function () {
print(" ... is false.");
});
danke und so long - peterS. - pseliger@gmx.net
hallo again Timo,
na gut, Du hast ja recht. es liegt tatsaechlich auf der hand, dies zu tun.
... wenn man dann aber schon so weit ist, faellt mir auf und ein, das der
ganze kram konsequenterweise auch gleich mit einem vezicht auf benutzung
von »if ( .. ) { ... } else { ... } « umgesetzt werden sollte.
done:
also nochmal:
/*
[link:http://de.wikipedia.org/wiki/Smalltalk-80_(Programmiersprache)#IF-Anweisung]
*/
[link:http://www.pseliger.de/jsExtendedApi/jsApi.Boolean.ifTrue.ifFalse.dev.js@title=Boolean.prototype.ifTrue] = (function (fct, target/*optional:[object|function]*/) { // [caseTrue], [ifTrue], [ifTrueDo]
return (((this.valueOf() && (typeof fct == "function")) ? (function () {fct.call(((typeof target == "undefined") || ((typeof target == "obj") && !target)) ? (null) : (target)); return true;}) : (function () {return false;}))());
});
Boolean.prototype.ifFalse = (function (fct, target/*optional:[object|function]*/) { // [caseFalse], [ifFalse], [ifFalseDo]
return (((!this.valueOf() && (typeof fct == "function")) ? (function () {fct.call(((typeof target == "undefined") || ((typeof target == "obj") && !target)) ? (null) : (target)); return true;}) : (function () {return false;}))());
});
/*
[link:http://jconsole.com]
*/
(7 < 6).ifTrue(function () {
print(" ... is true.");
}).ifFalse(function () {
print(" ... is false.");
});
(7 > 6).ifTrue(function () {
print(" ... is true.");
}).ifFalse(function () {
print(" ... is false.");
});
so long - peterS. - pseliger@gmx.net
Moin.
... ein immer noch ganz passabler code-steinbruch:
Ziemlich beeindruckend, deine Typerkennung. Nach Lesen dieses Artikels habe ich mir auch eine eigene Version einer typeOf
-Funktion zusammengeschustert:
function typeOf(value) {
var type = typeof value;
if(type === 'object') {
return value === null ? 'null' : Object.prototype.toString.call(value).
match(arguments.callee.regex)[1];
}
else return type;
}
typeOf.regex = /^\[(.*)\]$/;
Diese Funktion sollte es unter anderem ermöglichen, Arrays auch über Fenstergrenzen hinweg zu erkennen (der instanceof
-Operator versagt hier).
Der Rückgabewert ist bei nicht-Objekten identisch mit typeof
, bei Objekten setzt er sich zusammen aus 'object ' gefolgt von der [[Class]]-Eigenschaft ('Array', 'String', 'Number', ...).
null
wird extra behandelt und liefert 'null'.
Christoph
Hi,
try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
Alles überflüssig.
try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
Das ist der einzig notwendige Aufruf.
MS bleibt i.d.R. abwärtskompatibel, und neuere IEs brauche das ja eh nicht mehr (es wird sich also auch in Zukunft nicht mehr ändern).
Gruß, Cybaer
Moin.
try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
Das ist der einzig notwendige Aufruf.
Ist das sicher? Ich meine, dass mit dieser Version einige IE-Versionen Probleme (mit synchronen Anfragen, war es glaube ich?) hatten.
Vielleicht trügt mich da aber auch mein Gedächtnis...
Christoph
Hi,
Ist das sicher?
Was ist beim IE schon "sicher"? >;->
Ich meine, dass mit dieser Version einige IE-Versionen Probleme (mit synchronen Anfragen, war es glaube ich?) hatten.
Ist mir nicht bekannt. Aber wenn Du das verifizieren könntest, dann schrei ruhig nochmal "Hallo!". ;-)
Gruß, Cybaer