快速提示:使用Flexbox和jQuery的用户可排序列表

带有巨大磁铁的卫星用于对小行星进行分类

在本文中,我们将逐步学习如何构建一个简单的jQuery插件,该插件根据其自定义数据属性的值对元素进行排序。

如果您对最终结果感到好奇,请查看相应的CodePen演示:

请参阅用于CodePen上按SitePoint( @SitePoint )对元素进行排序的Pen Simple jQuery插件

注意:本文假定您对flexbox有基本的了解,以及如何开发jQuery插件 。 如果您不熟悉这些主题,请确保查看链接。

可达性问题

要构建我们的插件,我们将利用flexbox的功能。

默认情况下,弹性项目根据其源顺序进行布局。 但是,通过使用order属性,我们可以在父级flex容器内更改其顺序。 具有较低order值的项目将首先出现。 请参阅以下示例:

见笔Flexbox的的“命令”属性由SitePoint( @SitePoint上) CodePen

如果有多个具有相同order值的商品,则这些商品的订单取决于其来源顺序。

尽管order属性使我们可以轻松地对元素进行重新排序,但它具有可访问性限制:它在源顺序和可视顺序之间造成了脱节。 为了更好地理解该问题,请查看本文 (尤其是“源顺序与视觉顺序”部分)。

因此,在继续研究如何构建我们的插件之前,请注意,它将无法访问。

标记

首先,我们定义一个包含十二个列表项的无序列表:

<ul class="boxes">
  <li>
    <a href="#">
      Box1
      <div class="details">
        <span class="length">13M</span>
        <span class="price">670€</span>
      </div>
    </a>
  </li>

  <!-- more list items here -->

</ul>

注意,在每个列表项中都有.details元素,该元素显示有关相应项的一些信息。 稍后我们将看到,我们还将添加自定义HTML属性来存储此信息。

注意: .details元素并不是必需的。 我们仅使用它来更好地了解目标元素的排序方式。

接下来,我们确定要排序的属性。 在我们的项目中,这些是pricelength属性。 考虑到这一点,我们使用它们的名称将自定义属性( data-pricedata-length )应用于列表项。 这些属性的值匹配的文本值(只有数字) .length.price元件,其是一部分.details元件。

例如,以下是第一个列表项的属性:

<li data-length="13" data-price="670">
  <a href="#">
    Box1
    <div class="details">
      <span class="length">13M</span>
      <span class="price">670€</span>
    </div>
  </a>
</li>

此时,我们指定将对列表项进行排序的元素。 我们使用<select>元素执行此操作:

<select class="b-select">
  <option disabled selected>Sort By</option>
  <option data-sort="price:asc">Price Ascending</option>
  <option data-sort="price:desc">Price Descending</option>
  <option data-sort="length:asc">Length Ascending</option>
  <option data-sort="length:desc">Length Descending</option>
</select>

如您所见,所有<option>元素(第一个元素除外)都包含data-sort属性。 此属性的值使用以下约定:

<option data-sort="price:asc">

因此,作为值,我们具有要排序的属性,后跟冒号以及“ asc”或“ desc”指示符。

CSS样式

准备好标记后,让我们向页面添加一些基本样式。 具体来说,我们将无序列表定义为flex容器,并将列表项的width: 25% 。 以下是相关的CSS规则:

.boxes {
  display: flex;
  flex-wrap: wrap;
}

.boxes li {
  width: 25%;
}

编译插件

我们将其插件numericFlexboxSorting 。 在显示构建过程之前,我们先从结局开始,并说明如何初始化它。

初始化插件

通常,插件应按以下方式初始化:

$("your-select-tag").numericFlexboxSorting();

例如,在我们的例子中:

$(".b-select").numericFlexboxSorting();

默认情况下,插件将使用.boxes li类对元素进行排序。 我们可以通过更改elToSort配置属性的值来覆盖此行为:

$(".b-select").numericFlexboxSorting({
  elToSort: "the-elements-you-want-to-sort"
});

步骤分解

现在我们准备描述开发过程!

第一步,我们通过numericFlexboxSorting添加numericFlexboxSorting方法来扩展jQuery的原型( $.fn )对象:

$.fn.numericFlexboxSorting = function() {
  const $select = this;

  // do stuff here

  return $select; 
};

在该方法中, this关键字引用我们的<select>元素。 创建插件后,我们必须返回此元素。 如果不这样做,方法链接将无法工作。

考虑以下代码,例如:

$(".b-select").numericFlexboxSorting().css("background", "red");

在这里,除非我们返回目标元素,否则css方法将不会执行任何操作。

正如我们已经提到的,默认情况下,插件将使用.boxes li类对元素进行排序。 但是,如果需要,我们应该能够覆盖此行为。 为了实现这一点,我们利用了jQuery的extend方法:

