Как я могу воссоздать быстрый просмотр продукта Squarespace в стандартном представлении продукта?

Обзор

Итак, я пытаюсь взять функциональность из одной части коммерческого шаблона Squarespace Galapagos и добавить ее в другую, но это оказывается сложнее, чем я думал.

Мне нужна возможность замены изображений в «Быстром просмотре» (пример — наведите указатель мыши на любое изображение и нажмите «Быстрый просмотр»), чтобы заменить столбец полноразмерных масштабируемых изображений в «Просмотре продукта» (пример — вы видите это, когда нажимаете на продукт).

Итак, я нашел код для каждого раздела:

Просмотр продукта

Этот код просто просматривает каждое изображение в массиве и выдает его с идентификатором jsProductItemImages, что позволяет наводить курсор и масштабировать его.

<div class="productitem-images" id="jsProductItemImages">
    {.repeated section items}
        {.image?}
            <div class="productitem-image-zoom-wrapper sqs-image-zoom-area"><img data-load="false" class="productitem-image loading" {@|image-meta} /></div>
        {.end}
        {.video?}
            {@|video}
        {.end}
    {.end}
</div>

Быстрый просмотр

Я не на 100% придерживаюсь логики, но, по сути, это захват первого изображения и превращение его в основное изображение при наведении/масштабировании, а затем перечисление всего массива изображений под ним в виде миниатюр. Я читал, что символ @ эквивалентен выражению this в javascript, но я не понимаю, почему он используется для вывода только первого изображения в массиве.

<figure class="ProductItem-gallery">
  {.section items}
    <div class="ProductItem-gallery-slides">
      {.repeated section @}
        {.image?}
          <div class="ProductItem-gallery-slides-item" data-slide-index="{@index}"><img class="ProductItem-gallery-slides-item-image" data-load="false" {@|image-meta} /></div>
        {.end}
        {.video?}
          {@|video}
        {.end}
      {.end}
    </div>
  {.end}
  <div class="ProductItem-gallery-thumbnails">
    {.if items.1}{.repeated section items}<div class="ProductItem-gallery-thumbnails-item"><img class="ProductItem-gallery-thumbnails-item-image" data-load="false" {@|image-meta} /></div>{.end}{.end}
  </div>
</figure>

Связанный JS

Во-первых, следует отметить, что я просмотрел и записал в консоль каждую функцию, чтобы увидеть, что дает Quick View ее функциональность - безрезультатно. Именно поэтому я здесь. Таким образом, легко увидеть, откуда берется функция масштабирования: представление продукта в функции Galapagos.ProductItem в строке 103 $imageContainer = Y.one('#jsProductItemImages');

Но я не вижу ничего необычного, когда смотрю на Quick View. Я должен что-то упустить!

var Galapagos = {};

