什么是跟随的侧边栏?为什么要用它来提高你的转换率?就像跟随的header一样,跟随的侧边栏的目的是让侧边栏元素一直显示在视图中(或者至少在满足某些条件时)。这里的内容可以是产品选项(可配置下拉菜单、图像样本等)、添加到购物车按钮或任何其他对您的产品重要的元素。也就是说,您的客户可以自由浏览产品上的所有内容,添加到购物车按钮“随时待命“,客户一旦决定购买该产品,只需要点击就可以了!
让我们开始更改代码以实现此功能,出于本篇博客的目的,我创建了一个自定义主题 Magease/StickySidebar。
LESS 代码
在app/design/frontend/Magease/StickySidebar/web/css/source/中创建_extend.less文件,然后复制/粘贴以下代码:
.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
.box-tocart .action.tocart {
width: 100%;
margin-right: 0;
}
.sidebar {
&.fixed {
position: fixed;
}
}
}
确保运行Grunt命令来链接并编译这段代码(仅在电脑桌面,它将侧边栏定位为固定元素并使添加到购物车按钮宽度为全宽)。
XML 代码
在app/design/frontend/Magease/StickySidebar/Magento_Catalog/layout/中创建catalog_product_view.xml文件,然后复制/粘贴以下代码:
<page layout="2columns-right" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<referenceBlock remove="true" name="catalog.compare.sidebar" />
<referenceBlock remove="true" name="wishlist_sidebar" />
<move element="product.info" destination="sidebar.additional" />
<referenceContainer name="sidebar.additional">
<block class="Magento\Framework\View\Element\Template"
name="sticky.sidebar.wrapper"
template="Magento_Catalog::sticky-sidebar-js.phtml"
after="-" />
</referenceContainer>
</page>
这部分代码负责以下内容:
- 将页面布局从一列更改为两列,右侧为侧栏
- 删除使用此页面布局时包含的两个块(比较和心愿单块)
- 更改包含产品选项的块的位置,并将添加到购物车按钮添加到侧栏
- 添加模板文件,用于调用AMD组件以处理粘性侧边栏逻辑和计算
PHTML 代码
在app/design/frontend/Magease/StickySidebar/Magento_Catalog/templates/中创建sticky-sidebar-js.phtml文件,然后复制/粘贴以下代码:
<script type="text/javascript" data-mage-init='{"stickySidebar":{}}'></script>
RequireJS 代码
在app/design/frontend/Magease/StickySidebar/中创建requirejs-config.js文件,然后复制/粘贴以下代码:
var config = {
map: {
"*": {
stickySidebar: "js/sticky-sidebar",
}
}
};
jQuery 代码
在pp/design/frontend/Magease/StickySidebar/web/js/中创建sticky-sidebar.js文件,然后复制/粘贴以下代码:
define(["jquery", "matchMedia", "domReady!"], function ($, mediaCheck) {
"use strict";
var sidebar = {};
var a2c = $(".product-add-form");
var a2c_mobile_target = $(".product-info-main > .price-box");
// nodes required to calculate sidebar params: width, left, padding-left
var page_main = $(".page-main");
var page_main_w;
var main = $(".main");
var main_w;
// nodes required to calculate sidebar params: top
var header = $(".page-header");
var nav = $(".nav-sections");
var breadcrumbs = $(".breadcrumbs");
// luma specific css values
var a2c_mb = parseInt($("#product-addtocart-button").css("margin-bottom"));
var main_pb = parseInt(main.css("padding-bottom"));
var tabs_mb = parseInt($(".product.info.detailed").css("margin-bottom"));
sidebar.el = $(".sidebar");
sidebar.padding_ratio = parseFloat(sidebar.el.css("padding-left")) / page_main.width();
sidebar.updateHorizontalParams = function () {
if (sidebar.el.hasClass("fixed")) {
page_main_w = parseFloat(page_main.width());
main_w = parseFloat(main.width());
sidebar.width = page_main_w - main_w;
sidebar.left = ($(window).width() - page_main_w) / 2 + main_w;
sidebar.p_left = parseInt(page_main_w * sidebar.padding_ratio);
sidebar.el.css({
"width": sidebar.width + "px",
"left": sidebar.left + "px",
"padding-left": sidebar.p_left + "px"
});
}
};
sidebar.updateVerticalParams = function () {
sidebar.height = sidebar.el.height();
var scrolled_from_top = $(window).scrollTop();
var header_h = header.outerHeight(true) || 0;
var nav_h = nav.outerHeight(true) || 0;
var breadcrumbs_h = breadcrumbs.outerHeight(true) || 0;
var content_h = main.outerHeight(true) || 0;
var sidebar_limit_top = header_h + nav_h + breadcrumbs_h;
var sidebar_limit_bottom = sidebar_limit_top + content_h;
var sidebar_limit_bottom_criteria = scrolled_from_top + sidebar.height + main_pb + a2c_mb - tabs_mb;
if (sidebar_limit_bottom < sidebar_limit_bottom_criteria) {
// sidebar should start drifting out of viewport on the top
sidebar.top = sidebar_limit_bottom - sidebar_limit_bottom_criteria;
sidebar.el.css({"top": sidebar.top + "px"});
} else if (scrolled_from_top > sidebar_limit_top) {
// header and breadcrumbs are now above viewport
if (!sidebar.el.hasClass("fixed")) {
sidebar.el.addClass("fixed");
sidebar.updateHorizontalParams();
}
sidebar.top = 0;
sidebar.el.css({"top": sidebar.top + "px"});
} else {
sidebar.el.removeClass("fixed").removeAttr("style");
}
};
var onResize = function () {
$(window).on("resize", function () {
sidebar.updateHorizontalParams();
});
}, onScroll = function () {
$(window).on("scroll", function () {
sidebar.updateVerticalParams();
});
}, onInit = function () {
mediaCheck({
media: "(min-width: 768px)",
entry: function () {
sidebar.el
.addClass("fixed")
.prepend(a2c.detach());
sidebar.updateHorizontalParams();
sidebar.updateVerticalParams();
onResize();
onScroll();
},
exit: function () {
a2c.detach().insertAfter(a2c_mobile_target);
sidebar.el
.removeClass("fixed")
.removeAttr("style");
}
});
};
onInit();
});
让我为您提供代码的解释:
- 方法onInit()用于初始化逻辑
- 通过利用matchMedia库,产品选项可以改变移动和桌面布局之间的位置(这种元素的分离是必要的,因为在移动设备上,侧边栏将是页脚之前的最后一个元素,并且不会让它在页面下方到目前为止)。此媒体查询还负责添加(在桌面上)或删除(在移动设备上)CSS类名“固定”
- 当仅在电脑桌面上时,JS将计算四个CSS属性的值(updateHorizontalParams() - > width,left,padding-left属性,updateVerticalParams() - > top属性)和加载事件侦听器(在页面调整大小和页面滚动以执行相同的计算
- 侧边栏的显示可分为三种不同的状态:
- 状态#1 - 只要面包屑在视窗中可见,侧边栏就相对定位
- 状态#2 - 只要面包屑在视窗外滚动,侧边栏就会定位为固定元素并保留在视口中
- 状态#3 - 一旦侧边栏的底边与内容的底边对齐,侧边栏就开始滑出视窗外,就像页面的其余部分一样