在为我们的客户开发Magento 2项目时,我应该设置more/less按钮,它不是Blank或Luma主题的一部分。按钮位于产品页面上,但只能在电脑上的Details选项卡(移动设备上的手风琴)内,该选项卡显示后台中产品描述字段。
在我们开始之前,我已经创建了一个自定义主题(Magease/ MoreLess,它正在扩展Blank主题),请确保在进行过程中为您的主题更新了正确的路径。代码是在最新的带有样本数据的(2.1.6)上编写的。
首先,我们需要创建几个文件:
touch app/design/frontend/Magease/MoreLess/Magento_Catalog/layout/catalog_product_view.xml
touch app/design/frontend/Magease/MoreLess/requirejs-config.js
touch app/design/frontend/Magease/MoreLess/web/js/toggle-product-description.js
touch app/design/frontend/Magease/MoreLess/Magento_Catalog/templates/more-less.phtml
touch app/design/frontend/Magease/MoreLess/web/css/source/_theme.less
让我们看一下这些文件,并介绍将在每个文件中放置哪些代码:
requirejs-config.js
使用此文件注册您自己的JavaScript组件:
var config = {
map: {
"*": {
// alias: path-to-corresponding-js-file
toggleProductDescription: 'js/toggle-product-description'
}
}
};
- toggleProductDescription是指向Javascript文件的任意位置的任意组件别名(Magento会自动将.js扩展名附加到文件名)。
catalog_product_view.xml
这是产品页面的主要布局文件,在content容器内部,创建新块并使用指定的模版文件:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body>
<referenceContainer name="content">
<block class="Magento\Framework\View\Element\Template" name="more-less-js" template="Magento_Catalog::more-less.phtml" />
</referenceContainer>
</body>
</page>
more-less.phtml
此文件包含更多/更少功能的基本配置。鉴于Magento为每个选项卡使用相同的模板文件,建议将JavaScript初始化部分分离到不同的文件中。
<script type="text/x-magento-init">
{
".product.data.items .product.attribute.description .value":{
"toggleProductDescription":{
"contentMaxHeight": 200
}
}
}
</script>
让我简要解释一下这些元素是什么以及它们的目的是什么:
- .product.data.items .product.attribute.description .value - 字符串(但实际上是CSS选择器),用作进一步JavaScript处理的容器
- toggleProductDescription - 在RequireJS配置文件中注册的JavaScript文件的别名
- contentMaxHeight - 将在主JavaScript文件中使用的变量的声明
- 200 - 变量的任意值
toggle-product-description.js
将所有JavaScript逻辑放在此文件中,这样的JavaScript组件的骨架应该是这样的:
define([
"jquery", // declare your libraries, if you are using them
], function ($) { // delare library aliases
'use strict';
return function (config, node) {
// paste snippet #1 here
// paste snippet #2 here
}
});
这是最重要的部分 - 从.phtml文件传递参数并返回输出:
- config - 包含所有自定义变量的全局变量。在这种情况下,您应该使用config.contentMaxHeight来获取变量的值
- node - selector,可用于初始化jQuery对象
在匿名函数内部,我创建了一个简单的JSON对象,该对象包含更多/更少功能的所有参数:触发更改的链接和应用更改的目标元素。
// snippet #1
var moreLess = {
button: {
el: $("<a>", {
id: "toggle-description",
href: "#"
}),
expanded_text: "Show less",
collapsed_text: "Show more"
},
target: {
el: $(node),
height: $(node).height(),
maxHeight: config.contentMaxHeight,
collapsedClassName: "collapsed",
}
};
该代码利用了函数参数,这使其可以解析目标元素的更多/更少状态。
// snippet #2
if (moreLess.target.height > moreLess.target.maxHeight) {
// update button text value
moreLess.button.el.text(moreLess.button.collapsed_text);
moreLess.target.el
// add css class to apply some styling
.addClass(moreLess.target.collapsedClassName)
// append link to product description
.parent().append(moreLess.button.el);
}
moreLess.button.el.on("click", function (e) {
e.preventDefault();
if (moreLess.target.el.hasClass(moreLess.target.collapsedClassName)) {
moreLess.target.el.removeClass(moreLess.target.collapsedClassName);
moreLess.button.el.text(moreLess.button.expanded_text);
} else {
moreLess.target.el.addClass(moreLess.target.collapsedClassName);
moreLess.button.el.text(moreLess.button.collapsed_text);
}
});
当加载组件时,它将检查content的高度是否大于定义的值,如果大于,则追加more/less按钮并为其分配一个事件监听器。
_theme.less
这是您要创建的可选文件,我已经创建了一些最小的样式(透明到实体背景)使更多/更少按钮有很好的效果。
.product.attribute.description .value{
max-height: none;
position: relative;
max-height: none;
border-bottom: 1px solid #d1d1d1;
&.collapsed {
max-height: 200px;
overflow: hidden;
&:after {
content: "";
position: absolute;
width: 100%;
height: 160px;
z-index: 1;
display: block;
bottom: 0;
background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 70%, rgba(255,255,255,1) 100%); /* FF3.6-15 */
background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 70%,rgba(255,255,255,1) 100%); /* Chrome10-25,Safari5.1-6 */
background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 70%,rgba(255,255,255,1) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#ffffff',GradientType=0 ); /* IE6-9 */
}
}
}
#toggle-description {
margin-top: 20px;
display: inline-block;
}
以下是它在前端的样子: