在为我们的客户开发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;
}

以下是它在前端的样子: