内容切换组件的三种构建方式:jQuery,JS,CSS

不久之前,我的一个朋友构建了一个UI组件,用于根据当前对<select>元素的<select>来更改页面的内容。 她的代码有效,但是对于JavaScript来说是新手,她在jQuery中构建了该组件,并要求我帮助对其进行优化。

在不完全复制代码的同时,我创建了以下示例来展示她尝试创建的UI组件的类型:

<div class="select-area">
  <select name="choose" id="choose" class="input-select">
    <option value="nul" selected>Make a Selection</option>
    <option value="opt1">Option 1</option>
    <option value="opt2">Option 2</option>
    <option value="opt3">Option 3</option>
  </select>
</div>

<section class="jqueryOptions opt1">
  <div class="content">
    <h2>Option 1 Content</h2>
    <p>
      ...
    </p>
  </div>
</section>

<section class="jqueryOptions opt2">
  <div class="content">
    <h2>Option 2 Content</h2>
    <p>
      ...
    </p>
  </div>
</section>

<section class="jqueryOptions opt3">
  <div class="content">
    <h2>Option 3 Content</h2>
    <p>
      ...
    </p>
  </div>
</section>

经过一点优化后,这是我们最终用来切换所选内容块的显示状态的jQuery。

$(function() {
  $('.jqueryOptions').hide();

  $('#choose').change(function() {
    $('.jqueryOptions').slideUp();
    $('.jqueryOptions').removeClass('current-opt');
    $("." + $(this).val()).slideDown();
    $("." + $(this).val()).addClass('current-opt');
  });
});

那么这是怎么回事?

上面的jQuery函数查找所有具有'jqueryOptions'类的内容块,并默认隐藏它们。

然后,当用户改变所选择的选项select的输入(其具有的“选择”的ID),则函数关闭使用jQuery的任何潜在的打开内容块.slideUp()方法,然后与打开所选择的选项slideDown() 它通过获取所选选项的值(称为this )并使用与“ this”中的值匹配的类名引用该元素来做到这一点。

所以:

<option value="opt1">Option 1</option>

火柴:

<section class="options opt1">
  ...
</section>

这是一个演示:

请参阅CodePen带有 SitePoint( @SitePoint )的jQuery的Pen 内容切换组件

或在这里查看工作的整页演示

那还不算难,是吗?

那么,为什么不就这样呢?

jQuery解决方案的问题在于,我们仅包含了这小部分功能的jQuery(压缩后为98kb)。 我们可以做得更好。

在不更改标记的情况下,让我们看看如何首先使用原始JavaScript然后仅使用CSS来创建相同的效果。

首先,让我们考虑一下要重新产生这种效果需要发生什么。

  • 默认情况下,内容需要隐藏。
  • 进行选择后,我们需要显示所选内容。
  • 选择新选项时,我们还需要隐藏所有以前打开的内容。

在代码中将对此进行解释,但还有其他一些内容,但这是我们需要牢记的三个主要要点。 其中之一是默认情况下隐藏内容,我们默认情况下可以使用CSS进行设置,所以这是一项无效的规定。 两个要走。

创建Vanilla JavaScript版本

首先,让我们设置一些变量以使我们的生活更轻松。

var selectInput = document.getElementById('choose'),
    panels = document.querySelectorAll('.options'),
    currentSelect,
    i;

现在,我们有了变量,可以轻松访问输入选择( selectInput ),不同的内容面板( panels ),当前选择的占位符以及迭代器。

接下来,我们需要编写一些函数来帮助我们处理上面项目符号列表中的项目。

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

首先从最后一个项目符号开始,当选择一个新选项时,我们需要确保隐藏所有可见内容。 为此,我们将创建自己的函数:

function clearShow() {
  for ( i = 0; i < panels.length; i++ ) {
    panels[i].classList.remove('show');
  }
}

