Für mein Projekt Mein-Online-Adventskalender habe ich die alte Fancybox ersetzt und eine eigene kleine Lösung geschrieben. Kein JQuery, kein AngularJS.. einfaches kleines altes JavaScript.
function MediaViewer(){
this.dialog = null;
this.mediaContainers = [];
this.elements=[];
this.init=function(){
var elements=document.querySelectorAll("[mv-dialog]");
for(var i=0; i<elements.length;i++){
var func=function(controller){
return function(){
controller.close();
};
};
elements.addEventListener("click", func(this), true);
this.dialog = elements;
this.dialog.style.display="none";
}
this.close();
var elements=document.querySelectorAll("[mv-item]");
for(var i=0; i<elements.length;i++){
var el = elements;
var src="";
if(el.getAttribute("mv-src")){
src=el.getAttribute("mv-src");
}
else if(el.getAttribute("src")){
src=el.getAttribute("src");
}
var contEl={
id:this.elements.length,
src:src,
type: el.getAttribute("mv-item").length > 0 ? el.getAttribute("mv-item") : el.nodeName
};
this.elements[contEl.id] = contEl;
var func=function(controller, id){
return function (){
controller.openDialog(id);
};
};
el.addEventListener("click", func(this, contEl.id), true);
}
var elements=document.querySelectorAll("[mv-container]");
for(var i=0; i<elements.length;i++){
var el = elements;
var cont={
element:el,
type:el.getAttribute("mv-container").length >0 ? el.getAttribute("mv-container") : el.nodeName
}
var func=function(controller){
return function(){
controller.close();
};
};
elements.addEventListener("click", func(this), true);
this.mediaContainers[this.mediaContainers.length] = cont;
}
};
this.close=function(){
var classes = this.dialog.getAttribute("class");
if(!classes){
classes = "";
}
if(classes.length == 0 || classes.match(/mvvisible/)){
classes=classes.replace(/mvvisible/, "");
classes += " mvinvisible";
this.dialog.setAttribute("class", classes);
}
};
this.openDialog=function(id){
this.dialog.style.display="";
for(var i=0;i<this.mediaContainers.length;i++){
var cont=this.mediaContainers;
if(cont.type.toUpperCase() == this.elements[id].type.toUpperCase()){
cont.element.style.display="";
cont.element.setAttribute("src",this.elements[id].src);
}
else{
cont.element.style.display="none";
}
}
var classes = this.dialog.getAttribute("class");
if(!classes){
classes = "";
}
if(!classes.match(/mvvisible/)){
classes=classes.replace(/mvinvisible/, "");
classes += " mvvisible";
this.dialog.setAttribute("class", classes);
}
}
this.init();
}
Die Anzeige, die man vor dem schliessenden Body-Tag einbauen muss:
<div mv-dialog style="display:none">
<img mv-container="img"/>
<video mv-container="video" autoplay mute></video>
</div>
<script type="text/javascript">
new MediaViewer();
</script>
Passendes CSS:
div[mv-dialog]{
position:fixed;
display:flex;
flex-flow: column;
top:0vh;
left:0vh;
width:100%;
height:100%;
background-color:rgba(0,0,0,0.8);
}
img[mv-item], video[mv-item]{
cursor:pointer;
}
div[mv-dialog].mvvisible{
animation-name:animvvisible;
animation-duration:1s;
display:default;
}
@keyframes animvvisible{
0%{opacity:0;transform:scale(0.5);}
90%{transform:scale(1);}
100%{opacity:1;}
}
div[mv-dialog].mvinvisible{
animation-name:animvinvisible;
animation-duration:2s;
height:0;
}
@keyframes animvinvisible{
0%{opacity:1;transform:scale(1);height:100%;}
90%{transform:scale(0.5);}
100%{opacity:0;height:0;}
}
img[mv-container]{
display:block;
margin-left:auto;
margin-right:auto;
margin-top:5vh;
margin-bottom:auto;
max-width:98vw;
max-height:90vh;
vertical-align:middle;
cursor:pointer;
border-radius:5px;
}
video[mv-container]{
display:block;
margin-left:auto;
margin-right:auto;
margin-top:5vh;
margin-bottom:auto;
max-width:98vw;
max-height:90vh;
vertical-align:middle;
cursor:pointer;
}
Damit kann man ganz einfach Pop-Ups zur Mediendarstellung erstellen.
<img mv-item src="test.jpg">
<button mv-item="img" mv-src="test.jpg">click to open</button>
<img mv-item mv-src="test.jpg" src="test_thumb.jpg">
<button mv-item="video" mv-src="test.mp4">open video</button>
Man ganz einfache eigene Container in den Dialog einbauen. Der Name wird bei mv-item angegeben. Sollten nur die Tags wie mv-item angegeben sein versucht die Logik im Dialog ein Element des selben Typs (img, video, etc) zu finden.
Ich habe gestern Abend mal eine Animation so wohl als animiertes GIF als auch WebM ausgegeben.
Der Unterschied in der Dateigröße ist schon enorm.
Wenn man also überlegt, ob man auf der eigenen Seite Animationen als GIF oder WebM (selbst der neue Edge wird es unterstützen) nimmt, ist WebM wohl die beste Wahl. Damit es sich wie ein GIF verhält muss man es so einbinden:
<video src="ani.webm" autoplay loop mute></video>