Image Load Event in IE

Geschrieben in javascript von natalia am 15 Dezember 2011

In einer kleinen Animation mit jQuery sollen bestimmte Aktionen ausgeführt werden, wenn Bilder geladen sind. Dazu habe ich ein Image Load Event verwendet:

$image1 = $('<img />').attr('src', circle1Img).attr('width', 250).attr('height', 250).
load( function() {
	$('#animation .circle-1 .image').html('');
	$('#animation .circle-1 .image').append($(this));
});

Das hat auch wunderbar funktioniert, außer im IE8 (vermutlich auch IE7), wobei sich der IE8 im Legacy Mode korrekt verhält. Wie meine Recherche ergab, wird das Load Event vorzeitig gefeuert, weil das Bild aus dem Browser-Cache geladen wird. Das ist aber nur im IE so (wen wundest es eigentlich noch). Ein Lösung fand ich im Blog von David Walsh. Damit es auch im IE funktioniert, muss das src-Attribut erst gesetzt werden, wenn das Load Event definiert ist:

$image1 = $('<img />').attr('src', circle1Img).attr('width', 250).attr('height', 250).
load( function() {
	$('#animation .circle-1 .image').html('');
	$('#animation .circle-1 .image').append($(this));
});
$image1.attr('src', circle1Static);

Das Problem tritt natürlich nicht auf, wenn man die Bilder nicht aus dem Cache lädt:

var circle1Img = 'fileadmin/templates/img/animcircle_01.gif?' + Math.floor(Math.random()*10000);

Weiter-Button in verschachtelten Tabs

Geschrieben in javascript von natalia am 9 August 2011

In verschachtelten Tabs, die mit jQuery erstellt wurden, sollte eine Navigation mittels Weiter-Button umgesetzt werden. Für einfache Tabs habe ich einige Beispiele gefunden:
jQuery UI Tabs with Next/Previous oder jQuery Tabs Next Button. Allerdings sind in diesem Fall die Tabs verschachtelt. d.h. innerhalb von Tabs befinden sich wiederum Tabs: Tab A enthält Tabs A1, A2 und A3, Tab B enthält B1, B2 und B3 und C hat keine Subtabs. Wenn man also in A3 angekommen ist, sollte der Weiter-Button zu B1 verweisen. Weiterhin sollte die normale Tab-Navigation (also das Anklicken der Tab-Titel) weiterhin funktionieren. Wenn man also den Tab A2 auswählt, sollte der Weiter-Button immer noch auf A3 springen lassen.

<div id="tab">
	<ul>
		<li><a href="#tab-a">A</a></li>
		<li><a href="#tab-b">B</a></li>
		<li><a href="#tab-c">C</a></li>
	</ul>
	<div id="tab-a">
		<ul>
			<li><a href="#tab-a1">A1</a></li>
			<li><a href="#tab-a2">A2</a></li>
			<li><a href="#tab-a3">A3</a></li>
		</ul>
		<div id="a1">
			Inhalt A1
		</div>
		<div id="a2">
			Inhalt A2
		</div>
		<div id="a3">
			Inhalt A3
		</div>
	</div>
	<div id="tab-b">
		<ul>
			<li><a href="#tab-b1">B1</a></li>
			<li><a href="#tab-b2">B2</a></li>
			<li><a href="#tab-b3">B3</a></li>
		</ul>
	</div>
	[... usw]
</div>

Ich habe einen Button implementiert, der sich außerhalb der Tabs befindet. Damit eine Navigation möglich ist, müssen die Tab-Objekte gespeichert werden:

var $firstLevel = $('#tabs').tabs();	
var counter = 0;
$('#tabs .tabbed').each( function(index, elem) {
	var cid = $(elem).parent().attr('id');
	tabObjects[counter] = $(elem).tabs();
	counter++;
});

Wenn der Weiter-Button geklickt wird, wird ermittelt, welcher Tab der ersten Ebene gerade aktiv ist. Falls es Tabs der zweiten Ebene gibt, wird ermittelt, welcher von denen gerade aktiv ist. Dann wird geprüft, ob auf den Tab der zweiten Ebene Geschwister-Elemente folgen. Wenn ja, dann wird der nächste aktiviert. Wenn nicht, dann wird der nächste Tab der ersten Ebene aktiviert.

$('#next-button a').click( function() {
	var selected = $firstLevel.tabs('option', 'selected');
	var tabId = $('#tabs > div').eq(selected).attr('id');
	$subTab = tabObjects[selected];
 
	var length = $firstLevel.tabs('length');
	if($subTab != undefined) {
		var subSelected = $subTab.tabs('option', 'selected');
		var subLength = $subTab.tabs('length');
		if(subSelected + 1 < subLength) {
			/*
			 * switch to next tab
			 */
			$subTab.tabs('select', subSelected + 1);
		} else if(selected + 1 < length) {
			/*
			 * switch no next parent tab
			 */
			$firstLevel.tabs('select', selected + 1);
			if(length == selected + 2) {
				$(this).hide();
			}
			$subTab = tabObjects[selected + 1];
			if($subTab != undefined) {
				$subTab.tabs('select', 0);
			}
		}
	} else {
		$firstLevel.tabs('select', selected + 1);
	}
});