clearShow()函数正在做一些事情。 首先,它使用我们的panels变量(这是页面上所有节点的列表,带有“选项”类),并对其进行迭代(在本例中为三个),并从所有节点中删除“ show”类。

“显示”类使内容在我们的页面上可见。

现在我们有了从每个内容块中删除“显示”类的方法,我们需要一种将“显示”添加到选定面板的方法。

function addShow(showThis) {
  var el = document.getElementsByClassName(showThis);
  for ( i = 0; i < el.length; i++ ) {
     el[i].classList.add('show');
   }
}

addShow()函数接收一个名为showThis的参数,并将“ show”类添加到具有与select输入的当前值相匹配的类的面板节点。 现在,我们仍然需要另外一块将showThis值传递给addShow()

function vUpdate() {
  currentSelect = selectInput.value;

  clearShow();
  addShow(currentSelect);
}

selectInput.addEventListener('change', vUpdate);

每当更新选择输入(通过change事件检测到vUpdate()时,都会执行vUpdate()函数。 因此,当vUpdate()运行时,它将执行以下操作:

  • 获取selectInput的当前值并将其存储在currentSelect变量中。
  • 执行clearShow函数以从面板中删除任何.show痕迹。
  • 执行addShow()函数,传入currentSelect以完成该函数的缺失部分
  • .show分配给具有与选择输入的当前值匹配的类的面板。

您可以查看下面的演示以查看全部操作:

请参阅CodePen带有 SitePoint( @SitePoint )的香草JavaScript的Pen 内容切换组件

或者,您可以在此处查看整页演示

但是在继续之前...如果您从选择输入中选择一个选项,然后刷新页面,则输入的值可能会保留,但不会显示相应的面板。

我们可以通过添加以下内容来解决此问题:

if (selectInput.value !== 'nul') {
  currentSelect = selectInput.value;
  addShow(currentSelect);
}

if结构将检查selectInput值是否不是nul 。 如果是这种情况,它将把当前选择的值传递给addShow()函数,从而在重新加载页面时触发该事件。 修复页面刷新且select元素显示一个值但未显示适当内容的罕见情况很方便。

最后,在需要支持Internet Explorer 9或更低版本的情况下,我们不能使用classList() 。 要解决此问题,以下是用于在元素中添加和删除类的函数。 上面的CodePen演示使用了以下功能:

function addClass(elm, newClass) {
    elm.className += ' ' + newClass;
}

function removeClass(elm, deleteClass) {
  elm.className = elm.className.replace(new RegExp("\\b" + deleteClass + "\\b", 'g'), '').trim();
  /* the RegExp here makes sure that only
     the class we want to delete, and not
     any other potentially matching strings 
     get deleted.
  */
}

只能用CSS做到吗?

利用我制作的许多组件,我想尝试看看在纯CSS解决方案中复制它们有多接近。 但是,如果jQuery和Vanilla JavaScript解决方案可以基于相同的标记,则仅需修改CSS解决方案。

与以前的版本相比,最大,最重要的变化是需要完全替换select 。 在前面的示例依靠select元素的值更改将显示哪个内容面板的情况下,仅CSS并不了解这些值更改,因此无法利用不同的值来切换不同的选择器链。

select元素将只需要重新创建,然后,我们将使用所谓的“复选框/单选按钮hack”。

这是我们新的“ select元素”的标记。

<input type='checkbox' class="invis" id="open_close" />
<input type='radio' name='opts' class="invis" id="opt1" />
<input type='radio' name='opts' class="invis" id="opt2" />
<input type='radio' name='opts' class="invis" id="opt3" />

<header class="header-base">
  <div class="content">
    <p>
      Choose an Option
    </p>

    <div class="select-area">
      <label for="open_close" class="input-select">
        ...
      </label>

      <ul class="select-options">
        <li>
          <label for="opt1">Option 1</label>
        </li>
        <li>
          <label for="opt2">Option 2</label>
        </li>
        <li>
          <label for="opt3">Option 3</label>
        </li>
      </ul>
    </div>

  </div>
</header>

基本上,这里所做的是在HTML和CSS允许的情况下,尽可能多地重现select元素,而无需JavaScript的帮助。 标头上方的输入用作站点上select面板和内容面板的样式锚的控件。 新的无序列表和标签成为我们的新select元素。

opt1,opt2和opt3的标签会更改具有相应ID的单选按钮的选中状态。 在CSS中,根据选择了哪个单选按钮,使用常规的同级选择器将相应的面板设置为显示。

#opt1:checked ~ main .opt1,
#opt2:checked ~ main .opt2,
#opt3:checked ~ main .opt3 {
  display: block;
  height: 100%;
  overflow: visible;
  visibility: visible;
}

