Tutorials: JavaScript und AJAX

Dynamisches Imageresize

   
Dieses Script hilft, wenn Bilder mit Übergröße dynamisch verkleinert werden sollen. Es ist sogar in der Lage, die ursprüngliche Größe wiederherzustellen, wenn es gewünscht ist. Es sollen dabei die Größe der verkleinerten Bilder sowie die Option, das Bild in einem neuen Fenster oder im aktiven Fenster zu vergrößern, frei einstellbar sein.

Als ersten Schritt erstellen wir ein neues JavaScript-Dokument imageresize.js. Unsere Funktion nennen wir "imageResize":
function imageResize(maxWidth, maxHeight, targetClass, newWindow) {
}


Als Parameter werden die Angaben für die maximale Breite bzw. Höhe, die zu suchende Klasse und die Option eines neuen Fensters angegeben.

Der Parameter "targetClass" wird benötigt, um die zu verkleinernden Bilder von eventuellen Layoutgrafiken zu unterscheiden. Falls die verkleinert würden, würde wahrscheinlich ein heilloses Chaos über die Struktur der Seite hereinbrechen.

Als nächstes überprüfen wir, ob der letzte Parameter gesetzt wurde und definieren diesen gegebenenfalls. Danach wird eine Schleife initiiert, die alle Bilder der Seite durchläuft:
function imageResize(maxWidth, maxHeight, targetClass, newWindow) {
// Vierten Parameter prüfen
if(imageResize.arguments.length == 3) {
var newWindow = false;
}

// Schleife initiieren
var img = document.images;
for(i = 0; i < img.length; i++) {
}
}


Nun kommt das eigentliche Verkleinern der Bilder an die Reihe: Die if-Blöcke kontrollieren zunächst, ob überhaupt verkleinert werden muss und passen dann Größe der Bilder an:
function imageResize(maxWidth, maxHeight, targetClass, newWindow) {
if(imageResize.arguments.length == 3) {
var newWindow = false;
}

var img = document.images;
for(i = 0; i < img.length; i++) {
// Diese Flag werden wir noch brauchen...
var changed = false;
if(img[i].className == targetClass) {
// Falls die Breite zu groß ist
if(img[i].width > maxWidth) {
img[i].height = maxWidth / img[i].width * img[i].height;
img[i].width = maxWidth;
changed = true;
}
// Falls die Höhe zu groß ist
if(img[i].height > maxHeight) {
img[i].width = maxHeight / img[i].height * img[i].width;
img[i].height = maxHeight;
changed = true;
}
}
}
}


So weit, so gut. Aber schließlich soll der Betrachter ja noch das ganze Bild sehen können, wenn ein Bild bis zur Unkenntlichkeit verkleinert wurde. Dafür brauchen wir zunächst eine neue Funktion: "toggleResize". Sie wird dafür verantwortlich sein, dass die ursprüngliche Größe wiederhergestellt werden kann. Wir brauchen dazu wieder vier Parameter:
function toggleResize(maxWidth, maxHeight, imgIndex, newWindow) {
}


Die ersten zwei und der vierte Parameter sollten selbsterklärend sein. Als neuer Parameter wird "imgIndex" benötigt, der den Index des Bildes liefert. Alle Parameter werden später von "imageResize" übergeben. Nun kommt das Vergrößern der Bilder:
function toggleResize(maxWidth, maxHeight, imgIndex, newWindow) {
var img = document.images[imgIndex];
// Falls das Bild innerhalb der Seite vergrößert werden soll
if(toggleResize.arguments.length == 3 || toggleResize.arguments[3] == false) {
img.width = img.naturalWidth;
img.height = img.naturalHeight;
// oder lieber in einem neuen Fenster
} else {
var winWidth = img.naturalWidth;
var winHeight = img.naturalHeight;
window.open(img.src, img.name, "width=" + winWidth + ",height=" + winHeight);
}
}


Diese Funktion würde soweit schon funktionieren. Allerdings würden vergrößerte Bilder innerhalb einer Seite nicht mehr kleiner gemacht und würden wahrscheinlich alles sprengen, wenn der Code so bliebe. Deshalb muss eine neue Kontrollstruktur her, die überprüft, ob das Bild schon vergrößert wurde, und es dann wieder komprimiert:
function toggleResize(maxWidth, maxHeight, imgIndex, newWindow) {
var img = document.images[imgIndex];
if(toggleResize.arguments.length == 3 || toggleResize.arguments[3] == false) {
// Falls die Breite des Bildes das Maximum höher übersteigt als die Höhe...
if(img.naturalWidth / maxWidth > img.naturalHeight / maxHeight) {
if(img.width > maxWidth) {
img.height = maxWidth / img.width * img.height;
img.width = maxWidth;
} else {
img.width = img.naturalWidth;
img.height = img.naturalHeight;
}
// ansonsten...
} else {
if(img.height > maxHeight) {
img.width = maxHeight / img.height * img.width;
img.height = maxHeight;
} else {
img.width = img.naturalWidth;
img.height = img.naturalHeight;
}
}
} else {
var winWidth = img.naturalWidth;
var winHeight = img.naturalHeight;
window.open(img.src, img.name, "width=" + winWidth + ",height=" + winHeight);
}
}


