将响应式页面元素与JavaScript合并

Responsive design is not about removing and shrinking web page components as the browser narrows: it’s about making the most of the space available in the viewport. Sometimes that means merging components, rather than taking them away. A prime example is the columnar layout of the kind shown above. On wide screens, the columns appear side-by-side:

自适应设计并不是要随着浏览器的缩小而删除和缩小网页组件,而是要充分利用视口中的可用空间。 有时,这意味着合并组件,而不是将其删除。 一个很好的例子是上面显示的那种柱状布局。 在宽屏幕上,各列并排显示:

Display of A, B and C elements as seperate columns

But as the viewport narrows, it may make sense to merge columns A and C together:

但是随着视口变窄,将列A和C合并在一起可能是有意义的:

Display of A and C elements merged together on the left

There are scripts (such as the excellent appendAround) that can help create this, but they all have similar disadvantages:

有一些脚本(例如出色的appendAround )可以帮助创建此脚本,但是它们都有类似的缺点:

  • Framework dependencies.

    框架依赖性。
  • The setup of “catcher” containers for moved elements can be confusing.

    用于移动元素的“捕手”容器的设置可能会造成混淆。

The reality is, you can achieve your own custom solution in just a half-dozen lines of code, as demonstrated here.

现实情况是,您只需使用六行代码即可实现自己的自定义解决方案,如此处所示。

HTML和CSS (The HTML & CSS)

The markup for this example is pretty straightforward:

此示例的标记非常简单:

<div id="wrapper">
	<nav>A</nav>
	<main>B</main>
	<aside>C</aside>
</div>

I’ll place the elements side-by-side and the same height using , although many other possibilities exist, including display: table.

尽管存在许多其他可能性,包括display: table ,但我将使用相同高度的元素。

#wrapper { 
	display: flex; width: 100%;  
}
#wrapper > * { 
	flex: .5; 
}
#wrapper nav { 
	background: hsl(90, 50%, 80%);
	display: flex;
	flex-direction: column; 
}
#wrapper main { 
	background: hsl(180, 50%, 80%); flex: 2; 
}
#wrapper aside { 
	background: hsl(270, 50%, 80%); 
}
#wrapper aside, #wrapper main { 
	min-width: 150px;
}

I’ve given each of the elements an HSL background to keep them distinct; the <main> element is set to be 4× the width of the other two via the flex property. As the <nav> element will be taking the <aside> element as a guest when the viewport narrows, I’ve set it to display as a column. This won’t disturb the content of the element, but will set the original content above the <aside> when the two are merged.

我为每个元素提供了HSL背景,以使其与众不同。 通过flex属性<main>元素设置为其他两个元素的宽度的4倍。 由于<nav>元素将在视口变窄时将<aside>元素用作来宾,因此我将其设置为显示为列。 这不会打扰元素的内容,但是当两者合并时,会将原始内容设置为<aside>以上。

使用JavaScript合并元素 (Merging Elements With JavaScript)

At the end of the page, we start our script by identifying the elements that will be affected, together with the conditions for switching:

在页面的最后,我们通过识别将受影响的元素以及切换条件来启动脚本:

var nav = document.querySelector("#wrapper > nav"),
aside = document.querySelector("#wrapper > aside"),
wrapper = document.getElementsById("wrapper"),
tablet = window.matchMedia("screen and (max-width: 800px)");

The matchMedia expression sets the viewport width at which we want to merge the elements. This movement and merge is controlled by a single function:

matchMedia表达式设置我们要合并元素的视口宽度。 此移动和合并由单个功能控制:

function combinator(state){
	aside.remove();
	if (state.matches) { 
		nav.appendChild(aside);
	} else {
		wrapper.appendChild(aside);
	}
}

You could also use the more traditional JavaScript remove method if you needed IE support.

如果需要IE支持,也可以使用更传统JavaScript删除方法

This function effectively “pops” the <aside> element in and out of <nav> at the breakpoint set by the matchMedia variable. We just have to call it:

该功能有效地将<aside>元素“弹出”在matchMedia变量设置的断点处的<nav>中。 我们只需要调用它:

combinator(tablet);

However, this will only call the function once, during the initial page load. We must also add a listener to react to any subsequent changes to the viewport:

但是,这将在初始页面加载期间仅调用一次函数。 我们还必须添加一个侦听器,以对视口的任何后续更改做出React:

tablet.addListener(combinator);

融合合并 (Blending The Merge)

Once the merge is complete, the shifted element should take some of the styles of its new parent. I would suggest adding a single-line CSS declaration:

合并完成后,转移的元素应采用其新父元素的某些样式。 我建议添加单行CSS声明:

.wrapper nav > aside { 
	width: 100%; background: inherit; 
}

Note that this declaration doesn’t have to placed inside an @media query, since we can usually assume there’s no other condition in which an <aside> element might be placed inside <nav>.

请注意,此声明不必放在@media查询中,因为我们通常可以假设没有其他条件可以将<aside>元素放置在<nav>

Of course there are many other possibilities for this technique; I’ll explore more in future articles.

当然,这种技术还有许多其他可能性。 我将在以后的文章中进一步探讨。

翻译自: https://thenewcode.com/949/Merging-Responsive-Page-Elements-with-JavaScript

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值