我有以下代码,它采用一些简单的HTML并使用一些JS来显示/隐藏它。
// So forEach can be used on 'querySelectorAll' and 'getElementsByClassName' collections
HTMLCollection.prototype.forEach = NodeList.prototype.forEach = Array.prototype.forEach;
function HideShow(e, itm_id) {
var tbl = document.getElementById(itm_id);
if (tbl.style.display == "") {
e.innerHTML = "<i class='fa fa-plus' aria-hidden='true'></i>";
tbl.style.display = "none";
} else {
e.innerHTML = "<i class='fa fa-minus' aria-hidden='true'></i>";
tbl.style.display = "";
}
}
// -----------------------------------------------------------
// NEW Code
// New toggle links
let toggles = document.getElementsByClassName('toggler');
// Attach click event
toggles.forEach(link => link.addEventListener('click', fnToggleElement))
// Event handler definition
function fnToggleElement() {
let elements = document.querySelectorAll(`[id^="${this.dataset.selector}"]`)
let className = 'd-none'
elements.forEach(el => {
let fas = el.parentElement.closest('.item,.sub-container,.menu-container').querySelectorAll('.fa')
if (el.classList.contains(className)) {
el.classList.remove(className)
fas.forEach(fa => {
fa.classList.remove('fa-plus')
fa.classList.add('fa-minus')
})
} else {
el.classList.add(className)
fas.forEach(fa => {
fa.classList.remove('fa-minus')
fa.classList.add('fa-plus')
})
}
})
}
body {
background: #fff;
margin-top: 20px;
}
h1.heading {
font: 'Oswald';
text-transform: uppercase;
}
td {
background: #f1f1f1;
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 20px;
margin: 5px;
border-top: 1px solid #fff;
border-left: 1px solid #fff;
}
.wrappingmapping {
margin: 20px 0 0 20px;
border-radius: 85px;
overflow: hidden;
border: 10px solid #fff;
box-shadow: 0 0 10px #999;
}
.menu-container {
margin-bottom: 50px;
}
.sub-container {
padding: 20px;
background: repeating-linear-gradient( -45deg, #999, #999 10px, #888 10px, #888 20px);
border-radius: 2px;
}
.heading {
color: #000;
background: #ccc;
border-bottom: 1px solid #ccc;
padding: 5px;
}
.indent {
background: #fff;
padding: 20px;
}
.icon {
width: 64px;
height: 64px;
}
.item {
background: #fff;
padding-left: 10px;
background: #f1f1f1;
border-top: 1px solid #fff;
font-size: 30px;
}
.gallery {
width: 100%;
*width: 99.94877049180327%;
margin: 0;
padding: 0;
}
.gallery.grid li {
margin: 2px 5px;
}
.gallery.grid li {
margin: 2px 5px;
display: block;
}
.gallery.grid li:hover {
background: #ccc;
}
.gallery.grid li {
display: inline-block;
border-top: 1px solid #eee;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
border-left: 1px solid #eee;
padding: 6px;
position: relative;
-moz-box-sizing: border-box;
border-radius: 3px 3px 3px 3px;
background: #fff;
}
.gallery a {
display: block;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<div class="container-fluid">
<div>
<span class="toggler btn btn-primary btn-lg" data-selector="parent_">Toggle</span>
</div>
<hr />
<!-- first section -->
<div id="activities" class="menu-container">
<h1 class="heading">
<a href="javascript:;" onclick="HideShow(this,'parent_activities')">
<i class="fa fa-minus" aria-hidden="true"></i>
</a> Activities
</h1>
<div id="parent_activities" class="sub-container">
<ul class="gallery grid">
<li>
<a href="#"><img title="jack-o-lantern - " src="https://cdn.jsdelivr.net/emojione/assets/svg/1f383.svg" class="icon" role="presentation"></a>
</li>
</ul>
</div>
</div>
<!-- second section -->
<div id="animals-nature" class="menu-container">
<h1 class="heading">
<a href="javascript:;" onclick="HideShow(this,'parent_animals-nature')">
<i class="fa fa-minus" aria-hidden="true"></i>
</a> Animals & Nature
</h1>
<div id="parent_animals-nature" class="sub-container">
<ul class="gallery grid">
<li>
<a href="#"><img title="monkey face - " src="https://cdn.jsdelivr.net/emojione/assets/svg/1f435.svg" class="icon" role="presentation"></a>
</li>
</ul>
</div>
</div>
</div>
代码工作正常,蓝色切换按钮显示并隐藏其下方的DIV。
然而,我遇到的问题是,当DIV折叠时,我无法点击蓝色加号图标来单独展开div。再次展开它们的唯一方法是使用切换按钮,而不是能够使用蓝色加号图标上的链接。
可能不可能做我想做的事情,但我觉得我可能并不遥远,但我正在努力研究如何继续,因为我正在使用我之前提供的解决方案问题,而不是一个“真正的”程序员并不真正理解解决方案中的JS代码如何工作,我只知道它有一个小问题。
答案 0 :(得分:1)
无法使用的主要原因是您可以使用例如
内联更改显示值 tbl.style.display = "none";`
由于内联样式通常具有更高的特异性,它们会覆盖外部CSS规则(如此处使用d-none
),除非在这些类中开始使用!important
,当然,这不推荐作为解决此类问题的一般方法。
通过执行类似的操作,使用按钮切换班级
if (tbl.className.indexOf("d-none") > -1 ) {
e.innerHTML = "<i class='fa fa-plus' aria-hidden='true'></i>";
tbl.classList.remove("d-none");
} else {
e.innerHTML = "<i class='fa fa-minus' aria-hidden='true'></i>";
tbl.classList.add("d-none");
}
Stack snippet
// So forEach can be used on 'querySelectorAll' and 'getElementsByClassName' collections
HTMLCollection.prototype.forEach = NodeList.prototype.forEach = Array.prototype.forEach;
function HideShow(e, itm_id) {
var tbl = document.getElementById(itm_id);
if (tbl.className.indexOf("d-none") > -1 ) {
e.innerHTML = "<i class='fa fa-plus' aria-hidden='true'></i>";
tbl.classList.remove("d-none");
} else {
e.innerHTML = "<i class='fa fa-minus' aria-hidden='true'></i>";
tbl.classList.add("d-none");
}
}
// -----------------------------------------------------------
// NEW Code
// New toggle links
let toggles = document.getElementsByClassName('toggler');
// Attach click event
toggles.forEach(link => link.addEventListener('click', fnToggleElement))
// Event handler definition
function fnToggleElement() {
let elements = document.querySelectorAll(`[id^="${this.dataset.selector}"]`)
let className = 'd-none'
elements.forEach(el => {
let fas = el.parentElement.closest('.item,.sub-container,.menu-container').querySelectorAll('.fa')
if (el.classList.contains(className)) {
el.classList.remove(className)
fas.forEach(fa => {
fa.classList.remove('fa-plus')
fa.classList.add('fa-minus')
})
} else {
el.classList.add(className)
fas.forEach(fa => {
fa.classList.remove('fa-minus')
fa.classList.add('fa-plus')
})
}
})
}
body{
background: #fff;
margin-top:20px;
}
h1.heading {
font: 'Oswald';
text-transform: uppercase;
}
td { background: #f1f1f1; border-bottom:1px solid #ccc; border-right:1px solid #ccc; padding:20px; margin:5px; border-top:1px solid #fff; border-left:1px solid #fff; }
.wrappingmapping {
margin:20px 0 0 20px;
border-radius:85px;
overflow:hidden;
border:10px solid #fff;
box-shadow:0 0 10px #999;
}
.menu-container {
margin-bottom: 50px;
}
.sub-container {
padding: 20px;
background: repeating-linear-gradient(
-45deg,
#999,
#999 10px,
#888 10px,
#888 20px
);
border-radius: 2px;
}
.heading {
color: #000;
background: #ccc;
border-bottom: 1px solid #ccc;
padding: 5px;
}
.indent {
background: #fff;
padding: 20px;
}
.icon {
width: 64px;
height: 64px;
}
.item {
background: #fff;
padding-left: 10px;
background: #f1f1f1;
border-top: 1px solid #fff;
font-size: 30px;
}
.gallery {
width: 100%;
*width: 99.94877049180327%;
margin: 0;
padding: 0;
}
.gallery.grid li {
margin: 2px 5px;
}
.gallery.grid li {
margin: 2px 5px;
display: block;
}
.gallery.grid li:hover {
background: #ccc;
}
.gallery.grid li {
display: inline-block;
border-top: 1px solid #eee;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
border-left: 1px solid #eee;
padding: 6px;
position: relative;
-moz-box-sizing: border-box;
border-radius: 3px 3px 3px 3px;
background: #fff;
}
.gallery a {
display: block;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<div class="container-fluid">
<div>
<span class="toggler btn btn-primary btn-lg" data-selector="parent_">Toggle</span>
</div>
<hr />
<!-- first section -->
<div id="activities" class="menu-container">
<h1 class="heading">
<a href="javascript:;" onclick="HideShow(this,'parent_activities')">
<i class="fa fa-minus" aria-hidden="true"></i>
</a> Activities
</h1>
<div id="parent_activities" class="sub-container">
<ul class="gallery grid">
<li><a href="#"><img title="jack-o-lantern - " src="https://cdn.jsdelivr.net/emojione/assets/svg/1f383.svg" class="icon" role="presentation"></a></li>
</ul>
</div>
</div>
<!-- second section -->
<div id="animals-nature" class="menu-container">
<h1 class="heading">
<a href="javascript:;" onclick="HideShow(this,'parent_animals-nature')">
<i class="fa fa-minus" aria-hidden="true"></i>
</a> Animals & Nature
</h1>
<div id="parent_animals-nature" class="sub-container">
<ul class="gallery grid">
<li><a href="#"><img title="monkey face - " src="https://cdn.jsdelivr.net/emojione/assets/svg/1f435.svg" class="icon" role="presentation"></a></li>
</ul>
</div>
</div>
</div>
答案 1 :(得分:0)
由于您已经在网页中添加了JQuery,我为您的问题编写了一个JQuery解决方案。这看起来比在JS中编写所有内容更清晰。如果你想坚持使用JS,你可以为JS重写相同的逻辑。 问题是你没有处理所有的情况。
$(document).ready(function() {
// all of them are already open so set toggle accordingly
$('.toggler').addClass('toggle-open');
// on click
$('.heading > a').on('click', function(event){
// prevent href action
event.preventDefault();
// change hedding icon
// If - then make + else make -
if ( $(this).find('i').hasClass('fa-minus') ) {
// change of - to +
$(this).find('i').removeClass('fa-minus').addClass('fa-plus');
// hide sub container
$(this).parent().parent().find('.sub-container').css("display", "none");
// give an indication of state
$(this).parent().parent().find('.sub-container').addClass('closed');
// if this action made all closed sub-container but toggle thinks any sub-container is open, indicate all closed state
if ( $('.sub-container.closed').length == $('.menu-container').length ) {
$('.toggler').removeClass('toggle-open');
}
}
else if ( $(this).find('i').hasClass('fa-plus') ) {
// change + to -
$(this).find('i').removeClass('fa-plus').addClass('fa-minus');
// show sub container
$(this).parent().parent().find('.sub-container').css("display", "block");
// give an indication of state
$(this).parent().parent().find('.sub-container').removeClass('closed');
// if this action made any open sub-container but toggle thinks all are off, indicate open state
$('.toggler').addClass('toggle-open');
}
});
// toggler actions
$('.toggler').on('click', function(){
// we use toggle-open class to check any sub-container is open or all sub-container closed
// if toggle-open class is there which means all sub-container or any sub-container is open
// change if it is all sub-container open or any sub-container open
if ( $(this).hasClass('toggle-open') ) {
// close all sub-container
$('.heading').each(function() {
// here each item is taken then closes it, $(this) refers the context
$(this).find('i').removeClass('fa-minus').addClass('fa-plus');
$(this).parent().find('.sub-container').css("display", "none");
$(this).parent().parent().find('.sub-container').addClass('closed');
});
// set all closed mode
$('.toggler').removeClass('toggle-open');
}
else{
// open all
$('.heading').each(function() {
$(this).find('i').removeClass('fa-plus').addClass('fa-minus');
$(this).parent().find('.sub-container').css("display", "block");
$(this).parent().parent().find('.sub-container').removeClass('closed');
});
// indicate sub-container is open
$('.toggler').addClass('toggle-open');
}
});
});
body {
background: #fff;
margin-top: 20px;
}
h1.heading {
font: 'Oswald';
text-transform: uppercase;
}
td {
background: #f1f1f1;
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 20px;
margin: 5px;
border-top: 1px solid #fff;
border-left: 1px solid #fff;
}
.wrappingmapping {
margin: 20px 0 0 20px;
border-radius: 85px;
overflow: hidden;
border: 10px solid #fff;
box-shadow: 0 0 10px #999;
}
.menu-container {
margin-bottom: 50px;
}
.sub-container {
padding: 20px;
background: repeating-linear-gradient( -45deg, #999, #999 10px, #888 10px, #888 20px);
border-radius: 2px;
}
.heading {
color: #000;
background: #ccc;
border-bottom: 1px solid #ccc;
padding: 5px;
}
.indent {
background: #fff;
padding: 20px;
}
.icon {
width: 64px;
height: 64px;
}
.item {
background: #fff;
padding-left: 10px;
background: #f1f1f1;
border-top: 1px solid #fff;
font-size: 30px;
}
.gallery {
width: 100%;
*width: 99.94877049180327%;
margin: 0;
padding: 0;
}
.gallery.grid li {
margin: 2px 5px;
}
.gallery.grid li {
margin: 2px 5px;
display: block;
}
.gallery.grid li:hover {
background: #ccc;
}
.gallery.grid li {
display: inline-block;
border-top: 1px solid #eee;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
border-left: 1px solid #eee;
padding: 6px;
position: relative;
-moz-box-sizing: border-box;
border-radius: 3px 3px 3px 3px;
background: #fff;
}
.gallery a {
display: block;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
</head>
<body>
<div class="container-fluid">
<div>
<span class="toggler btn btn-primary btn-lg" data-selector="parent_">Toggle</span>
</div>
<hr/>
<div class="menu-container">
<h1 class="heading">
<a href="#"><i class="fa fa-minus" aria-hidden="true"></i></a> Activities
</h1>
<div class="sub-container">
<ul class="gallery grid">
<li>
<a href="#"><img title="jack-o-lantern - " src="https://cdn.jsdelivr.net/emojione/assets/svg/1f383.svg" class="icon" role="presentation"></a>
</li>
</ul>
</div>
</div>
<div class="menu-container">
<h1 class="heading">
<a href="#"><i class="fa fa-minus" aria-hidden="true"></i></a> Animals & Nature
</h1>
<div class="sub-container">
<ul class="gallery grid">
<li>
<a href="#"><img title="monkey face - " src="https://cdn.jsdelivr.net/emojione/assets/svg/1f435.svg" class="icon" role="presentation"></a>
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
我没有更改任何CSS或添加类 我模式很少改为HTML,所以看起来更干净。还删除了ID,因为我们需要可以容纳项目的通用解决方案。否则,每次添加内容或删除内容时都需要修复JS。
下次简易解决方案 - &gt; 使用Bootstrap 中的折叠。您忘了添加 Bootstrap特定的JS 文件。请参阅:bootstrap collapse with multiple-targets