Ich wollte in einer Webdesign Vorlage shadowbox verwenden und musste feststellen, dass es damit einige Probleme gibt:
1. Der Overlay Container erstreckt sich nicht auf die ganze Höhe des Displays
2. Der shadowbox Container sitzt immer zuoberst an der Seite. Wenn der Besucher sich daher innerhalb der Seite befindet und die Shadowbox aufruft, kann es vorkommen, dass diese nicht gesehen werden kann
Das Hauptproblem liegt an der fixierten Positionierung des shadowbox containers. MobileSafari kennt „position: fix“ nicht. Anscheinend werden alle so positionierten Elemente wie „position: absolute“ behandelt. Das andere Problem ist, dass die relative Grösse von 100% angewendet auf den HTML body nicht funktioniert.
Nachdem ich das Web nach möglichen Lösungen durchforstet habe, stellte ich fest, dass es anscheinend noch keine wirkliche Lösung für das Problem gibt. So habe ich mich selber daran gemacht um die Darstellung von shadowbox in MobileSafari in Ordnung zu bringen. Und anscheinend ist das auch gar nicht so schwierig.
In diesem Artikel möchte ich kurz meine Lösung des Problems beschreiben. Da ich jQuery verwendet habe, ist der verwendete Code nicht in allen Projekten 1:1 zu übernehmen, doch denke ich, wird klar, was unternommen werden muss.
Als erstes muss ich noch anfügen, dass ich generell die Webseite für iPhone und iPad optimiert habe und daher im Header folgendes eingebaut habe:
1. Meta Tag:
<meta name="viewport" content="user-scalable=no, width=device-width" />
Dieser meta tag führt dazu, dass die Seite sich immer auf die gesamte Breite des dargestellten Bereichs eingepasst wird und der Benutzer die Seite nicht zoomen kann.
2. CSS Dokumente für iPhone und iPad einbauen:
<!--[if !IE]>-->
<link media="only screen and (max-device-width: 480px)" href="iphone.css" type="text/css" rel="stylesheet" />
<link media="only screen and (min-device-width: 768px) and (max-device-width: 1024px)" href="ipad.css" type="text/css" rel="stylesheet" />
<!--<![endif]-->
Mit diesem Code ist es mir möglich, gezielt iPhone und iPad anzusprechen und gegebenenfalls Änderungen im Layout vorzunehmen
Ich vermute, dass folgende Beschreibungen, wie man die shadowbox Darstellung in MobileSafari fixen kann, kaum obige Anpassungen voraussetzen. Aber ausschliessen möchte ich es nicht.
So, und nun zum eigentlichen Thema: Wie lautet meine Lösung des Problems?
1. Schritt: Überprüfung, ob es sich um ein iDevice (iPhone/iPad handelt):
Folgende kurze Funktionen überprüfen, ob der Besucher mit einem iDevice unterwegs ist:
function checkiPhone() {
var iPhone=((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)));
return iPhone;
}
function checkiPad() {
var iPad=navigator.userAgent.match(/iPad/i);
return iPad;
}
Natürlich ist der userAgent immer mit Vorsicht zu geniessen, es scheint aber gut zu klappen.
Anschliessend müssen die Funktionen noch aufgerufen werden, damit die Variablen gesetzt werden. Dies geschieht in jQuery in der document.load methode:
jQuery(function() {
iPhone=checkiPhone();
iPad=checkiPad();
});
2. Schritt: Die Darstellung der Shadowbox fixen
Folgend ist mein Script, um die Darstellung in Ordnung zu bringen:
function fixiDevSB() {
if (iPhone || iPad) {
jQuery('#content a').click(function(e) {
var relTag=jQuery(this).attr('rel');
if ((/shadowbox/gi.test(relTag)) || (/lightbox/gi.test(relTag))) {
var wScroll=jQuery(window).scrollTop();
var wScrollCSS=wScroll+'px';
jQuery('#sb-container').css('top', wScrollCSS);
}
});
}
return;
}
Kurze Erklärung:
– in der ersten Zeile wird geprüft, ob der Besucher ein iPhone oder iPad benutzt. Wenn ja, werden die folgenden Zeilen ausgeführt.
– Die shadowbox wird auf Mausklick geöffnet, also wird hier dieser Event abgefangen bzw. eine Funktion eingefügt, welche genau dann ausgeführt werden soll, wenn der Benutzer auf einen Link klickt.
– Nun wird getestet, ob es sich bei dem Link um einen „shadowbox“ link handelt. Dies ist der Fall, wenn der Link ein „rel“ Attribut besitzt mit dem Wert von „shadowbox“ oder „lightbox“. Ist dies der Fall, kommen die folgenden Zeilen zur Anwendung.
– mit jQuery(window).scrollTop() wird die obere Position des Inhalts gemessen an der oberen Kante des Dokuments bestimmt. Mit anderen Worten, wieviele Pixel nach unten gescrollt wurden. Da es sich bei diesem Wert um eine Zahl handelt müssen wir noch den String „px“ anfügen, um den CSS Wert in Pixel zu erhalten.
– Nun definieren wir das CSS für den shadowbox Container so um, dass der Wert für „top“ sich genau an der oberen Kante des Bildschirms befindet.
Das wäre eigentlich auch schon alles, um den Inhalt der Shadowbox dort anzeigen zu lassen, wo sich der Benutzer gerade befindet.
Es hat sich gezeigt, dass die Höhe des Shadowbox Containers aber etwas zu klein ist, so dass er sich nicht auf die ganze Höhe des sichtbaren Bereichs erstreckt. Dies kann im CSS einfach angepasst werden, indem ein padding hinzu gefügt wird:
#sb-overlay {
padding-top: 30px;
padding-bottom: 30px;
}
Da dies nur bei iPhone/iPad geschehen soll, habe ich diese Angabe in den separaten iPhone.css und iPad.css Dokumenten vorgenommen.
Prinzipiell wird der container nun etwas zu weit nach unten versetzt (jedenfalls auf dem iPad). So könnte man in der „fixiDevSB()“ Funktion die Positionierung entsprechend anpassen:
wScroll-=30
Das war’s und es war kaum eine Hexerei. Shadowbox funktioniert nun einwandfrei in MobileSafari.
Relevante Links:
Shadowbox: http://shadowbox-js.com
jQuery Doku: http://api.jquery.com
MobileSafari Viewports: http://www.quirksmode.org/mobile/viewports2.html
Hello,
i tried to fix it with your informations, but it seems i’m not an expert enough to get it working. Could you give us a link to see it in work? It could help me to see how the html is written.
Thks in advance
By the way some people look like expecting a fix on Shadowbox Forum…
http://shadowbox-js.com/forum.html#nabble-td5834790
I have used my customization on this page:
http://www.rapid-ideas.com/previews/usine4/page5/page11/page11.html
Chris
Ok, thks for the reply!
but unfortunately, seen on my ipod touch, there is always the trouble of an overlay which doesn’t cover all your page if we scroll. I thought it was fixing it too.
anyway, thanks for sharing your skills
OK. Per default mobile safari will scroll all content but you should be able to disable this behaviour by catching the touchmove event like this:
function loaded() {
document.addEventListener('touchmove', function(e){ e.preventDefault(); });
}
document.addEventListener('DOMContentLoaded', loaded);
Haven’t tested it but it should work.
If you are using jQuery and my fix above you can also add the loaded function handling right below the checkiPad function:
jQuery(function() {
iPhone=checkiPhone();
iPad=checkiPad();
$(document).bind('touchmove',function(e){
e.preventDefault();
}
});
Hey Christoph!
Erstmal vielen dank fuer Deinen Fix hier, ist im Internet immer noch nicht zu finden ausser hier und verwunderlicherweise auch noch nicht vom Shadowbox-Team angepasst worden.
Leider habe ich aber Probleme.
Ich weiss naemlich nicht, ob ich den gesamten Code oben in die ganz normale shadowbox.js einfuegen muss, oder ob ich eine neue Datei erstellen soll. Wenn ich ihn in die .js einfuege, kommt die Box beim anklicken der Bilder nichtmehr…
Angemerkt sei noch, dass ich die Shadowbox insofern modifiziert habe, dass bei einem Mouseover links oder rechts zurueck bzw. vor in der Gallerie navigiert werden kann… Evtl hat es ja damit was zu tun.
Viele Gruesse,
Marco
Hallo Marco
Das Javascript solltest du schon nicht direkt in shadowbox einbauen, damit du später keine Probleme mit Updates hast. Ich empfehle also, den Code entweder in eine schon bestehende JS Datei auszulagern oder eine neue dafür zu erstellen (z.B. sb-fix.js).
Was dich aber – und wahrscheinlich auch andere Leser – noch interessieren dürfte: unter iOS läuft shadowbox anstandslos. Apple hat „position: fixes“ und „overflow: auto“ in die neueste iOS Version (noch beta) eingebaut. Habe es eben gleich getestet. Also, vielleicht genügt es ja, einfach 2-3 Monate zu warten, bis iOS5 veröffentlicht wird.