Diese Funktion ist soweit fertig. Damit sie auch funktioniert, muss sie allerdings auch von aufgerufen werden können. Das schaffen wir, wenn wir in "imageResize" beim Verkleinern einen Link und ein onClick-Event hinzufügen:
function imageResize(maxWidth, maxHeight, targetClass, newWindow) {
if(imageResize.arguments.length == 3) {
var newWindow = false;
}

var img = document.images;
for(i = 0; i < img.length; i++) {
var changed = false;
if(img[i].className == targetClass) {
if(img[i].width > maxWidth) {
img[i].height = maxWidth / img[i].width * img[i].height;
img[i].width = maxWidth;
changed = true;
}
if(img[i].height > maxHeight) {
img[i].width = maxHeight / img[i].height * img[i].width;
img[i].height = maxHeight;
changed = true;
}

// Wenn das Bild überhaupt geändert wurde
if(changed == true) {
// Einen Link hinter dem Image hinzufügen
var clickDiv = document.createElement("div");
clickDiv.innerHTML = "<a href="javascript:toggleResize(" + maxWidth + ", " + maxHeight + ", " + i + ", " + newWindow + ");" >Klicken zum Vergrößern</a>";
img[i].parentNode.insertBefore(clickDiv, img[i].nextSibling);
// Ein onClick-Event definieren
img[i].setAttribute("onclick", "javascript:toggleResize(" + maxWidth + ", " + maxHeight + ", " + i + ", " + newWindow + ")");
// Und ein paar optische Effekte, damit der Betrachter auch sieht, dass das Bild verkleinert wurde ;-)
img[i].style.border = "2px dashed #efefef";
img[i].style.padding = "1px";
}
}
}
}


Nun sieht unser gesamter Code so aus:
function imageResize(maxWidth, maxHeight, targetClass, newWindow) {
if(imageResize.arguments.length == 3) {
var newWindow = false;
}

var img = document.images;
for(i = 0; i < img.length; i++) {
var changed = false;
if(img[i].className == targetClass) {
if(img[i].width > maxWidth) {
img[i].height = maxWidth / img[i].width * img[i].height;
img[i].width = maxWidth;
changed = true;
}
if(img[i].height > maxHeight) {
img[i].width = maxHeight / img[i].height * img[i].width;
img[i].height = maxHeight;
changed = true;
}

if(changed == true) {
var clickDiv = document.createElement("div");
clickDiv.innerHTML = "<a href="javascript:toggleResize(" + maxWidth + ", " + maxHeight + ", " + i + ", " + newWindow + ");" >Klicken zum Vergrößern</a>";
img[i].parentNode.insertBefore(clickDiv, img[i].nextSibling);
img[i].setAttribute("onclick", "javascript:toggleResize(" + maxWidth + ", " + maxHeight + ", " + i + ", " + newWindow + ")");
img[i].style.border = "2px dashed #efefef";
img[i].style.padding = "1px";
}
}
}
}

function toggleResize(maxWidth, maxHeight, imgIndex, newWindow) {
var img = document.images[imgIndex];
if(toggleResize.arguments.length == 3 || toggleResize.arguments[3] == false) {
if(img.naturalWidth / maxWidth > img.naturalHeight / maxHeight) {
if(img.width > maxWidth) {
img.height = maxWidth / img.width * img.height;
img.width = maxWidth;
} else {
img.width = img.naturalWidth;
img.height = img.naturalHeight;
}
} else {
if(img.height > maxHeight) {
img.width = maxHeight / img.height * img.width;
img.height = maxHeight;
} else {
img.width = img.naturalWidth;
img.height = img.naturalHeight;
}
}
} else {
var winWidth = img.naturalWidth;
var winHeight = img.naturalHeight;
window.open(img.src, img.name, "width=" + winWidth + ",height=" + winHeight);
}
}


Jetzt müsste alles funktionieren. Aufgerufen wird es zum Beispiel so:
<html>
<head>
<script type="text/javascript" src="imageresize.js"></script>
</head>

<body onload="imageResize(640, 480, 'contentImage', true);">
<img src="resize.jpg" name="mach mich kleiner" class="contentImage" />
</body>


Viel Spaß damit! ;-)

Ben


Login