Y.use('node', function(Y) {

    Galapagos.Site = (function(){
    console.log("Galapagos.Site");

        var $productPage;

        function init() {
      console.log("Galapagos.Site init()");

            $productPage = Y.one('.collection-type-products');

            if( $productPage && $productPage.hasClass('view-list') ) Galapagos.ProductList.init();
            if( $productPage && $productPage.hasClass('view-item') ) Galapagos.ProductItem.init();

            addDesktopTouchscreenClass();
            addMediaQueryBreakpointClass();
            bindEventListeners();

        }

        function addDesktopTouchscreenClass() {
      console.log("Galapagos.Site addDesktopTouchscreenClass()");
            if (Y.one('html').hasClass('touch')) {
                var mousemoveDetection = Y.on('mousemove', function(){
                    Y.one('body').addClass('galapagos-desktop-touchscreen');
                    mousemoveDetection.detach();
                });
            }

        }

        function addMediaQueryBreakpointClass() {
      console.log("Galapagos.Site addMediaQueryBreakpointClass()");
            if( document.documentElement.clientWidth <= 724 ) {
                if (Y.one('.catnav-container')) Y.one('.nav-container').prepend(Y.one('.catnav-list'));
                Y.one('html').addClass('tablet-breakpoint-mixin');
            } else {
                if (Y.one('.catnav-container')) Y.one('.catnav-container').prepend(Y.one('.catnav-list'));
                Y.one('html').removeClass('tablet-breakpoint-mixin');
            }

        }

        function bindEventListeners() {
      console.log("Galapagos.Site bindEventListeners()");
            Y.on('resize', addMediaQueryBreakpointClass);
        }

        function getDocWidth() {
      console.log("Galapagos.Site getDocWidth()");
            return Y.one(document).get('docWidth');
        }

        function getDocHeight() {
      console.log("Galapagos.Site getDocHeight()");
            return Y.one(document).get('docHeight');
        }

        return {
            init:init,
            getDocWidth: getDocWidth,
            getDocHeight:  getDocHeight
        }

    }());


    Galapagos.TweakListener = (function(){
    console.log("Galapagos.TweakListener");
        function listen(tweakName, callBack) {

            if (Y.Global) {
                Y.Global.on('tweak:change', Y.bind(function(f){
                    if ((f.getName() == tweakName) && (typeof callBack === 'function')) {
                        callBack(f.getValue());
                    }
                }));
            }

        }

        return {
            listen:listen
        }

    }());


    Galapagos.ProductItem = (function(){
    console.log("Galapagos.ProductItem");
        var cat;
        var $imageContainer;
        var $images;
        var imageZoomInstances = [];
        function init() {
      console.log("Galapagos.ProductItem init()");

            cat = Y.QueryString.parse(location.search.substring(1)).category;
            $imageContainer = Y.one('#jsProductItemImages');
            $images = $imageContainer.all('img[data-src]');

            if ( cat ) setCatCrumb();
            loadProductDetailImages();

            bindEventListeners();
            bindTweakListeners();
            buildProductDetailImagesLightbox();

        }

        function bindEventListeners() {
      console.log("Galapagos.ProductItem bindEventListeners()");
            Y.on('resize', function(){
                loadProductDetailImages();
            });

        }

        function setCatCrumb() {
      console.log("Galapagos.ProductItem setCatCrumb()");
            var $catCrumb = Y.one('#jsCategoryCrumb');
            var $catCrumbLink = $catCrumb.one('a');
            var catCrumbHref = $catCrumbLink.getAttribute('href');

            //var $mobileCatCrumbLink = Y.one('#jsMobileCategoryCrumb');

            $catCrumbLink.set('text', cat).setAttribute('href', catCrumbHref + '?category=' + encodeURIComponent(cat));
            //$mobileCatCrumbLink.setAttribute('href', catCrumbHref + '?category=' + encodeURIComponent(cat));

            $catCrumb.removeClass('galapagos-display-none');

        }

        function loadProductDetailImages() {
      console.log("Galapagos.ProductItem loadProductDetailImages()");
            var imageZoomEnabled = Y.one('.tweak-product-item-image-zoom-enabled');

            $images.each(function(image) {

                ImageLoader.load(image.removeAttribute('data-load'), { load:true });

                if (imageZoomEnabled) {
                    image.on('load', function() {
                        instantiateImageZoom(image);
                    });
                }
            });

        }

        function instantiateImageZoom(image) {
      console.log("Galapagos.ProductItem instantiateImageZoom()");
            imageZoomInstances.push(new Y.Squarespace.ImageZoom({
                host: image.get('parentNode'),
                behavior: 'hover',
                zoom: parseFloat(Y.Squarespace.Template.getTweakValue('tweak-product-item-image-zoom-factor'))
            }));
        }

        function destroyImageZoomInstances() {
      console.log("Galapagos.ProductItem destroyImageZoomInstances()");
            if (!imageZoomInstances || imageZoomInstances.length < 1) {
              return;
            }

            Y.Array.each(imageZoomInstances, function(zoomInstance){
              zoomInstance.destroy(true);
            });
        }

        function buildProductDetailImagesLightbox() {
      console.log("Galapagos.ProductItem buildProductDetailImagesLightbox()");
            if ($images.size() >= 1 ) {

                var lightboxSet = [];

                $images.each(function(image) {
                    lightboxSet.push({
                        content: image
                    });
                });

                // Only show controls for size > 1
                var hasControls = $images.size() > 1;

                $imageContainer.delegate('click', function(e) {

                    var lightbox = new Y.Squarespace.Lightbox2({
                        controls: {
                            previous: hasControls,
                            next: hasControls
                        },
                        set: lightboxSet,
                        currentSetIndex: $images.indexOf(e.target)
                    });

                    lightbox.render();

                }, 'img', this);

            }
        }

        function bindTweakListeners() {
      console.log("Galapagos.ProductItem bindTweakListeners()");
            if (Y.Global) {
                Y.Global.on('tweak:close', function() {
                    if (Y.one('.collection-type-products.view-item')) {
                        destroyImageZoomInstances();
                        if (Y.one('.tweak-product-item-image-zoom-enabled')) {
                            $images.each(function(image){
                                instantiateImageZoom(image);
                            });
                        }
                    }
                }, this);
            }
        }

        return {
            init:init
        }

    }());


    Galapagos.ProductList = (function(){
    console.log("Galapagos.ProductList");

        var $catNav,
            $productGrid,
            $productGridOrphans,
            $productGridImages,
            $orphanProducts,
            productCount,
            maxGridUnit,
            orphanProductCount,
            isGridBuilt;


        function init() {
      console.log("Galapagos.ProductList init()");

            $catNav = Y.one('#jsCatNav');
            $productGrid = Y.one('#jsProductGrid');
            $productGridOrphans = Y.one('#jsProductGridOrphans');

            if (!Y.UA.mobile && Y.one('.show-alt-image-on-hover:not(.product-info-style-overlay)')) {
                $productGridImages = $productGrid.all('img[data-src]');
            } else {
                $productGridImages = $productGrid.all('img.productlist-image--main[data-src]');
            }

            productCount = $productGrid.all('.productlist-item').size();
            maxGridUnit = 8;
            orphanProductCount;
            isGridBuilt = false;

            bindEventListeners();
            bindTweakListeners();
            if($catNav) setActiveCategory();
            if(Y.one('body').hasClass('product-grid-style-organic')) {
                buildGrid();
            } else {
                $productGrid.removeClass('loading').removeClass('loading-height');
                loadGridImages($productGridImages);
            }

        }

        function bindEventListeners() {
      console.log("Galapagos.ProductList bindEventListeners()");
            Y.on('resize', function(){
                loadGridImages($productGridImages);
            });

        }

        function buildGrid() {
      console.log("Galapagos.ProductList buildGrid()");
            for (var i = maxGridUnit; i > 0; i--) {

                orphanProductCount = productCount % i;

                if(productCount <= maxGridUnit || i > 4) {

                    if(0 === orphanProductCount) {

                        $productGrid.addClass('item-grid-' + i);

                        isGridBuilt = true;
                        break;

                    }

                } else {

                    if(0 === productCount % 9) {  // if productCount is a multiple of 9, use the 9-grid.  we use 9-grid only for multiples of 9 because 8-grid looks more interesting.

                        $productGrid.addClass('item-grid-' + 9);

                    } else { // otherwise, use the 8-grid and put the remainder into the orphan div

                        $productGrid.addClass('item-grid-' + maxGridUnit);
                        $orphanProducts = Y.all('.productlist-item').slice((productCount % maxGridUnit) * -1);

                        $productGridOrphans
                            .append($orphanProducts)
                            .addClass('item-grid-' + productCount % maxGridUnit);
                    }

                    isGridBuilt = true;
                    break;

                }

            }

            if(isGridBuilt) {
                $productGrid.removeClass('loading').removeClass('loading-height');
                loadGridImages();
            }

        }

        function setActiveCategory() {
      console.log("Galapagos.ProductList setActiveCategory()");

            var catNavItemCount = $catNav.all('.catnav-item').size();

            for (var i = catNavItemCount - 1; i > 0; i--) {

                var $item = $catNav.all('.catnav-item').item(i);
                var $link = $item.one('.catnav-link');
                var category = Y.QueryString.parse(location.search.substring(1)).category;
                var href = Y.QueryString.parse($link.getAttribute('href').substring(2)).category;

                if(category && href && category === href) {
                    $item.addClass('active-link');
                }
                else if(!category) {
                    $catNav.one('#jsCatNavRoot').addClass('active-link');
                }

            }

        }

        function loadGridImages() {
      console.log("Galapagos.ProductList loadGridImages()");
            $productGridImages.each(function(image) {
                ImageLoader.load(image.removeAttribute('data-load'), { load: true });

                image.on('load', function(){
                    if (image.hasClass('productlist-image--main.has-alt-image')) {
                        image.siblings('.productlist-image--alt').removeClass('galapagos-hidden');
                    }
                });
            });
        }

        function bindTweakListeners() {
      console.log("Galapagos.ProductList bindTweakListeners()");
            if (Y.Global) {

                Y.Global.on(['tweak:beforeopen', 'tweak:close', 'tweak:reset'], function() {
                    setTimeout(function(){
                        Galapagos.ProductList.init();
                    }, 1000);
                });

                Y.Global.on(['tweak:beforeopen'], function() {
                    setTimeout(function(){
                        Galapagos.ProductList.init();
                        $productGrid.one('.productlist-item').addClass('is-hovered');
                    }, 1000);
                });

                Y.Global.on(['tweak:close'], function() {
                    setTimeout(function(){
                        Galapagos.ProductList.init();
                        $productGrid.one('.productlist-item').removeClass('is-hovered');
                    }, 1000);
                });

            }

            Galapagos.TweakListener.listen('product-grid-style', function(value) {

                if('Organic' === value) {
                    buildGrid();
                } else {
                    $productGrid.append($orphanProducts);
                    loadGridImages();
                }
            });

            Galapagos.TweakListener.listen('product-info-style', function(value) {

                if('Overlay' === value) {
                    $productGrid.one('.productlist-item').addClass('is-hovered');
                } else {
                    $productGrid.one('.productlist-item').removeClass('is-hovered');
                }

            });

            Galapagos.TweakListener.listen('productImageAspectRatio', function(value) {
                loadGridImages();
            });

            Galapagos.TweakListener.listen('productImageSpacing', function(value) {
                loadGridImages();
            });

        }

        return {
            init:init
        }


    }());


    Y.on('domready', function() {

        Galapagos.Site.init();

    });

});