有很多细节可以复制select元素,这些细节取决于要检查的适当单选按钮和CSS的常规同级选择器。 有关常规兄弟选择器的更多信息以及仅CSS可以完成的其他整洁的事情,您应该查看我的文章CSS可以做到吗?CSS变形菜单

这些文章中我没有介绍的是重新创建select元素的一些较困难的方面。

很简单,我们希望根据所按下的选项立即更新页面的内容。 我们遇到的问题是,如果select元素和内容块均基于相同的单选按钮,则单击select元素会使内容消失。 不仅如此,如果打开了select选项,然后单击其中一个选项,则这些选项将消失,然后显示内容块。

为了缓解此UX缺陷,我添加了<input type="checkbox" class="invis" id="open_close" /> 。 现在可以同时打开select元素和当前内容。 缺点是select元素在单击选项时不会关闭,而是在再次单击时才关闭。 不理想。 但是,我觉得这是比我之前提到的更好的体验。 为了帮助吸引人们注意再次选择要关闭的select元素,我在打开元素时将向下箭头更改为X:

#open_close:checked ~ .header-base .select-area .select-options {
  opacity: 1;
  visibility: visible;
}

#open_close:checked ~ .header-base .select-area:after {
  border: none;
  content: 'X';
  top: -24px;
}

我要重新创建的真正select元素的另一个功能是,当选择一个新选项时,主select元素的文本将变为该选项。 使用:before伪元素,可以根据选择哪个单选按钮来更改文本:

.input-select:before {
  content: 'Make a Selection';
}

#opt1:checked ~ .header-base .input-select:before {
  content: 'Option 1';
}

#opt2:checked ~ .header-base .input-select:before {
  content: 'Option 2';
}

#opt3:checked ~ .header-base .input-select:before {
  content: 'Option 3';
}

通过查看纯CSS的CodePen演示的源代码,可以看到以上内容以及更多内容:

请参阅CodePen具有 SitePoint( @SitePoint )的纯CSS的Pen 内容切换组件

这是完整版

最后,简要总结一下优缺点……

我们只是考虑了三种不同的方式来使用jQuery创建相似的接口,然后使用普通JavaScript,然后仅使用CSS。 每种技术都有其优点和缺点。

到目前为止, jQuery解决方案最简单,几乎没有代码。

jQuery解决方案的缺点是,如果只需要该接口的库,那么您将添加整个库用于一个目的。

利用CSS转换和过渡的Vanilla JavaScript解决方案非常类似于jQuery解决方案。 最小化它的时钟为486字节–显然比jQuery替代要小得多。

该解决方案的缺点是并非所有浏览器都支持某些JavaScript,并且要支持这些浏览器,您需要编写其他变通方法(如我所做的那样)。

纯CSS解决方案非常适合那些希望尝试CSS的人或对JavaScript不太熟悉的人。 但是,它需要大量重复的,依赖于标记CSS才能正常工作,并且可能对网站的可访问性产生负面影响,因为您必须以不希望使用的方式使用元素。

无论您偏向哪种解决方案,请务必权衡每种解决方案的利弊,并致力于提供最佳的用户体验。

翻译自: https://www.sitepoint.com/content-switching-component-built-three-ways/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值