jQuery: Tinyscrollbar innerhalb von Tabs

Geschrieben in javascript von natalia am 3 August 2011

Wenn man das jQuery Plugin Tiny Scrollbar für Inhalte eines Tabs verwendet, dann wird die Höhe des Elements nicht korrekt berechnet und die Funktionalität nicht gesetzt. Eine Erklärung dafür gibt es auf der jQuery Tabs-Seite: der Tab-Inhalt ist versteckt, daher können die Dimensionen nicht berechnet werden.
Man kann den Tiny Scrollbar aber aktivieren, wenn der Tab (vorausgesetzt es ist nicht der erste und sichtbare) sichtbar wird.

$('#tabs').bind('tabsshow', function(event, ui) {
	if (ui.panel.id == "tab1") {
		$('#content1').tinyscrollbar();
	} else if(ui.panel.id == "tab2") {
		$('#content2').tinyscrollbar();
	}
});

JavaScript-Meldungen in der Firebug Konsole ausgeben

Geschrieben in javascript von natalia am 28 Januar 2011

Das ist eine kleine Funktion, die das Leben und Programmieren viel einfacher macht. Falls man Firebug installiert hat, kann man mit console.log(nachricht) im JavaScript-Code eine Nachricht in der Firebug-Konsole ausgeben.

Erweiterung jQuery Carousel

Geschrieben in javascript von natalia am 18 Januar 2011

Ich wollte das jQuery-Carousel, das auf dieser Seite mit vielen schönen Beispielen vorgestellt wird, ein wenig anpassen, und zwar sollte es mehr möglichkeiten geben, die Buttons und die Paginierung zu positionieren, als bisher. So sollte es möglich sein, dass die Prev/Next-Buttons um die Paginierung herum gepackt werden können.
jQuery Carousel
Als erstes habe ich für den Parameter btnsPosition weitere Optionen hinzugefügt: after, paginationOutside und paginationInside. Bei after werden die Buttons beide hinter das Carousel gepackt, bei paginationOutside werden die Buttons direkt vor und hinter die Paginierung gepackt und bei paginationInside vor und hinter die Paginierung, allerdings innerhalb des umschließenden Divs.

if(params.btnsPosition == "after") {
	params.prevBtnInsert = "insertAfter";
	params.nextBtnInsert = "insertAfter";
}
if(params.btnsPosition == "paginationOutside") {
	params.prevBtnInsert = "insertBefore";
	params.nextBtnInsert = "insertAfter";
	params.btnsPosition = "pagination";
}
if(params.btnsPosition == "paginationInside") {
	params.prevBtnInsert = "prepend";
	params.nextBtnInsert = "append";
	params.btnsPosition = "pagination";
}
// Prev Button
if ($.isFunction(env.params.prevBtnInsertFn)) {
	env.$elts.prevBtn = env.params.prevBtnInsertFn(env.$elts);
} else { 
	if(env.params.pagination && params.btnsPosition == "pagination") {
		env.$elts.prevBtn = $(params.prevBtn)[params.prevBtnInsert](env.$elts.pagination);
	} else if (params.btnsPosition == "outside"){
		env.$elts.prevBtn = $(params.prevBtn)[params.prevBtnInsert](env.$elts.carousel);
	} else {
		env.$elts.prevBtn = $(params.prevBtn)[params.prevBtnInsert](env.$elts.wrap);
	}
}
 
// Next Button
if ($.isFunction(env.params.nextBtnInsertFn)) {
	env.$elts.nextBtn = env.params.nextBtnInsertFn(env.$elts);
} else {
	if(env.params.pagination && params.btnsPosition == "pagination") {
		env.$elts.nextBtn = $(params.nextBtn)[params.nextBtnInsert](env.$elts.pagination);
	} else if (params.btnsPosition == "outside"){
		env.$elts.nextBtn = $(params.nextBtn)[params.nextBtnInsert](env.$elts.carousel);
	} else {
		env.$elts.nextBtn = $(params.nextBtn)[params.nextBtnInsert](env.$elts.wrap);
	}
}

Die letzten beiden Optionen werden nur dann ausgewertet, wenn die Paginierung an ist.

jQuery Validation

Geschrieben in javascript von natalia am 13 September 2010

Um Formulare Client-seitig zu validieren, gibt es ein Plugin für jQuery: jQuery Validation

