Вернуться на предыдущую страницу

Иногда необходим простой и быстрый способ получить увеличение изображений на сайте без особых затрат на Javasript... И в данном материале Вы найдете этот способ.

Логика очень простая... У нас есть некий контейнер с изображениями-миниатюрами. Нажимая на которые должно подгружаться большое изображение в хорошем качестве...

DEMO

CODEPEN

HTML:

<div class="fx ac jc gap fw zoomImages">
<img data-big="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/1.jpg" src="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/1_th.jpg" alt>
<img data-big="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/2.jpg" src="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/2_th.jpg" alt>
<img data-big="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/3.jpg" src="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/3_th.jpg" alt>
<img data-big="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/4.jpg" src="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/4_th.jpg" alt>
<img data-big="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/5.jpg" src="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/5_th.jpg" alt>
<img data-big="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/6.jpg" src="https://f.inverser.pro/files/scripts/0/MicroImageZoomJS/img/6_th.jpg" alt>
</div>

JS:

"use strict";
(()=>{
    const d=document;//create document alias
    const s=(e)=>d.querySelector(e);//select one func
    const a=(e)=>d.querySelectorAll(e);//select all func
    function addListenerMulti(element, eventNames, listener) {
        const events = eventNames.split(' ');
        for (let i=0, iLen=events.length; i<iLen; i++) {
            element.addEventListener(events[i], listener, false);
        }
    }
    const imgs=a('.zoomImages img');//get our images
    if(imgs.length>0){
        imgs.forEach(e=>{
            e.addEventListener('click',()=>{
                d.body.classList.add('ovh');//hide window scroll
                const source_=e.getAttribute('data-big');
                if(source_){//if source is
                    let mobile=false;
                    if(window.innerWidth<1024){
                        mobile=true;
                    }
                    const newImg=d.createElement('img');
                    newImg.src=source_;
                    newImg.classList.add('pr','z1','zoomOut','an');
                    const newDiv=d.createElement('div');
                    //add classes for main zoom div
                    newDiv.classList.add('pf','p0','ova','z11','an','o0','zoomOut','zoomDiv','loading_');
                    let cnt="",cnt2="",cnt3="";
                    cnt=setTimeout(()=>{//timeout for animation
                        newDiv.classList.remove('o0','zoomOut')
                    },100);
                    newDiv.setAttribute('style',`background:rgba(255,255,255,.7)`);
                    d.body.appendChild(newDiv);
                    newImg.onload=()=>{//all logic start when image was fully loaded
                        let tf=true;
                        //check image resolution
                        newDiv.classList.remove('loading_')
                        if(newImg.naturalHeight-100>window.innerHeight||newImg.naturalWidth-100>window.innerWidth){
                            const zoomDiv=s('.zoomDiv');
                            if(zoomDiv){
                                const btnZoom=d.createElement('button');
                                let btnZoomTxt='Zoom to fit';
                                btnZoom.classList.add('pf','z2','zoomBtn');
                                newDiv.appendChild(btnZoom);
                                addListenerMulti(btnZoom,'touchstart mouseenter',()=>{tf=!tf});
                                addListenerMulti(btnZoom,'touchend mouseleave',()=>{tf=!tf});
                                btnZoom.addEventListener('click',()=>{
                                    newImg.classList.toggle('zoomImgCl');
                                    newDiv.classList.toggle('fx');
                                    newDiv.classList.toggle('ac');
                                    newDiv.classList.toggle('jc');
                                });
                                if(mobile) {
                                    btnZoomTxt = 'View full image';
                                    btnZoom.click();
                                }
                                btnZoom.innerText=btnZoomTxt;
                                const btnClose=btnZoom.cloneNode();
                                btnClose.classList.add('pf','z2','zoomBtnClose');
                                btnClose.innerText='Close';
                                newDiv.appendChild(btnClose);
                                btnClose.addEventListener('click',()=>{
                                    close()
                                })
                            }
                        }else{newDiv.classList.add('fx','jc','ac')}
                        clearTimeout(cnt);
                        clearTimeout(cnt2);
                        clearTimeout(cnt3);
                        cnt2=setTimeout(()=>{
                            newImg.classList.remove('zoomOut')
                        },400);
                        newDiv.appendChild(newImg);
                        newDiv.addEventListener('click',()=>{
                            close()
                        });
                        function close(){
                            if(!tf)return;
                            d.body.classList.remove('ovh');
                            newDiv.classList.add('o0','zoomOut');
                            cnt3=setTimeout(()=>{
                                newDiv.remove();
                            },1000);
                        }
                    };
                }
            })
        })
    }
})()

CSS:

/*FOR DEMO PAGE*/
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
body,button{font-family: 'Roboto',-apple-system, sans-serif}
body{min-height: 150vh}
.fw{flex-wrap: wrap}
.gap{gap:.75rem}
main,footer{max-width: 666px;margin: auto}
footer a{display: block;margin: 2rem 0}
/*\ FOR DEMO PAGE*/
/*FOR ZOOM IMAGE*/
.ovh{overflow: hidden}
.ova{overflow: auto}
.fx{display: flex}
.jc{justify-content: center}
.ac{align-items: center}
.pr{position: relative}
.pf{position: fixed}
.p0{top:0;right:0;bottom:0;left:0}
.an{transition: all linear .5s}
.z1{z-index:1}
.z2{z-index:2}
.z11{z-index: 11}
.o0{opacity: 0}
.zoomOut{transform: scale(0)}
.zoomDiv{cursor:zoom-out;text-align: center}
.zoomImages img{width:200px;height: auto;max-width: 100%;border-radius:1rem;cursor: zoom-in}
.zoomImgCl{max-width:98vw;max-height:98vh}
.loading_:after{content: '';position:absolute;top:50%;left:50%;width:3rem;height: 3rem;border:2px solid;border-color:#333 transparent;border-radius: 50%;animation: spinnerAlt ease-in-out .5s infinite;transform:translate(-50%,-50%)rotateY(180deg)}
button.zoomBtn,button.zoomBtnClose{top:0;left:0;border:2px solid #333;background:rgba(255,255,255,.5);backdrop-filter:blur(5px);border-radius:.75rem;padding:.25rem;color:#333}
button.zoomBtnClose{left:auto;right: 0}
@keyframes spinnerAlt {
100% {
transform:translate(-50%,-50%)rotateY(180deg)rotate(360deg);
}
}
/*\ FOR ZOOM IMAGE*/
Miscro Image Zoom Native JS (responsive)