jQuery 单击图例元素时折叠字段集
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4658491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
collapse fieldset when legend element clicked
提问by dnagirl
I have a jQuery function which toggles the visibility of the contents of a fieldset when its legend is clicked, leaving just the fieldset border (if there is one) and the legend showing:
我有一个 jQuery 函数,它在单击字段集的图例时切换字段集内容的可见性,只留下字段集边框(如果有)和图例显示:
$('legend.togvis').click(function() {
$(this).siblings().toggle();
return false;
});
It works great unless the fieldset contains text nodes.
除非字段集包含文本节点,否则它工作得很好。
<fieldset><legend class='togvis'>Click Me</legend>
<p>I toggle when the legend is clicked.</p>
But I'm a recalcitrant text node and refuse to toggle.
</fieldset>
In an effort to toggle the text nodes too I tried this:
为了切换文本节点,我也尝试过:
$('legend.togvis').click(function() {
$(this).parent().contents().not('legend').toggle();
return false;
});
which works the same as the first function. And this:
它的工作原理与第一个函数相同。和这个:
$('legend.togvis').click(function() {
$(this).parent().contents(":not(legend)").toggle();
return false;
});
which throws the error
抛出错误
Message: 'style.display' is null or not an object
Line: 5557
Char: 3
Code: 0
URI: http://code.jquery.com/jquery-1.4.4.js
Any thoughts on how to get the entirecontents of a fieldset (minus the legend) to toggle when the legend is clicked?
关于如何在单击图例时让字段集的全部内容(减去图例)进行切换的任何想法?
ETA Solution, with many thanks to Eibx
ETA 解决方案,非常感谢 Eibx
$('legend.togvis').click(function() {
$(this).parent().contents().filter(
function() { return this.nodeType == 3; }).wrap('<span></span>');//wrap any stray text nodes
$(this).siblings().toggle();
});
回答by はると
You simply cannot make text disappear in HTML, JavaScript or CSS. It needs to be contained in a HTML element that will have display:none;
applied or something similar.
您根本无法让 HTML、JavaScript 或 CSS 中的文本消失。它需要包含在将display:none;
应用或类似的 HTML 元素中。
The following code will wrap everything into a div, and move your legend to the same level as the div, and make the div show/hide when you click on the legend.
下面的代码将把所有东西都包装成一个 div,并将您的图例移动到与 div 相同的级别,并在您单击图例时显示/隐藏 div。
$("fieldset legend").click(function() {
if ($(this).parent().children().length == 2)
$(this).parent().find("div").toggle();
else
{
$(this).parent().wrapInner("<div>");
$(this).appendTo($(this).parent().parent());
$(this).parent().find("div").toggle();
}
});
- Code: http://jsbin.com/eleva3/edit
- Preview: http://jsbin.com/eleva3
回答by Frédéric Hamidi
Since text nodes are not elements, there is no way to toggle them.
由于文本节点不是元素,因此无法切换它们。
As a last resort, if you cannot wrap them with an element, you can remove everything except the legend and add the elements and the text nodes back later:
作为最后的手段,如果您不能用元素包装它们,您可以删除除图例之外的所有内容,然后再添加元素和文本节点:
$(document).ready(function() {
$('legend.togvis').click(function() {
var $this = $(this);
var parent = $this.parent();
var contents = parent.contents().not(this);
if (contents.length > 0) {
$this.data("contents", contents.remove());
} else {
$this.data("contents").appendTo(parent);
}
return false;
});
});
You can test that solution here.
您可以在此处测试该解决方案。
回答by amosrivera
Use a div tag to separate the contents, something like:
使用 div 标签来分隔内容,例如:
<fieldset>
<legend class='togvis'>Click Me</legend>
<div class="contents">
<p>I toggle when the legend is clicked.</p>
But I'm a recalcitrant text node and refuse to toggle.
</div>
</fieldset>
Then you only need to toggle the div.
然后你只需要切换div。
$('legend.togvis').click(function() {
$(this).closest("contents").toggle();
return false;
});
Updateonly in case you cannot edit the HTML you can do the following but it will only work if all texts are within at least one tag:
仅在您无法编辑 HTML 的情况下进行更新,您可以执行以下操作,但仅当所有文本都在至少一个标签内时才有效:
$('legend.togvis').click(function() {
$(this).parents("fieldset").find("*:not('legend')").toggle();
return false;
});
Online demo here:http://jsfiddle.net/yv6zB/1/
在线演示在这里:http : //jsfiddle.net/yv6zB/1/
回答by ocket8888
Glorious Pure HTML/CSS Solution
光荣的纯 HTML/CSS 解决方案
This can be done purely with HTML and CSS, now in the year 2019.
这可以完全使用 HTML 和 CSS 完成,现在是 2019 年。
#toggle + #content {
display: none;
}
#toggle:checked + #content {
display:block;
}
legend {
width: 85%;
border: 1px solid black;
padding: 3px 6px;
cursor: pointer;
}
legend label {
width: 100%;
display: inline-block;
cursor: inherit;
}
legend label::after {
content: "▼";
float: right;
}
<body>
<form>
<fieldset>
<legend><label for="toggle">Test</label></legend>
<!-- This input has no name, so it's not submitted with the form -->
<input type="checkbox" id="toggle" checked="" hidden=""/>
<div id="content">
<label>Some text field<input type="text" name="some-text-field"/></label><br/>
<label>Some color input<input type="color" name="some-color-field"/></label>
</div>
</fieldset>
</form>
</body>
Javascript Version
Javascript 版本
While the Pure HTML/CSS Solution is clearly glorious, there's nothing wrong with using Javascript to program interactivity on a page. But I've noticed all other answers use JQuery, which is totally unnecessary in the year 2019.
虽然纯 HTML/CSS 解决方案显然非常出色,但使用 Javascript 对页面交互进行编程并没有错。但我注意到所有其他答案都使用 JQuery,这在 2019 年完全没有必要。
window.addEventListener('load', () => {
const collapser = document.getElementById('collapser');
const collapsable = document.getElementById('collapsable');
function collapse(event) {
if (event) {
event.stopPropagation();
}
collapsable.hidden = !collapsable.hidden;
}
collapser.addEventListener('click', collapse);
});
legend {
width: 85%;
border: 1px solid black;
padding: 3px 6px;
cursor: pointer;
display: inline-block;
}
legend::after {
content: "▼";
float: right;
}
<body>
<form>
<fieldset>
<legend id="collapser">Test</legend>
<div id="collapsable">
<label>Some text field<input type="text" name="some-text-field"/></label><br/>
<label>Some color input<input type="color" name="some-color-field"/></label>
</div>
</fieldset>
</form>
</body>
回答by Ivan Buttinoni
May be you simply enclose your text into the sibilig tag:
可能您只是将文本括在 silig 标签中:
<fieldset><legend class='togvis'>Click Me</legend>
<div><p>I toggle when the legend is clicked.</p>
But I'm a recalcitrant text node and refuse to toggle.</div>
</fieldset>
回答by Sean Anderson
I liked the accepted answer, but did not find it robust enough for my purposes. Just checking the length of the number of child elements does not support many scenarios. As such, I would consider using an implementation similar to:
我喜欢接受的答案,但没有发现它对我的目的来说足够强大。仅检查子元素数量的长度不支持很多场景。因此,我会考虑使用类似于以下内容的实现:
$("fieldset legend").click(function () {
var fieldset = $(this).parent();
var isWrappedInDiv = $(fieldset.children()[0]).is('div');
if (isWrappedInDiv) {
fieldset.find("div").slideToggle();
} else {
fieldset.wrapInner("<div>");
$(this).appendTo($(this).parent().parent());
fieldset.find("div").slideToggle();
}
});