jquery - JQuery Toggle visibility of divs
问题描述
My theme uses the following structure (doesn't allow me to have a separate class for each button):
<button class="x-active" role="tab" aria-selected="true" aria-controls="panel-1" data-x-toggle="tab" data-x-toggleable="tab-item-1"><span>Button 1</span></button>
<button class="x-active" role="tab" aria-selected="true" aria-controls="panel-2" data-x-toggle="tab" data-x-toggleable="tab-item-2"><span>Button 2</span></button>
I am looking for some JQuery code which will toggle the visibility of two different divs, depending on which button the user presses.
i.e. If Button 1 is pressed the divs should be:
<div id="section-1" style="display:block;"></div>
<div id="section-2" style="display:none;"></div>
and If Button 2 is pressed the divs should be:
<div id="section-1" style="display:none;"></div>
<div id="section-2" style="display:block;"></div>
Any help would be much appreciated as not sure how to start on this.
解决方案
我建议:
// select all <button> elements, using the on() method
// to bind the anonymous function as the event-handler
// for the 'click' event:
$('button').on('click', function() {
// here we find the attribute-value of the
// data-x-toggleable attribute as a String,
// and use the String.prototype.match() method
// along with a regular expression, to find a
// sequence of one-or-more numbers "\d+" at the
// end of the string "$":
const num = this.dataset.xToggleable.match(/\d+$/);
// if match doesn't find a result then it returns
// null; here we check that we have a result:
if (num) {
// if we have a result we hide all <div> elements
// whose 'id' attribute-value starts with the string
// of 'section', and then we hide them using the
// hide() method:
$('div[id^=section]').hide();
// here we use a template literal string to interpolate
// the value of the 'num' variable into the string,
// which finds the <div> element with an 'id' of
// "section" which ends with the number found earlier,
// and we show it using the show() method:
$(`div#section-${num}`).show();
}
});
$('button').on('click', function() {
const num = this.dataset.xToggleable.match(/\d+$/);
if (num) {
$('div[id^=section]').hide();
$(`div#section-${num}`).show();
}
});
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
div[id^=section] {
border: 2px solid #f90;
margin: 0.5em 1em;
}
div[id^=section]::before {
content: attr(id);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="x-active" role="tab" aria-selected="true" aria-controls="panel-1" data-x-toggle="tab" data-x-toggleable="tab-item-1"><span>Button 1</span></button>
<button class="x-active" role="tab" aria-selected="true" aria-controls="panel-2" data-x-toggle="tab" data-x-toggleable="tab-item-2"><span>Button 2</span></button>
<div id="section-1"></div>
<div id="section-2"></div>
作为 jQuery 的替代方案,同样的事情可以用纯 JavaScript 轻松完成:
// here we have a named function, defined using Arrow Syntax
// since we don't need to use the 'this' of the function; one
// argument, the Event object, is automatically passed in from
// EventTarget.addEventListener():
const toggleDisplay = (evt) => {
// here we retrieve the element upon which the event-listener
// was bound, using evt.currentTarget (the 'currentTarget'
// property of the Event Object 'evt'), we then use the
// Element.dataset API to access - as before - the sequence
// of numbers at the end of the data-x-toggleable attribute-
// value:
const num = evt.currentTarget.dataset.xToggleable.match(/\d+$/);
// if we have a matching number, therefore 'num' is not
// false/falsey:
if (num) {
// we retrieve all <div> elements whose 'id' attribute-
// value starts with "section" and then iterate over that
// NodeList using NodeList.prototype.forEach():
document.querySelectorAll('div[id^=section]').forEach(
// the first argument to the anonymous Arrow function
// expression is a reference to the current Node of the
// NodeList over which we're iterating, here I called
// id 'div', but you can call it anything you like (so
// long as it's not a reserved word); in this function
// we hide the elements by updating the 'display' property
// of the 'style' to 'none':
(div) => div.style.display = 'none'
);
// because we're using an id selector, again using a
// template literal (as in the jQuery example), we
// can only retrieve one element (if there's a match)
// or null if no element is found. As we can only find
// one element we can update its display to 'block' to
// in order to show it:
document.querySelector(`#section-${num}`).style.display = 'block';
}
};
// here we find all the <button> elements on the page,
// using document.querySelectorAll() and then use
// NodeList.prototype.forEach() to iterate over those
// element-nodes using another Arrow function expression:
document.querySelectorAll('button').forEach(
// the first argument represents the current node of
// the nodeList, here called 'btn'; with the arrow
// function we bind the toggleDisplay() function, note
// the deliberate lack of parentheses, as the event-
// handler for clicks on the <button> elements:
(btn) => btn.addEventListener('click', toggleDisplay)
);
const toggleDisplay = (evt) => {
const num = evt.currentTarget.dataset.xToggleable.match(/\d+$/);
if (num) {
document.querySelectorAll('div[id^=section]').forEach(
(div) => div.style.display = 'none'
);
document.querySelector(`#section-${num}`).style.display = 'block';
}
};
document.querySelectorAll('button').forEach(
(btn) => btn.addEventListener('click', toggleDisplay)
);
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
div[id^=section] {
border: 2px solid #f90;
margin: 0.5em 1em;
}
div[id^=section]::before {
content: attr(id);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="x-active" role="tab" aria-selected="true" aria-controls="panel-1" data-x-toggle="tab" data-x-toggleable="tab-item-1"><span>Button 1</span></button>
<button class="x-active" role="tab" aria-selected="true" aria-controls="panel-2" data-x-toggle="tab" data-x-toggleable="tab-item-2"><span>Button 2</span></button>
<div id="section-1"></div>
<div id="section-2"></div>
参考:
推荐阅读
- sql-server - TSQL 随机样本
- arrays - 在 Fortran 中以特定格式打印文件中的数组变量
- ubuntu - imagemagick 构造文档,每个 A4 页面有两个图像
- apache2 - Bitnami Lamp 堆栈子域
- python - 按键迭代字典列表和分组项
- mysql - 我可以用什么替换“IDENTITY”来完成这项工作?
- reactjs - admin-on-rest 中的批量操作
- c# - 在 C# 中,我应该使用什么数据类型来存储具有标准偏差的数字列表?
- html - 如何使链接填充不同高度的表格单元格?
- jquery - 是否可以通过 jquery 打开/关闭 Google Analytics?