Кастомная навигация для fotorama (jQuery). Из говна конфетка.

Йо-йо. Недавно писал кастомную навигацию для jquery-плагина fotorama.io. А именно мне нужно было сделать навигацию из миниатюр картинок в несколько строк (в одну или две в зависимости от условий), при наведении на миниатюру показать нужную картинку и в мобильной версии вывести порядковый номер и количество картинок.

Решение

window.__CAR_STATE_ = 'Новый';
var rowsCointByCarState = {
    'С пробегом': 2,
    'Новый': 1
}


fotoramaDefaultsCar = {
    width: '100%',
    thumbwidth: 100,
    thumbheight: 70,
    allowfullscreen: true,
    keyboard: true,
    arrows: 'always',
    nav: 'thumbs',
    captions: true,
    transition: 'dissolve',
    transitionduration: '0'
}

if(document.getElementById('car360')){
    document.getElementById('car360').classList.add('fotorama_custom_360');
}

if(!SAFE_isMobile()){

    $(function () {
        $('.fotorama[data-c-fr="car"]').fotorama(fotoramaDefaultsCar);
    });



    $('.fotorama[data-c-fr="car"]').on('fotorama:ready', function (e, fotorama, extra) {

        var isFullScreen = false;

        var data = fotorama.data;
        var frNavBox = this.querySelector('.fotorama__nav-wrap');
        frNavBox.classList.add('fotorama_custom_nav_hidden');

        // start Open or Close fullscreen
        var fullScreenIcon = this.querySelector('.fotorama__fullscreen-icon');
        fullScreenIcon.style.display = 'none';
        var icon360 = document.getElementById('car360');

        var stageFotorama = this.querySelector('.fotorama__stage');
        var elFullScreen = document.createElement('div');
        elFullScreen.style.position = 'absolute';
        elFullScreen.style.top = '0';
        elFullScreen.style.left = '0';
        elFullScreen.style.bottom = '0';
        elFullScreen.style.right = '0';
        elFullScreen.style.zIndex = '5';
        elFullScreen.style.cursor = 'pointer';
        elFullScreen.title = 'В полноэкранный режим';



        stageFotorama.insertAdjacentElement('afterend', elFullScreen);

        elFullScreen.appendChild(this.querySelector('.fotorama__arr.fotorama__arr--next'));
        elFullScreen.appendChild(this.querySelector('.fotorama__arr.fotorama__arr--prev'));


        elFullScreen.addEventListener('click', function (e) {
            if(e.target !== e.currentTarget) return;

            if(!elFullScreen.classList.contains('active')){
                fotorama.requestFullScreen();
            } else {
                fotorama.cancelFullScreen();
            }
        });
        $(this).on('fotorama:fullscreenenter', function () {
            elFullScreen.classList.add('active');
            elFullScreen.style.display = 'none';
            fullScreenIcon.style.display = 'block';
            if(icon360){
                icon360.classList.toggle('fotorama_custom_360');
            }

            isFullScreen = true;
        });
        $(this).on('fotorama:fullscreenexit', function () {
            elFullScreen.classList.remove('active');
            elFullScreen.style.display = 'block';
            fullScreenIcon.style.display = 'none';
            if(icon360){
                icon360.classList.toggle('fotorama_custom_360');
            }
            isFullScreen = false;
        });


        var vanilaJsItem = document.querySelector('.fotorama[data-c-fr="car"]');
        var nav = document.createElement('div');
        nav.classList.add('fotorama_custom_nav');
        nav.style.display = 'block';
        nav.style.position = 'relative';
        vanilaJsItem.appendChild(nav);

        var borderBox = document.createElement('div');
        borderBox.classList.add('fotorama_custom_nav__border_box');
        borderBox.style.width = fotoramaDefaults.thumbwidth + 'px';
        borderBox.style.height = fotoramaDefaults.thumbheight  + 'px';
        borderBox.style.position = 'absolute';
        nav.appendChild(borderBox);

        var arrEl = [];

        var parentWidth = nav.getBoundingClientRect().width;
        var elsInRow = Math.floor(parentWidth / fotoramaDefaults.thumbwidth);
        var widthItemsByPercent = parentWidth / elsInRow;

        var i = 1;
        var items = elsInRow * rowsCointByCarState[window.__CAR_STATE_];

        data.map(function (item) {
            if(i < items){
                var el = document.createElement('img');
                el.src = item.thumb;
                el.width = widthItemsByPercent;
                el.setAttribute('data-i', item.i);
                el.classList.add('fotorama_custom_nav_item');
                nav.appendChild(el);
                arrEl.push(el);
                i++;
            } else {
                var el = document.createElement('img');
                el.src = item.thumb;
                el.width = widthItemsByPercent;
                el.setAttribute('data-i', item.i);
                el.classList.add('fotorama_custom_nav_item');
                arrEl.push(el);
            }

        });

        var etcCountPhoto = arrEl.length - i;

        if(arrEl[i-1]){
            var wrap = document.createElement('div');
            wrap.style.width = widthItemsByPercent + 'px';
            wrap.style.height = arrEl[0].getBoundingClientRect().height + 'px';
            wrap.classList.add('fotorama_custom_last_img_wrap');
            wrap.dataset.count = etcCountPhoto;
            wrap.addEventListener('mouseover', function (e) {
                e.stopPropagation();
            });
            nav.appendChild(wrap);
            wrap.appendChild(arrEl[i-1]);
            wrap.title = 'Посмотреть все фото';

            $(wrap).on('click', function () {
                fotorama.requestFullScreen()
            })
        }



        borderBox.style.width = widthItemsByPercent + 'px';
        borderBox.style.height = arrEl[0].getBoundingClientRect().height + 'px';


        $(this).on('fotorama:fullscreenenter', function () {
            frNavBox.classList.add('fotorama__nav--thumbs');
            frNavBox.classList.remove('fotorama_custom_nav_hidden');
            nav.style.display = 'none';
        });

        $(this).on('fotorama:fullscreenexit', function () {
            frNavBox.classList.remove('fotorama__nav--thumbs');
            frNavBox.classList.add('fotorama_custom_nav_hidden');
            nav.style.display = 'block';
        });

        $(document).on('mouseover', '.fotorama__nav__frame', function () {
            var $fotoramaDiv = $(this).parents('.fotorama[data-c-fr="car"]'),
                fotoramaApi = $fotoramaDiv.data('fotorama');
            fotoramaApi.show({
                index: $('.fotorama__nav__frame', $fotoramaDiv).index(this)
            });
        });


        function setItemWidht() {

            // Количество элементов в строке
            //var elsInRow = arrY.filter(function(y){ return y === arrY[0] }).length;
            var parentWidth = nav.getBoundingClientRect().width;
            var elsInRow = Math.floor(parentWidth / fotoramaDefaults.thumbwidth);
            var widthItemsByPercent = parentWidth / elsInRow;

            arrEl.map(function (el) {
                var newWidth = widthItemsByPercent;
                el.width = newWidth;
                el.removeAttribute('height');
            });

            borderBox.style.width = widthItemsByPercent + 'px';
            borderBox.style.height = arrEl[0].getBoundingClientRect().height + 'px';
        }


        function handleResize() {
            arrEl.map(function (el) {
                el.width = fotoramaDefaults.thumbwidth;
                el.height = fotoramaDefaults.thumbheight;
            });

            setItemWidht();

            var i = fotorama.activeFrame.i;
            var currentImg = arrEl[i -1];
            borderBox.style.top = currentImg.offsetTop + 'px';
            borderBox.style.left = currentImg.offsetLeft + 'px';
        }

        window.addEventListener('resize', handleResize);


        $('.fotorama_custom_nav_item').click(function() {
            fotorama.show($(this).data('i') - 1);
        });

        $(document).on('mouseover', '.fotorama_custom_nav_item', function () {
            var $fotoramaDiv = $(this).parents('.fotorama[data-c-fr="car"]'),
                fotoramaApi = $fotoramaDiv.data('fotorama');
            fotoramaApi.show({
                index: $(this).data('i') - 1,
            });
            borderBox.style.top = this.offsetTop + 'px';
            borderBox.style.left = this.offsetLeft + 'px';
        });

        $(this).on('fotorama:show', function (e, fotorama, extra) {
            if(isFullScreen === false){
                var i = fotorama.activeFrame.i;
                var currentImg = arrEl[i -1];

                if(currentImg.parentElement && currentImg.parentElement === nav){
                    borderBox.style.top = currentImg.offsetTop + 'px';
                    borderBox.style.left = currentImg.offsetLeft + 'px';
                    borderBox.style.display = 'block';
                } else {
                    borderBox.style.display = 'none';
                }

            }

        });

    });
} else {
    fotoramaDefaultsCar.nav = false;
    fotoramaDefaultsCar.arrows = false;
    fotoramaDefaultsCar.transition = 'slide';
    fotoramaDefaultsCar.click = false;


    $(function () {
        $('.fotorama[data-c-fr="car"]').fotorama(fotoramaDefaultsCar);

        $('.fotorama[data-c-fr="car"]').on('fotorama:ready', function (e, fotorama, extra) {
            // start Open or Close fullscreen
            var fullScreenIcon = this.querySelector('.fotorama__fullscreen-icon');
            // fullScreenIcon.style.display = 'none';
            var icon360 = document.getElementById('car360');


            // Modify fullScreenIcon
            var modifyOptions = {
                display:'block',
                width:'100%',
                height:'100%',
                background:'none'
            }
            var modifyOptions2 = {
                width:'100%',
                height:'100%',
                background:'none'
            }
            function modifyOptionsFn(el, modifyOptions, bool) {
                if(bool === true){
                    for(var option in modifyOptions){
                        el.style[option] = modifyOptions[option];
                    }
                } else {
                    for(var option in modifyOptions){
                        el.style[option] = '';
                    }
                }
            }

            modifyOptionsFn(fullScreenIcon, modifyOptions, true);

            // Caption
            var frWrap = this.querySelector('.fotorama__wrap');
            var captionBlock = document.createElement('div');
            captionBlock.style.position = 'absolute';
            captionBlock.style.bottom = '2px';
            captionBlock.style.right = '2px';
            captionBlock.style.display = 'block';
            captionBlock.classList.add('fotorama_custom_caption_block');


            captionBlock.innerText = fotorama.activeFrame.caption;

            var glif = document.createElement('span');
            glif.classList.add('glyphicon');
            glif.classList.add('glyphicon-camera');

            captionBlock.insertAdjacentElement('afterbegin', glif);

            frWrap.appendChild(captionBlock);



            $(this).on('fotorama:show', function (e, fotorama, extra) {
                captionBlock.innerText = fotorama.activeFrame.caption;
                captionBlock.insertAdjacentElement('afterbegin', glif);
            });


            // !-Caption

            $(this).on('fotorama:fullscreenenter', function () {
                modifyOptionsFn(fullScreenIcon, modifyOptions2, false);
                fullScreenIcon.style.display = 'flex';
                if(icon360){
                    icon360.classList.toggle('fotorama_custom_360');
                }
            });
            $(this).on('fotorama:fullscreenexit', function () {
                modifyOptionsFn(fullScreenIcon, modifyOptions, true);
                if(icon360){
                    icon360.classList.toggle('fotorama_custom_360');
                }
            });


        });

    });
}
.fotorama_custom_nav__border_box{transition:top 360ms,left 360ms;border-style:solid;border-color:#00afea;background-image:linear-gradient(to bottom right,rgba(255,255,255,.25),rgba(64,64,64,.1));z-index:4}.fotorama_custom_360{top:2px!important}[data-c-fr=car] .fotorama__caption__wrap{display:none}.fotorama_custom_caption_block{padding:6px 10px;background:#ccc}.fotorama_custom_caption_block>span{margin-right:3px;position:relative;top:2px}.fotorama_custom_nav_hidden{position:absolute;left:-13000px}.fotorama_custom_last_img_wrap{display:inline-block;position:relative}.fotorama_custom_last_img_wrap:before{content:'Ещё ' attr(data-count) ' фото';position:absolute;top:0;left:0;right:0;bottom:0;background-color:#00000080;color:#fff;font-size:1.5em;display:flex;justify-content:center;align-items:center;text-align:center;cursor:pointer}.fotorama__stage__frame{opacity:1!important}.fotorama__stage__shaft{opacity:1!important}