简体   繁体   English

当 html 结构不确定时,CSS 选择器选择父项下的第一个和最后一个元素

[英]CSS selector to select first and last element under parent, when html structure is not deterministic

I have following HTML structure.我有以下HTML结构。 Is it possible to select first and last my-item element under parent element purely by CSS ?是否可以纯粹通过CSS选择parent元素下的第一个和最后一个my-item元素?

row in which my-item element is can be wrapped in other div s and (Angular) component elements. row ,其中my-item元件可以包裹在其他div S和(角) component的元件。 Also component elements can be nested within each other. component元素也可以相互嵌套。 This is HTML structure is generated based on current page.这是基于当前页面生成的HTML结构。

In JavaScript I would accomplish this by selecting all my-item elements under parent as a flat list and selecting a first and last of them.在 JavaScript 中,我将通过选择parent下的所有my-item元素作为平面列表并选择其中的第一个和最后一个来完成此操作。

UPDATE: Update HTML template to more resemble my actual page content.更新:更新HTML模板以更接近我的实际页面内容。

 var parentElement = document.querySelector('.parent'); var myItems = parentElement.querySelectorAll('.my-item'); var firstItem = myItems[0]; var lastItem = myItems[myItems.length-1]; firstItem.classList.add('red-background'); lastItem.classList.add('red-background');
 .red-background { background-color: red; }
 <div class="parent"> <person-component> <div class="template"> <div class="row"> <component-row-template> <div class="col"> <div class="my-item">Select me!</div> </div> <div class="col"> <div class="my-item">Not me</div> </div> </component-row-template> <component-row-template> <div class="col"> <div class="my-item">Not me</div> </div> </component-row-template> </div> <div class="row-separator"></div> <div class="row"> <component-row-template> <div class="col"> <div class="my-item">Not me</div> </div> <div class="col"> <div class="my-item">Not me</div> </div> </component-row-template> </div> </div> </person-component> <div class="row-separator"></div> <organization-component> <div class="template"> <div class="row"> <component-row-template> <div class="col"> <div class="my-item">Not me</div> </div> </component-row-template> </div> <div class="row-separator"></div> <div class="row"> <component-row-template> <div class="col"> <div class="my-item">Not me</div> </div> <div class="col"> <div class="my-item">Not me</div> </div> </component-row-template> </div> <div class="row-separator"></div> <person-component> <div class="template"> <div class="row"> <component-row-template> <div class="col"> <div class="my-item">Not me</div> </div> <div class="col"> <div class="my-item">Not me</div> </div> </component-row-template> </div> <div class="row"> <component-row-template> <div class="col"> <div class="my-item">Not me</div> </div> <div class="col"> <div class="my-item">Not me</div> </div> </component-row-template> </div> </div> </person-component> </div> </organization-component> <div class="row-separator"></div> <div class="row"> <row-template> <div class="col"> <div class="my-item">Not me</div> </div> <div class="col"> <div class="my-item">Not me</div> </div> </row-template> </div> <div class="row-separator"></div> <div class="row"> <row-template> <div class="col"> <div class="my-item">Not me</div> </div> <div class="col"> <div class="my-item">Select me!</div> </div> </row-template> </div> </div>

The below code can work with the assumption that every child div of the parent has the desired ".my-item" and the every ".my-item" is inside a ".col".下面的代码可以假设父级的每个子 div 都具有所需的“.my-item”并且每个“.my-item”都在“.col”中。

It will select the first and the last div from the direct siblings of ".parent" and then will try to find the first and last ".col" and apply the rule to the ".my-item" inside them.它将从“.parent”的直接兄弟中选择第一个和最后一个div,然后尝试找到第一个和最后一个“.col”并将规则应用于其中的“.my-item”。

.parent > div:last-of-type .col:last-of-type .my-item, 
.parent > div:first-of-type .col:first-of-type .my-item  {
  background-color: red;
}

If that's not the case and you really don't know anything about the html structure at all, then I am afraid that CSS cannot help you..如果不是这样,而且你真的对 html 结构一无所知,那么恐怕 CSS 帮不了你。

Assuming that all .my-item s are always wrapped inside a .col that is in turn wrapped inside at least another div (section) and that each section has only one .row (assumption taken from your example), yes it is possible to achieve what you want using a purely CSS approach.假设所有.my-item始终包裹在.col ,而.col又包裹在至少另一个div (section) ,并且每个部分只有一个.row (假设取自您的示例),是的,可以使用纯 CSS 方法实现您想要的。 The approach is:做法是:

  • Select .parent , as we're only interested only in selecting .my-item inside this element选择.parent ,因为我们只对在这个元素中选择.my-item感兴趣
  • As all .my-item s always have a div container (whether it be a nested container with class section or simply inside a row container), we can specifically determine which wrapper containers are the first and last.由于所有.my-item总是有一个div容器(无论是带有类section的嵌套容器还是只是row容器内),我们可以具体确定哪个包装容器是第一个和最后一个。 These first and last containers, respectively, must be the container in which the first and last my-item are contained.这些第一个和最后一个容器必须分别是包含第一个和最后一个my-item的容器。
  • As all .section container only has one .row , you can easily get the first and last .col of each .section .由于所有.section容器只有一个.row ,因此您可以轻松获取每个.section的第一个和最后一个.col This means that to get the first .my-item , simply select the first .col and from the first .section wrapper and apply the style to .my-item .这意味着要获得第一个.my-item ,只需从第一个.section包装器中选择第一个.col并将样式应用于.my-item Same logic works for your last .my-item .相同的逻辑适用于您的最后一个.my-item

Here is a minimal working example below:下面是一个最小的工作示例:

 let firstChild = document.querySelector('.parent > div:first-child .col:first-child .my-item') let lastChild = document.querySelector('.parent > div:last-child .col:last-child .my-item') console.log(firstChild, lastChild)
 .parent > div:first-child .col:first-child .my-item { background: #000; color: #FFF; } .parent > div:last-child .col:last-child .my-item { background: red; color: #FFF; }
 <div class="parent"> <div class="main-section"> <div class="section-wrapper"> <div class="row"> <div class="col"> <div class="my-item">Select me!</div> </div> <div class="col"> <div class="my-item">Not me</div> </div> </div> </div> </div> <div class="section-wrapper"> <div class="row"> <div class="col"> <div class="my-item">Not me</div> </div> <div class="col"> <div class="my-item">Not me</div> </div> </div> </div> <div class="row"> <div class="col"> <div class="my-item">Not me</div> </div> <div class="col"> <div class="my-item">Select me!</div> </div> </div> </div>

As mentioned, this code works if the above assumption is true.如前所述,如果上述假设成立,则此代码有效。 One easy example of when this code will break would be when there may be more that two .row s existing in one section -like wrapper.这段代码何时会中断的一个简单示例是,在一个.row section的包装器中可能存在两个以上的.row

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM