Seite abblenden
Kategorie JavaScript
Datum: 07.04.2008, 19:47 - Autor: Manko10
Ein Effekt, den es vor allem in Verbindung mit AJAX-Anwendungen oft zu sehen gibt: plötzlich verdunkelt sich die Seite.Dieses Abblenden der Seite ist an sich eigentlich gar nicht so schwer zu erzeugen, da es sich nur um einen halbtransparenten Layer über der Seite handelt. Wie das geht, erkläre ich in diesem Tutorial.
Zuerst sollte man sich klar machen, welche Programmiertechnik man verwenden will. Eine einfache Funktion? Nein, wir brauchen einen Container, der mehrere Elemente beinhalten kann. Also eine Klasse? Nein auch nicht. Aber es geht schon in die Richtung. Nehmen wir ein Literal. Literale sind Variablen, die Eigenschaften und Methoden beinhalten können, also ein Objekt.
Die Syntax ist dabei ziemlich einfach:
| Code: | ||
|---|---|---|
|
Fangen wir also an und legen zunächst zwei Eigenschaften (oder auch Attribute) fest. Die erste Eigenschaft wird das Layer-Element selbst enthalten, die zweite einen Wert für die maximale Undurchsichtigkeit (ein Wert von 0 = durchsichtig bis 1 = undurchsichtig). Letztere belegen wir mit dem Standardwert 0.7:
| Code: | ||
|---|---|---|
|
Nun fehlen noch die Methoden, welche den Layer erzeugen und einblenden und wieder ausblenden und aus dem Dokument entfernen.
Zunächst die Methode, die das Erzeugen und Löschen des Layers erledigt. Da wir diese Methode für beide Aktivitäten verwenden, muss zunächst geprüft werden, ob der Layer bereits existiert. Ist dies nicht der Fall, wird der Layer neu erzeugt, andernfalls gelöscht.
Auf die dabei verwendeten DOM-Methoden gehe ich nicht ein. Wenn du genaueres dazu wissen willst, benutze bitte eine Suchmaschine deines Vertrauens.
| Code: | ||
|---|---|---|
|
So, bisher merkt man noch recht wenig von diesem Layer, da er noch in keiner Weise formatiert wurde. Holen wir das also nach, indem wir in den if-Zweig der eben geschriebene Methode folgendes einfügen:
| Code: | ||
|---|---|---|
|
Da wir dem Dokument mit document.documentElement.style.overflow = 'hidden'; die Scrolleisten geklaut haben, müssen wir sie natürlich anschließend wiederherstellen, also muss in den else-Zweig noch das hinein:
| Code: | ||
|---|---|---|
|
Machen wir mit der zweiten Methode weiter, die das Ein- und Ausblenden des Layers übernimmt.
Damit der Layer auch halbtransparent ist, bedienen wir uns der CSS-Eigenschaft opacity. Weil CSS 2 für den IE jedoch eine Fremdsprache ist, kann er mit CSS 3 erst recht nichts anfangen und drum müssen wir mit filter:Alpha(opacity=xyz) nachhelfen.
Ich schreibe zuerst den vollständigen Code und erläutere ihn dann:
| Code: | ||
|---|---|---|
|
Da JavaScript es bekanntlich nicht so genau mit den Parametern nimmt, machen wir uns das doch zunutze. Die Methode muss nämlich unterscheiden können, ob sie gerade vom User aufgerufen wurde oder durch ein Timeout, das wir am Ende der Methode setzen.
Das machen wir mit einem weiteren Parameter, der in der eigentlichen Parameterliste nicht angegeben ist. Um alle Parameter auszulesen, die der Methode übergeben wurden, benutzen wir das automatisch erstellte Array arguments. Ist also arguments[1] (der zweite Parameter) nicht übergeben, so handelt es sich um den ersten Aufruf der Methode, also durch die von außen vom User. In diesem Falle muss der Layer also zuerst noch erzeugt werden.
Dann wird geprüft, ob aufwärts oder abwärts gezählt werden soll. Ist 0 übergeben, so wird die Methode kommentarlos beendet, da das keinen Sinn hätte.
Die Variable opacity enthält nun den Wert der aktuellen Transparenz. Dieser wird danach um den angegebenen Zähler verändert. Weil hierbei aber oft Rundungsfehler auftreten, wende ich einen kleinen Trick an. Ich runde die Kommazahl, die ich vorher mit 10 multipliziert habe, auf die nächste Ganzzahl auf und teile das Ergebnis wieder durch 10. Damit habe ich wieder eine korrekte Zahl.
Damit der Vorgang aber nicht endlos läuft, wird jetzt geprüft, ob die Variable über dem definierten Maximum oder unterhalb von 0 liegt. In beiden Fällen wird die Methode verlassen. Bei letzterem wird der Layer aber vorher noch aus dem Dokument entfernt.
Was jetzt noch passiert, ist nicht allzu spannend. Anhand des Benutzeragenten prüfen wir, ob der User den IE verwendet oder nicht und setzen die aktuelle Transparenzstufe mit den jeweils möglichen Mitteln.
Zu beachten gilt hierbei, dass der IE nicht eine Zahl zwischen 0 und 1 sondern zwischen 0 und 100 erwartet. Deshalb die Multiplikation mit 100.
Im darauf folgenden Schritt wird die Methode mit einem Timeout nochmals aufgerufen, diesmal mit zweitem Parameter.
Das ist es im Grund auch schon. Es fehlt aber noch etwas Entscheidendes: wenn der User auf den Layer klickt, soll dieser auch wieder ausgeblendet werden.
Dazu brauchen wir einen Event-Handler. Schreibe deshalb in die Methode pageLayer.addRemoveLayer() noch diesen Code:
| Code: | ||
|---|---|---|
|
Warum verwende ich hier nicht this? Ganz einfach. Die definierte anonyme Methode wird nicht direkt im Kontext des Literals ausgeführt, sondern per Event-Handler. Also muss ich auch den von außen sichtbaren Namen des Literals verwenden. Das ist auch der Grund, weshalb ich eingangs keine Klasse gewählt habe, da ich dann ja den späteren Namen des Objekts nicht kennte.
Hinweis für Fortgeschrittene:
Der Weg, addEventListener() für das Zuweisen eines Event-Handlers zu nehmen, wäre zwar der schönere Weg, aber dann müsste ich zu viel herumprogrammieren, um auch dem IE beizubringen, dass er dem Layer einen Event-Handler zuweisen soll. Er beharrt derzeit noch auf der Eigenkreation attachEvent(). Das einfache Zuweisen von onmousedown wird hingegen von jedem gängigen Browser unterstützt und reicht in diesem Falle auch aus.Das ist dann auch endgültig alles. Ganz schon viel für so ein kleines Tutorial
.Zum Schluss natürlich nochmal das gesamte Skript:
| Code: | ||
|---|---|---|
|
Um die Seite abzublenden, reicht der schlichte Befehl
| Code: | ||
|---|---|---|
|
Fertig!
Natürlich freue ich mich über jeden konstruktiven Kommentar. Was war gut? Was war nicht so gut? Bei solchen langen Artikel kann es gut sein, dass nicht alles gleich verständlich ist. Wenn du das Gefühl hast, dass etwas aus diesem Tutorial an dir vorbeigegangen ist, dann kannst du das gerne in einen Kommentar fassen.
Sei doch mutig, dich zu äußern!
Seiten: (1/1) 1
7 Kommentare:
hilfreiches tut
Datum: 29.04.2008, 21:35 - Autor: Gast
Hallo
ich finde dieses tutorial ist mit grosser mühe erstellt worden. den code kann man ja mal kopieren und wenns funtzt ist das ziel ja eigentlich schon erreicht, weil man eine funktion "meistens" nur zum laufen bringen will.
lg gandonit
Danke für das Tuorial
Datum: 02.04.2009, 21:22 - Autor: Nixe
Hallo,danke für das Tutorial hat mir sehr weitergeholen aber eine Anmerkung habe ich noch.
In der Funktion addRemoveLayer sollte am Ende des else Zweiges noch ein this.layerElement = null. Sonst kann man nur ein mal Ausblenden. Danach gibt es eine böse Fehlermeldung. So funktioniert es bei mir:
if (this.layerElement == null) {
...
} else {
// remove layer and make document scrollable
document.getElementsByTagName('body')[0].removeChild(this.layerElement);
document.documentElement.style.overflow = 'visible';
this.layerElement = null;
}
mfg
Nixe
Datum: 02.04.2009, 21:35 - Autor: Manko10
Hi Nixe,vielen Dank für die Ergänzung, sie wurde in das Tutorial eingefügt.
Ich denke, ich werde in nächster Zeit auch mal eine Neuauflage dieses Tutorials schreiben, in dem noch einige nützliche Sachen hinzugefügt werden, wie z.B. eine Lightbox in der Seitenmitte.
Datum: 31.07.2009, 12:09 - Autor: User
Hi Manko10,vielen Dank für Dein sehr hilfreiches Script!
In der Tat bin ich auch sehr interessiert in einer Fortsetzung, z.B. angedeutete Lightbox, oder einfach Elemente, die nicht von der Abdunkelung erfasst werden sollen.
take care, gummibär
Lightbox
Datum: 21.08.2009, 14:25 - Autor: User
Hi Manko10,ich bin's nochmal! Dein Script hat mir inzwischen gute dienste geleistet!
Wenn Du »this.layerElement.style.minHeight« genauso wie »this.layerElement.style.Height« mit »document.documentElement.scrollHeight+'px';« füllst, dann klappt's auch mit Firefox!
Die beiden »document.documentElement.style.overflow« kannst vergessen.
Untenstehend findest Du mein erweitertes Script für eine (Video-)Lightbox.
cu & glg
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>Videos</title>
<style>
img {border-color:transparent;margin:0px 5px}
span {width:150px;height:165px;float:left}
b {margin-left:5px}
i {font-size:smaller}
</style>
<script language=javascript>
function flv(video,w,h){
var box=document.getElementById("flvplayer"
var playersite=document.config.playersite.checked?"intern":"open"
var controlbar=document.config.controlbar.checked?"bottom&autostart=true":"over"
var displayclick=document.config.displayclick.checked?"fullscreen":"play"
if(controlbar=="bottom&autostart=true"
{h+=20;box.style.clip="rect(0px,"+w+"px,"+(h-1)+"px,0px)"}var jpg="inhalt"+video.substring(video.lastIndexOf("/"
,video.lastIndexOf("."
)+".jpg"var content=
"<object classid=clsid
27CDB6E-AE6D-11cf-96B8-444553540000 name=player width="+w+" height="+h+">"+"<param name=movie value=flvplayer.swf>"+
"<param name=allowfullscreen value=true>"+
"<param name=flashvars value=file="+video+"&image="+jpg+"&controlbar="+controlbar+"&displayclick="+displayclick+">"+
"<object type=application/x-shockwave-flash data=flvplayer.swf width="+w+" height="+h+">"+
"<param name=movie value=flvplayer.swf>"+
"<param name=allowfullscreen value=true>"+
"<param name=flashvars value=file="+video+"&image="+jpg+"&controlbar="+controlbar+"&displayclick="+displayclick+">"+
"<h3>Sie haben möglicherweise JavaScript deaktiviert oder verwenden eine ältere Version des Adobe Flash Player.<br><a href=http://get.adobe.com/flashplayer>Hier erhalten Sie die neueste Version des Flash Player.</a></h3>"+
"</object>"+
"</object>"
if(playersite=="intern"
{pageLayer.fadeLayer(0.05)
box.style.left=(document.body.offsetWidth-w)/2+"px"
box.style.top="200px"
box.style.display="block"
box.innerHTML=content}
else{
var fenster=window.open("","","width="+w+",height="+h+",left="+(screen.availWidth-w)/2+",top="+(screen.availHeight-h)/2)
with(fenster.document){
open()
write("<body style=margin:0>"+content)
close()}
fenster.focus()}}
var pageLayer={
layerElement:null,
maxLayerOpacity:0.8,
addRemoveLayer:function(){
if(this.layerElement==null){
this.layerElement=document.createElement("div"
this.layerElement.onmousedown=function(){
pageLayer.fadeLayer(-0.1,pageLayer.maxLayerOpacity)
var box=document.getElementById("flvplayer"
box.style.display="none"
box.innerHTML=""}
this.layerElement.style.position="absolute"
this.layerElement.style.top="0px"
this.layerElement.style.left="0px"
this.layerElement.style.width="100%"
this.layerElement.style.height=document.documentElement.scrollHeight+"px"
this.layerElement.style.minHeight=document.documentElement.scrollHeight+"px"
this.layerElement.style.backgroundColor="black"
document.getElementsByTagName("body"
[0].appendChild(this.layerElement)}else{
document.getElementsByTagName("body"
[0].removeChild(this.layerElement)this.layerElement=null}},
fadeLayer:function(addend){
var opacity
if(arguments[1]==null){
this.addRemoveLayer()
if(addend>0)opacity=0
else if(addend<0)opacity=this.maxLayerOpacity
else return}
else opacity=arguments[1]
opacity+=addend
opacity=Math.round(opacity*10)/10
if(opacity>this.maxLayerOpacity)return
else if(opacity<0){
this.addRemoveLayer()
return}
if(IE='\v'=='v')this.layerElement.style.filter="Alpha(opacity="+(opacity*100)+"
"else this.layerElement.style.opacity=opacity
setTimeout("pageLayer.fadeLayer("+addend+","+opacity+"
",20)}}</script>
</head>
<body style=font-family:Arial;font-size:smaller;text-align:center>
<div id=flvplayer style=position:fixed></div>
<form style=position:absolute;text-align:right name=config action="">Flashplayer in diesem Fenster <input type="checkbox" name="playersite" value="intern" checked><br>Navigationsleiste / Autostart <input type="checkbox" name="controlbar" value="bottom" checked><br>Fullscreen bei Mausklick <input type="checkbox" name="displayclick" value="fullscreen" checked></form>
<p><font size=7 face=Verdana color=steelblue><b><em>Videos</em></b></font></p><table><tr><td>
<span><a href="Beispielvideo.flv" onclick="flv(this.href,320,240);return false" title="Beispielvideo"><img src="inhalt/Beispielvideo.jpg"></a><b>Beispielvideo</b> [flv]<i> 1:23</i></span>
</body>
</html>
Datum: 23.08.2009, 12:21 - Autor: Manko10
Hi,vielen Dank für deine Ergänzungen, ich werde sie mit der Zeit einarbeiten und beizeiten wird es auch eine Fortsetzung geben.
Die letzten vier Wochen war ich aber im Urlaub und muss mich erstmal wieder zu Hause einfinden, meine Finger wieder eintippen und mich durch das durchwühlen, was in der Zeit alles so passiert ist. ;-)
Grüße und Danke
Manko10
Datum: 27.08.2009, 18:51 - Autor: Thomas
Wie kann man den Effekt in einen beliebigen DIV-Container oder den Z-Index verschieben? Ich habe auf meiner Seite einige Javascript-Elemente, die nicht im Body verankert sind und deshalb immer auf dem Layer liegen, obwohl sie dahinter sein sollten.Alle Bemühungen, die Zeile mit "getElementsByTagName('body')" umzubauen sind kläglich gescheitert. Gibt es etwas, dass ich hier übersehen habe?