Мои попытки

Мои первые несколько попыток заключались в удалении элемента div jsProductItemImages из представления «Продукт» и выгрузке всего блока figure из окна «Быстрый просмотр», а затем обновлении соответствующего css. Пока он загружает изображения (я вижу их в инспекторе, и они занимают место на странице), он отображается как пустой.

Я также пытался использовать только раздел эскизов из быстрого просмотра и ограничить просмотр продукта, чтобы показать только первое изображение с помощью {.section items.0}, но тогда любой эскиз, который я щелкнул, не менялся без написания сценария для него (очевидно), но я не Не хочу писать что-то подобное, когда я знаю, что это уже существует в коде!

Любая помощь будет принята с благодарностью!

ОБНОВИТЬ:

После замены разметки просмотра продукта на разметку быстрого просмотра я столкнулся с этими ошибками.

Uncaught TypeError: Cannot read property 'all' of null    site.js:104
  init                  @ site.js:104
  init                  @ site.js:17
  (anonymous function)  @ site.js:432
  _notify                 @ common-2a739bf…-min.js:1479
  notify                  @ common-2a739bf…-min.js:1479
  _notify                 @ common-2a739bf…-min.js:1475
  _procSubs             @   common-2a739bf…-min.js:1476
  fireSimple              @ common-2a739bf…-min.js:1476
  _fire                 @   common-2a739bf…-min.js:1476
  fire                  @   common-2a739bf…-min.js:1489
  _load                 @   common-2a739bf…-min.js:1463
  f                     @   common-2a739bf…-min.js:1457