Damit ist es möglich, Formulare vor dem Absenden fast automatisch zu validieren, die Ausgabe der Fehlermeldungen kann auch gesteuert werden. Außerdem ist es möglich, eigene Validierungsfunktionen hinzuzufügen. Hier sind die Beispiele, nach denen ich länger suchen musste.

Validieren eines Felder in Abhängigkeit eines anderen:
Das Feld number_nights ist nur dann obligatorisch, wenn die Checkbox ‘checkbox’ angekreuzt ist.

$("#dateForm").validate({
  rules: {
    "data[number_nights]" : {
      required: function() {
        return $('#checkbox').is(":checked");
      },
      min: 1,
      digits: true
    },

Definieren einer eigenen Validierungsfunktion:
Die Felder number_singlerooms und number_doublerooms sind beide obligatorisch und dürfen nur Zahlen (digits) enthalten. Dadurch ist aber nicht sichergestellt, dass in Summe mindenstens 1 rauskommt, daher definiere ich eine eigene Validierungsfunktion und weise sie den Feldern hinzu.

jQuery.validator.addMethod("minNumberRooms", function(value, element) {
  var sumRooms = $('#field_number_singlerooms').val() + $('#field_number_doublerooms').val();
  return this.optional(element) || (sumRooms > 0);
}, "Bitte wählen Sie mindesten ein Zimmer");
 
$("#dateForm").validate({
  rules: {
    "data[number_singlerooms]" : {
      required: true,
        digits: true,
        minNumberRooms : true
      },
      "data[number_doublerooms]" : {
        required: true,
        digits: true,
      minNumberRooms : true
    },

Quelle: http://stackoverflow.com/questions/241145/jquery-validate-plugin-how-to-create-a-simple-custom-rule

Linksammlung JavaScript

Geschrieben in javascript von natalia am 10 September 2010

jQuery Plugins

  • Color Box: die jQuery Alternative zu Lightbox (die auf Prototype basiert), sehr einfach anzuwenden
  • Confirm: eine Bestätigungsfunktion, dabei taucht neben einem Link zum Löschen die Abfrage auf, mit der man die auszuführende Aktion bestätigt
  • Numeric Stepper: kleines Eingabefeld, versehen mit Button, ermöglicht das erhöhen/verringern eines Wertes um einen vorher angebenen Wert (Schritweite), kennt man als Flex-Komponente

Hintergrund Bilder Caching im IE erzwingen

Geschrieben in javascript von natalia am 18 November 2009

Im IE werden die Hintergrundbild unter bestimmten Umständen nicht gecached, was bei einer Seite, die z.B. AJAX verwendet, dazu führen kann, dass der Hintergrund erst später geladen wird, oder weitere Hintergründe fehlen. Die “Lösung” ist dieses kleine Skript, was im IE tatsächlich zu einer Verbesserung führt.

  1. <script type="text/javascript">
  2.     try {
  3.         document.execCommand('BackgroundImageCache', false, true);
  4.     } catch(e) {
  5.         // nothing todo
  6.     }
  7. </script>

Allerdings habe ich nach dem Schnipsel erneut gesucht und noch weitere Ausführungen gefunden:
http://ajaxian.com/archives/no-more-ie6-background-flicker

JavaScript-Fehler in sr_feuser_register 2.5.21

Geschrieben in javascript,typo3 von natalia am 7 April 2009

In der letzten Version von sr_feuser_register wird ein JavaScript-Fehler gemeldet, wenn man ein Formular, dass MD5-Verschlüsselte Felder enthält (Passwort und Wiederholung) absendet. Der Fehler besteht darin, dass die Funktion (vielleicht wegen der Übersichtlichkeit) boolsche Werte groß geschrieben (als FALSE und TRUE) zurückgeben. Diese sind somit in JavaScript keine reservierten Wörter und werden als Variablen interpretiert. Die Lösung ist eigentlich ganz einfach – in der Klasse class.tx_srfeuserregister_marker.php nach FALSE suchen und in den zwei Funktion klein schreiben. Ich habe allerdings immer ein blödes Gefühl beim Patchen von Extensions.

Probleme mit upload_progress mit PHP

Geschrieben in default,javascript von natalia am 15 Oktober 2008

Ich hatte mal über Fileupload mit PHP berichtet:
Simpel mit PHP und mit AJAX

Das Prinzip an sich funktioniert, es gibt nur ein paar Dinge, die man beachten sollte.
Die Funktion zum Abfragen der Dateigröße gibt 0 oder nichts zurück, wenn die Datei, die hochgeladen wird, größer ist als die erlaubte maximale Größe definiert durch php.ini. D.h. wenn diese Grenze gering ist und man versucht eine Datei hochzuladen, die größer ist, gibt es keinen Fortschrittsbalken.
Lösung dafür habe ich noch keine gefunden, das Problem wird in diversen Foren angesprochen, kann aber anscheinend nicht gelöst werden.