使用jQuery并在每个h1内的内容周围有一个包装容器,我可以很容易地隐藏它们。
但没有包装容器,怎么会这样做?
在下一个h1之前做一些隐藏所有事情的最佳方法是什么?
我没有使用jQuery,因为这是React应用程序的一部分。
h1 {
border-bottom: solid 1px #000;
}
span {
float: right;
}

<h1>h1 <span>x</span></h1>
<p>test 1</p>
<h2>h2</h2>
<p>test 2</p>
<h1>h1-1 <span>x</span></h1>
<p>test 3</p>
<h2>h2-2</h2>
<p>test 4</p>
&#13;
或在div标签中的下一个h1之后和之前包装所有内容?
答案 0 :(得分:4)
我能用这个css做到这一点。只需添加课程&#34;开始&#34;从你想要开始折叠元素和类的h1到#34; upto&#34;到你希望元素崩溃的h1。
<强> CSS 强>
.start ~ *:not(h1) {
display: none;
}
.upto ~ * {
display: block !important;
}
HTML
<h1 class='start'>h1 <span>x</span></h1>
...
<h1 class ='upto'>h1-1 <span>x</span></h1>
这里将隐藏start和upto之间的所有元素。您可以通过添加&#39; start&#39;来实现折叠效果。和&#39; upto&#39;相应的课程
将类添加到下一个h1也可以通过Javascript完成。所以,我可以有一个简单的js函数来设置&#39; start&#39;以及&#39; upto&#39;。
function collapse(startHeaderNumber, uptoHeaderNumber) {
var allHeaders = document.getElementsByTagName("h1");
var totalNoOfHeaders = allHeaders.length;
if (startHeaderNumber > totalNoOfHeaders) {
return;
}
var startHeader = allHeaders[startHeaderNumber - 1];
startHeader.classList.add('start');
if (uptoHeaderNumber <= totalNoOfHeaders) {
var uptoHeader = allHeaders[uptoHeaderNumber - 1];
uptoHeader.classList.add('upto');
}
}
你可以简单地称之为
collapse(1 ,2)
它会折叠标题1和标题2之间的所有项目。或者,您可以将其称为
collapse(1)
会将第一个标题中的所有元素折叠到最后一个。
要获得完整演示,请参阅此fiddle
答案 1 :(得分:2)
sounds like you want something similar to jQuery's nextUntil()
function. Here is a good guide to doing that in vanilla js. The code ends up looking like this:
var nextUntil = function (elem, selector, filter) {
// Setup siblings array
var siblings = [];
// Get the next sibling element
elem = elem.nextElementSibling;
// As long as a sibling exists
while (elem) {
// If we've reached our match, bail
if (elem.matches(selector)) break;
// If filtering by a selector, check if the sibling matches
if (filter && !elem.matches(filter)) {
elem = elem.nextElementSibling;
continue;
}
// Otherwise, push it to the siblings array
siblings.push(elem);
// Get the next sibling element
elem = elem.nextElementSibling;
}
return siblings;
};
I obviously don't know the context behind what you are doing, but I reckon there's a better way around it by altering the HTML. This could potentially even let you do some of this with just css nth child selectors
答案 2 :(得分:1)
您可以递归使用previousElementSibling来获取h1
元素的所有兄弟姐妹。以下是使用previousElementSibling
:
const elems = document.getElementsByTagName('h1');
for (let i = 0; i < elems.length; i++) hidePrev(elems[i]);
function hidePrev(elem)
{
var pre = elem.previousElementSibling;
if (!pre) return;
pre.style.display = 'none';
hidePrev(pre);
}
&#13;
h1 {
border-bottom: solid 1px #000;
}
span {
float: right;
}
&#13;
<h1>h1 <span>x</span></h1>
<p>test 1</p>
<h2>h2</h2>
<p>test 2</p>
<h1>h1-1 <span>x</span></h1>
<p>test 3</p>
<h2>h2-2</h2>
<p>test 4</p>
&#13;
答案 3 :(得分:1)
我评论了代码。我希望你能理解这里发生了什么,但如果没有,请在下面评论。
function hideUntilNextSiblingWithSameName(elementName) {
/*
* @Param {elementName: String}
* Hide all elements until the next one with the same name
*/
var trackH1 = 0,
element = document.getElementsByTagName(elementName)[0],
node = element.parentNode.firstChild;
do {
// Keep truck of element with the same name.
if (node.tagName === element.tagName) trackH1 += 1;
// Stop if catch element with same name
if (trackH1 == 2) break;
// Do not hide link, script, style and text node
if (node.nodeType === 3 || node.tagName === "LINK" || node.tagName === "SCRIPT" || node.tagName === "STYLE") continue;
// Hide element
else {
node.style.visibility = "hidden";
}
} while (node = node.nextSibling)
}
hideUntilNextSiblingWithSameName("h1")
&#13;
<h1>h1 <span>x</span></h1>
<p>test 1</p>
<h2>h2</h2>
<p>test 2</p>
<h1>h1-1 <span>x</span></h1>
<p>test 3</p>
<h2>h2-2</h2>
<p>test 4</p>
<link rel="stylesheet" href="">
<script></script>
<style></style>
&#13;
https://codepen.io/anon/pen/QxGVNG
此刻,我隐藏了元素。但是,如果您甚至不想显示元素,请在else子句中使用 node.style.display = "none";
而不是 node.style.visibility = "hidden";
。
答案 4 :(得分:0)
您可以通过以下更简单的方式执行此操作。我们的想法是在这种情况下找到节点的直接父节点body
,并找到它的所有直接子节点。
然后,开始删除元素,直到我们找到所需的元素。在这个例子中,我试图隐藏元素,但你只需改变代码就可以删除它们。
以下是一个有效的演示:
const elems = document.querySelectorAll('body > *');
const elemBefore = document.querySelectorAll('h1')[1];
for (let i = 0; i < elems.length; i++) {
let elem = elems[i];
if (elem === elemBefore) {
break;
}
elem.style.display = 'none';
}
h1 {
border-bottom: solid 1px #000;
}
span {
float: right;
}
<h1>h1 <span>x</span></h1>
<p>test 1</p>
<h2>h2</h2>
<p>test 2</p>
<h1>h1-1 <span>x</span></h1>
<p>test 3</p>
<h2>h2-2</h2>
<p>test 4</p>
答案 5 :(得分:0)
也许你可以使用一个技巧并通过css隐藏h1和h2后面的
:
const selector = document.querySelectorAll('h1, h2');
const clickH = function (event) {
const h = event.target;
const attr = h.getAttribute('class');
if (attr === '') {
h.setAttribute('class', 'closed')
return undefined;
}
h.setAttribute('class', '')
}
selector.forEach((h) => {
h.setAttribute('class', 'closed')
h.addEventListener('click', clickH);
})
&#13;
h1, h2 {
position: relative;
border-bottom: solid 1px #000;
background-color: #fff;
height: 50px;
border-bottom: solid 1px #000;
display: block;
z-index: 2;
margin-bottom: 0;
}
.closed {
margin-bottom: -50px;
}
p {
height: 30px;
}
span {
float: right;
}
&#13;
<h1>h1 <span>x</span></h1>
<p>test 1</p>
<h2>h2</h2>
<p>test 2</p>
<h1>h1-1 <span>x</span></h1>
<p>test 3</p>
<h2>h2-2</h2>
<p>test 4</p>
&#13;