Предпросмотр картинки с открытием оригинала на JavaScript
При создании фотогалереи или любой системы, содержащей картинки, сталкиваешься с проблемой показа превьюшки, т.е. уменьшенной копии изображения с возможностью открыть оригинал. Как правило, для этого используют PHP-скрипт преобразования на сервере.
Я пошел по другому пути.
На сервере хранятся исходное изображение и миниатюра.
В атрибут src элемента img прописывается URL миниатюры, а URL оригинала большой картинки – в атрибут data-src.
<img src="images/thumbnail.jpg" data-src="images/image.jpg" alt="Портрет">
Вся страница должна быть помещена в один внешний div для формирования затемненной подложки.
При клике на элемент img, содержащий атрибут data-src, срабатывает соответствующая функция.
Исходный код примера:
<script>
function openwind(o){
var a;
if(o.nodeName=='IMG'){a=o.alt; fil=o.getAttribute('data-src');}
else if(o.nodeName=='A'){a=o.title;fil=o.href;}
else {fil=o;log("fil.nodeName=",fil.nodeName);}
a="<img onclick='fb_close()' src='"+fil+"' onload='fb_resize(this);' onerror='fb_error(this)' style='visibility:hidden' alt='"+a+"'/>";
fb_win(a);
return false;
}
function fb_win(html,ev){
fb_modal=document.createElement('div');
fb_modal.setAttribute('class','fb-win');
//console.log("fb_win:",html);
fb_modal.innerHTML=((ev==2)?'':'<div class="fb-win0" onclick="fb_close()"></div>')+'<div class="fb-win1">'+
'<a onclick="fb_close();return false;" title="Закрыть" href=""></a>'+html+
'<div class="dragbar" onmousedown="DD.start(event)" onmouseup="DD.stop(event)" oncontextmenu="return false" ondragstart="return false" ondblclick="DD.full(event)" ondragend="return DD.stop(event)"></div></div>';
document.body.appendChild(fb_modal);
if(ev){
if(ev==1){var d=document.forms;d=d[d.length-1][0].focus();}
else if(ev==2){_fade.init();}
else {/*console.log("eval:",ev); eval(ev);*/ExecScript(ev);}
}
addEvent(document, "keydown", fb_close);
addEvent(window, "resize", fb_ResizeDocument);
fb_ResizeDocument(); // для корректного расчета ширины окна нужно на все загружаемые в модальном окне изображения добавить onload="fb_ResizeDocument(event)"
// если в окно загружаются элементы с неограниченной шириной - окно будет максимально широким
var o=document.body.firstElementChild;
if(o){ // фиксирую основной экран(первый div внутри body) как подложку
var y = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var c=window.getComputedStyle(o, null);
var b=window.getComputedStyle(document.body, null);
//console.log(c.width, b.width,wW(),o);
if(c.width!=b.width && !o.getAttribute('data-width'))o.setAttribute('data-width',c.width);
o.style.width=Math.min(parseInt(c.width),wW())+'px'; // возможно была auto
var l=parseInt((wW()-parseInt(parseInt(c.width)))/2); if(l<=10)l=0; // это вертикальная прокрутка
//console.log('fb_win l=',l);
o.style.left=l+'px';
o.style.marginTop=-y+'px'; // подложка
addClass(o,'fb-fix');
window.scroll(0,0);
}
return fb_modal;
}
function fb_close(e) {// вызывается при нажатии клавиши в модальном окне и при нажатии на крестик
if (f_reload)reload();
if (typeof(e) == 'object') {
e = e || window.event;
if (e.type == 'keydown') {
if (e.keyCode == 27)fb_close(); // Esc
return;
}
}
//var a=getElementsByClass('fb-win',null,'DIV');
var a=document.querySelectorAll('div.fb-win');
if (a&&a.length) {
removeID(a[a.length - 1]);
if (a.length < 2)removeEvent(document, "keydown", fb_close);
a = getObj('Calendar');
if (a && a.style)a.style.display = 'none'; // прячу календарь
var o = document.body.firstElementChild;
if (o) {
var c = window.getComputedStyle(o, null);
var y = -parseInt(c.marginTop);
removeClass(o, 'fb-fix');
o.style.margin = ''; // 0 auto
o.style.left = ''; // auto
//o.style.width='auto'; // возможно была auto
o.style.width = (c = o.getAttribute('data-width') ? c : ''); // auto
//console.log("body.width:",o.style.width);
window.scroll(0, y);
}
}else console.log('fb_close: Нет ни одного открытого окна!');
}
function fb_ResizeDocument(e){
// вычисляю ширину модального окна и его положение по горизонтали
var o=fb_modal.querySelector('DIV.fb-win1'); if(!o){console.warn('Нет модального окна');return;}
var c=window.getComputedStyle(o, null);
//console.log('до',o,'width=',c.width, wW(), e);
if(!e || e.type!='resize' || wW()< parseInt(c.width)){
o.style.width='auto';
o.style.maxWidth=(wW()-10)+'px';
//console.log('~',o.style.width,o.style.maxWidth,c.width);
if(parseInt(c.width)<wW()&&wW()<500)o.style.width=wW()+'px';
else o.style.width=parseInt(parseInt(c.width)>500 ? Math.min(wW(),parseInt(c.width)+20) : 500 )+'px';
o.style.maxWidth='none';
//console.log('Меняю',o);
}else{
//console.log('НЕ Меняю',e.type);
}
var db=o.querySelector('DIV.dragbar'); if(db)db.style.width=(parseInt(c.width)-45)+'px'; else console.warn('В модальном окне нет dragbar!');
o.style.left=Math.max(0,parseInt((wW()-parseInt(parseInt(c.width)))/2))+'px';
//console.log('после',c.width, o.style.left);
// вычисляю положение модального окна по вертикали
o.style.top=(parseInt(c.height)>wH()*0.99 ? '0' : Math.floor((wH()-parseInt(c.height))/2)+'px' );
//console.log('fb_ResizeDocument', o.style.top );
}
</script>
.
Прокомментировать/Отблагодарить