Не знаете, почему возникает ошибка с .all, потому что он должен обращаться к одному и тому же массиву изображений в обеих ситуациях?


person Evan Lemmons    schedule 08.08.2016    source источник


Ответы (1)


В этом посте есть несколько вопросов, но позвольте мне ответить на вопрос быстрого просмотра, поскольку это то, что вы хотите «исправить».

Squarespace использует модульную систему надстроек JavaScript/CSS, называемых «свертками». Если вы вытащите исходный код, вы увидите объект окна, который содержит текущую конфигурацию любой данной страницы. При посещении страницы продуктов система инициирует использование их быстрого просмотра JS и размещения файла CSS. Это то место, где вы захотите искать. JS, в который вы копаетесь, не имеет отношения к Quick View (я не верю).

Quick View Rollup JS: http://static.squarespace.com/universal/scripts-compressed/product-quick-view-6a1e5642b473ebbb5944-min.js

Сводка CSS для быстрого просмотра: http://static.squarespace.com/universal/styles-compressed/product-quick-view-eb4b900ac0155bed2f175aa82e2a7c17-min.css

Эти свертки запускаются с помощью ловушек JavaScript в файлах шаблонов. Что вам нужно сделать, так это поэкспериментировать с использованием слова и слова шаблона продукта Galapagos, чтобы он имел те же классы и атрибуты данных, и посмотреть, работает ли это. Было бы слишком много времени, чтобы охватить все детали того, что вам нужно сделать, не работая над проектом. Сначала я бы начал с этого и посмотрел, можете ли вы настроить свой шаблон продукта для запуска Quick View JS как есть, без настройки.