$.fn.numericFlexboxSorting = function(options) {
  const settings = $.extend({
    elToSort: ".boxes li"
  }, options);

  // do stuff here
};

该插件将按升序或降序对数字进行排序。 考虑到这一点,我们定义了相应的变量,稍后我们将使用它们:

$.fn.numericFlexboxSorting = function(options) {
  const ascOrder = (a, b) => a - b;
  const descOrder = (a, b) => b - a;

  // do stuff here
};

用户从下拉列表中选择一个选项(第一个选项除外)后,我们应该检索并评估其值。 为此,我们使用change事件:

$.fn.numericFlexboxSorting = function(options) {
  const $select = this;

  $select.on("change", () => {
    const selectedOption = $select.find("option:selected").attr("data-sort");
    sortColumns(settings.elToSort, selectedOption);
  });

  // do stuff here
};

在事件处理程序内部,我们做两件事:

  1. 检索所选选项的data-sort属性的值(例如price:asc )。
  2. 调用sortColumns函数。

sortColumns函数接受两个参数:

  1. 我们要排序的元素。
  2. 所选选项的data-sort属性的值。

这是此函数的主体:

function sortColumns(el, opt) {
  const attr = "data-" + opt.split(":")[0];
  const sortMethod = (opt.includes("asc")) ? ascOrder : descOrder;
  const sign = (opt.includes("asc")) ? "" : "-";

  // 1
  const sortArray = $(el).map((i, el) => $(el).attr(attr)).sort(sortMethod);

  // 2
  for (let i = 0; i < sortArray.length; i++) {
    $(el).filter(`[${attr}="${sortArray[i]}"]`).css("order", sign + sortArray[i]);
  } 
}

让我们解释一下里面发生了什么:

  1. 根据用户要排序的属性(即pricelength ),我们为每个目标元素获取相关data-* attribute的值,并将其存储在数组中。 另外,根据用户想要对目标元素进行排序的方式,我们以升序或降序对数组进行排序。

  2. 我们遍历数组,找到相关元素,并为其分配一个order属性值(正值或负值),该值由其相应的data-* attribute的值确定。
    因此,例如,如果用户选择了price:asc选项,则data-price: 315的元素将收到order: 315

    当我们按升序排序时,插件如何工作

    另一方面,如果用户选择price:desc选项,则它将收到order: -315

    当我们按降序排序时,插件如何工作

最后,为了避免与使用$变量的其他库可能发生冲突,我们将代码包装在立即调用的函数表达式中,如下所示:

(function($) {
  $.fn.numericFlexboxSorting = function(options) {
    // do stuff here
  };
})(jQuery);

我们的插件已准备就绪。 您可以在下面的Codepen演示中实时看到它:

请参阅用于CodePen上按SitePoint( @SitePoint )对元素进行排序的Pen Simple jQuery插件

插件限制

在这一点上,我们必须回想起我们的插件有一个很大的限制:它不可访问。 为了证明这一点,请从下拉列表中选择一个选项,然后使用键盘( 单击笔单击 “ Tab”键 )来浏览链接。 注意,元素根据其DOM顺序而不是 CSS顺序集中。

无法使用该插件,因为源顺序和视觉顺序之间存在脱节

需要注意的另一件事是,该插件仅提供基本功能,因此只能在特定条件下使用。 例如,属性值字符串应仅包含数字值。 请记住,此值指定目标元素的order (期望数字)。

显然,对于元素的排序和过滤,还有更可靠,更强大的库,如下所示:

特别是对于MixItUp,有一篇SitePoint文章介绍了它的基本知识。

浏览器支持

该插件取决于flexbox,因此其支持取决于浏览器的flexbox支持。 令人高兴的是,这些天flexbox具有出色的浏览器支持。

我可以使用flexbox吗? 来自caniuse.com的主要浏览器对flexbox功能的支持数据。

下一步

如果您喜欢挑战并希望丰富此插件的功能,则可以执行以下操作:

  • 添加对随机排序的支持。

  • 提供给用户选择排序控件是<select>元素,许多<button>元素还是其他控件类型的选项。 对于这种情况,您可能想要提供其他设置,例如:

    $(".b-select").numericFlexboxSorting({
      elToSort: "the-elements-you-want-to-sort",
      controls: {
        select: true, // fires change event
        button: false // fires click event
      }
    });
    

结论

在本文中,我们经历了创建jQuery插件的过程。 该插件利用flexbox的功能,根据其自定义数据属性的值对元素进行排序。

您如何看待:将来您会用到这种东西吗? 您是否考虑过将JavaScript和flexbox结合的其他方式? 在评论中让我知道。

From: https://www.sitepoint.com/user-sortable-lists-flexbox-jquery/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值