person jasonbarone    schedule 08.08.2016
comment
Спасибо за помощь! Поэтому, когда я вытащил шаблон, у меня нет доступа к перечисленным вами сверткам. И единственный js, который я вижу включенным, это <squarespace:script src="site.js" combo="true"/>, но я полностью верю, что вы правы, потому что он точно не использует site.js для быстрого просмотра. Я думаю, мой вопрос заключается в том, как манипулировать представлением продукта, чтобы использовать его? Вы сказали, что у него должны быть те же классы и тому подобное, но прямое копирование / вставка галереи изображений Quick View не решило эту проблему - и это наверняка точные классы. - person Evan Lemmons; 08.08.2016
comment
Эй, что касается site.js.... это JS для конкретного шаблона. Есть десятки и десятки дополнительных JavaScript, которые НЕ уникальны для шаблона. Быстрый просмотр НЕ уникален для Галапагосских островов, и на самом деле, вероятно, в какой-то момент он станет функцией каждого отдельного шаблона. - person jasonbarone; 08.08.2016
comment
Я не тратил на это огромное количество времени, потому что я часто избегаю Squarespace JS (потому что его слишком сложно настроить), но также попробуйте включить быструю настройку .conf продукта: productQuickView: true. Я считаю, что это то, что вызывает активацию накопительных пакетов в коллекции. - person jasonbarone; 08.08.2016
comment
Мне будет проще решить эту проблему вместе с вами в чат-сообществе Talk Squarespace Slack, которым я руковожу. Через несколько дней я снова открою общедоступную регистрацию: squarefront.com. - person jasonbarone; 08.08.2016
comment
О, хорошо, ваш сайт выглядит как фантастический ресурс! Я проверил, и ` hasProductQuickView : true` уже был включен на template.conf и products.conf. Это воняет, потому что похоже, что они там просто не загружаются: imgur.com/a/495g1 - person Evan Lemmons; 08.08.2016
comment
И пойму ли я это или нет, дайте мне знать, когда ваш сайт снова заработает! @jasonbarone - person Evan Lemmons; 08.08.2016