如何在点击后保持一个元素处于活动状态:active

4
我很难从这个问题中获得模糊且不想要的答案,所以我决定发表一个清晰的问题来概述我面临的问题。
我正在使用的代码如下:
.flipClass {  
            font-size: Large;
            background-color: #4399CD; 
            color:#fff;
            text-align: left;
}

.flipClass:active{
                  background:#fff; 
                  color:#4399CD;
                  cursor:pointer;
                  transition:all .1s ease-out;
}
.flipClass:active:before {
                          content:'\f102';
                          font-family:FontAwesome;
                          font-style:normal;
                          font-weight:normal;
                          text-decoration:inherit;
                          padding-left:6px; 
                          padding-right:8px;
                          transition:all .3s;
}

我点击元素后,如何获取由.flipClass:active定义的CSS样式?目前,它仅在短暂的时间内处于活动状态。

请查看下面给出的片段:

 $("div[id^=flip]").click(function() {
   $(this).next("div[id^=panel]").stop().slideToggle("slow");
 });
.panelClass,
.flipClass {
  padding: 5px;
  padding-left: 15px;
  border: solid 1px #c3c3c3;
}
.flipClass {
  font-size: Large;
  background-color: #4399CD;
  color: #fff;
  text-align: left;
}
.flipClass:active {
  background: #fff;
  color: #4399CD;
  cursor: pointer;
  transition: all .1s ease-out;
}
.flipClass:active:before {
  content: '\f102';
  font-family: FontAwesome;
  font-style: normal;
  font-weight: normal;
  text-decoration: inherit;
  padding-left: 6px;
  padding-right: 8px;
  transition: all .3s;
}
.panelClass {
  padding: 30px;
  padding-top: 10px;
  display: none;
  background-color: #F3F5F6;
  color: #000;
}
.flipClass:before {
  content: '\f107';
  font-family: FontAwesome;
  font-style: normal;
  font-weight: normal;
  text-decoration: inherit;
  padding-left: 6px;
  padding-right: 8px;
  transition: all .3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />Currently, the .flipClass:active CSS style sheet is working only for a brief moment (precisely until the duration of the mouseclick and maybe some small offset). Click and HOLD mouseclick when clicking on .flipClass to see the effect. I want it to stay!
<div class="flipClass" id="flip1">FIRST HEADING</div>
<div class="panelClass" id="panel1">How to keep the first heading 'active' when this panel is showing? If I could figure that out, I could change the arrow to a pullup arrow too :3</div>
<div class="flipClass" id="flip2">SECOND HEADING</div>
<div class="panelClass" id="panel2">If both Headings have been clicked, this Heading and any other heading that were clicked should also be active (or atleast remain in the CSS state defined by .flipClass:active here)</div>

目前,.flipClass:active CSS样式表仅在短暂的时刻(准确地说,直到鼠标点击的持续时间和一些小偏移量)内起作用。我需要一种方法,在flipClass被点击后始终保持活动状态。我是否使用了不适当的伪选择器?

有什么解决方法吗?或者有没有其他专门用于此目的的伪选择器?可以给个例子吗?


请使用:focus代替。 - Aziz
一种方法是使用隐藏的 checkbox 和相应的 label。将标题作为 label,将 :active 样式绑定到 :checked + .flipClass 上。额外的好处是,你还可以通过 :checked + .flipClass + .panelClass 将你的手风琴移动到 CSS 中。顺便说一下,给类名后缀加上 "Class" 有点极度冗余。 - abluejelly
@Aziz :focus 只有在用户点击其他内容之前才有效,这不是他想要的行为。他希望样式能够根据面板是否显示保持不变,或者至少保持最近打开的面板处于 :active 状态。 - abluejelly
如果您只想让最近的一个样式保持不变,也可以通过:target实现它;唯一需要添加的是需要一个自指的锚点a - abluejelly
3个回答

2
对于接受用户输入焦点的元素,例如button元素,:focus伪类接近您想要的效果。但在这种情况下,看起来您可以展开多个部分,所以:focus不适用于此处。
相反,您可以使用JS应用额外的类,如下所示:

$("div[id^=flip]").click(function() {
   $(this).toggleClass("flipClass-active").next("div[id^=panel]").stop().slideToggle("slow");
 });
.panelClass,
.flipClass {
  padding: 5px;
  padding-left: 15px;
  border: solid 1px #c3c3c3;
}
.flipClass {
  font-size: Large;
  background-color: #4399CD;
  color: #fff;
  text-align: left;
  cursor: pointer;
  transition: all .1s ease-out;
}
.flipClass-active,
.flipClass:active {
  background: #fff;
  color: #4399CD;
}
.flipClass::before {
  content: '\f107';
  font-family: FontAwesome;
  font-style: normal;
  font-weight: normal;
  text-decoration: inherit;
  padding-left: 6px;
  padding-right: 8px;
  transition: all .3s;
}
.flipClass-active::before,
.flipClass:active::before {
  content: '\f102';
}
.panelClass {
  padding: 30px;
  padding-top: 10px;
  display: none;
  background-color: #F3F5F6;
  color: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />Currently, the .flipClass:active CSS style sheet is working only for a brief moment (precisely until the duration of the mouseclick and maybe some small offset). Click and HOLD mouseclick when clicking on .flipClass to see the effect. I want it to stay!
<div class="flipClass" id="flip1">FIRST HEADING</div>
<div class="panelClass" id="panel1">How to keep the first heading 'active' when this panel is showing? If I could figure that out, I could change the arrow to a pullup arrow too :3</div>
<div class="flipClass" id="flip2">SECOND HEADING</div>
<div class="panelClass" id="panel2">If both Headings have been clicked, this Heading and any other heading that were clicked should also be active (or atleast remain in the CSS state defined by .flipClass:active here)</div>


完美地回答了问题。+1。但是我可以请教您对@abluejelly的答案的看法吗?他/她使用了完全基于CSS的答案。至少可以说它很有创意,但我想知道它是否在任何方面提高了性能。而且,如果这种方法在某些地方受到限制呢? - Siddhant Rimal
嗯,现在我注意到了,我想知道为什么下拉箭头保持不变...嗯...代码似乎已经就位了。我想知道问题出在哪里。 - Siddhant Rimal
1
你的一些规则顺序错了,非活动规则能够覆盖活动规则。我编辑了我的答案来解决这个问题。@abluejay的答案也应该可以工作,我不认为会有任何性能差异,但可能更难维护。8个月后,当有人发现或引入错误时,你还记得为什么有隐藏的复选框和选中状态吗?这很聪明,但似乎将来需要重新调整。 - emackey
@emackey这就是为什么你可以简单地添加一个<!-- comment -->来解释"静态手风琴"的概念,并链接回你得到灵感的地方。你知道,就像你应该对待所有StackOverflow代码一样,这样它更易于维护。另外,我的无JavaScript解决方案的核心设计会随着时间的推移变得更加普遍,因为人们意识到他们能够这样做,而这种稀有性是Web对变化的厌恶和向后兼容性的需求的混合体(IE 8仅在今年结束了生命周期)。对于回复晚了,不好意思,是“果冻”而不是“杰”,我的名字是来自NetHack中的一种生物,而不是鸟哈哈 - abluejelly

1
放弃使用jQuery,利用:checked伪类、label和+选择器,我们可以真正地去本地化并静态化!这意味着我们必须自己动画显示面板的max-height。因为我们必须动画整个max-height而不仅仅是内容高度,所以我们必须欺骗眼睛使动画看起来不那么极端。为了做到这一点,还要动画化上/下填充,并让观众的眼睛完成剩下的部分。
这种解决方案的缺点是,您必须能够可靠地放置面板高度的上限。通过在动画完成后添加overflow:auto;可以在一定程度上缓解这个问题,但我会把如何做作为读者的练习。

.panelClass,
.flipClass {
  display:block;
  padding: 5px;
  padding-left: 15px;
  border: solid 1px #c3c3c3;
}

.flipClass {
  font-size: Large;
  background-color: #4399CD;
  color: #fff;
  text-align: left;
  cursor:pointer;
}
.flipClass:before {
  content: '\f107';
  font-family: FontAwesome;
  font-style: normal;
  font-weight: normal;
  text-decoration: inherit;
  padding-left: 6px;
  padding-right: 8px;
  transition: all .3s;
}
:checked + .flipClass {
  background: #fff;
  color: #4399CD;
  transition: all .1s ease-out;
}
:checked + .flipClass:before {
  content: '\f102';
  font-family: FontAwesome;
  font-style: normal;
  font-weight: normal;
  text-decoration: inherit;
  padding-left: 6px;
  padding-right: 8px;
  transition: all .3s;
}

.panelClass {
  /*display: none;/*We have to animate this ourselves now*/
  padding:0 30px;
  max-height:0;
  background-color: #F3F5F6;
  color: #000;
  transition:all 450ms ease-in-out;
  overflow:hidden;
}
:checked + .flipClass + .panelClass{
  max-height:900px;
  padding-top: 10px;
  padding-bottom: 30px;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css" rel="stylesheet" />Currently, the .flipClass:active CSS style sheet is working only for a brief moment (precisely until the duration of the mouseclick and maybe some small offset). Click and HOLD mouseclick when clicking on .flipClass to see the effect. I want it to stay!
<input type="checkbox" id="flip1" hidden />
<label class="flipClass" for="flip1">FIRST HEADING</label>
<div class="panelClass" id="panel1">How to keep the first heading 'active' when this panel is showing? If I could figure that out, I could change the arrow to a pullup arrow too :3</div>
<input type="checkbox" id="flip2" hidden />
<label class="flipClass" for="flip2">SECOND HEADING</label>
<div class="panelClass" id="panel2">If both Headings have been clicked, this Heading and any other heading that were clicked should also be active (or atleast remain in the CSS state defined by .flipClass:active here)</div>

另一个选择是使用 :target (MDN) 来“存储”最近选择的选项... 然而,如果用户在打开一个页面后将其加为书签,这会导致奇怪的行为,需要一些额外的逻辑来处理单击以关闭它,并且只能标记一个项目。如果您想要一个仅显示一个手风琴,那么这绝对是一个不错的选择。或者,您可以将上面代码中的复选框替换为单选按钮。

我喜欢@emackey的答案,因为它几乎完全符合我的需求。然而,在您的出色实现中,似乎没有使用JavaScript和jQuery扩展。这是否意味着它可以加快我的网页加载速度?如果您能告诉我这种实现方式是否会以任何方式对我的网站产生负面影响,我愿意使用它。我更喜欢非本地实现方式,因为它更可靠。我想知道这种方法的可靠性。它会一直有效吗?有例外吗? - Siddhant Rimal
我在我的博客上实现了它。 在网站上会发挥奇妙的作用,但似乎这会在Blogger上产生错误,因为某些<input>的属性不被正确支持,并且Blogger会尝试自动格式化代码…这会使很多事情混乱。 尽管如此,这仍然是一个绝佳的解决方案!! - Siddhant Rimal
@lancel0t "Native" 意味着缺少 jQuery(或任何其他外部库),这几乎总是更高效的(jQ 特别擅长变得迟缓和臃肿)。移除 Javascript 意味着页面将会_通常_更快(它被静态定义),并且运行 NoScript 或类似插件的人不会遇到无法访问的问题。缺点是,IE 8 及更早版本 将会遇到无法显示文本的无障碍问题,并且 IE 9 将缺少滑动动画。请注意,自 2016 年 1 月中旬以来,IE 8 已经停止支持。 - abluejelly

0

在CSS中,你不能使用:active来实现这个。保持链接激活的一种方法是使用脚本添加一个类,像这样

$("div[id^=flip]").click(function() {
   $(this).toggleClass('active').next("div[id^=panel]").stop().slideToggle("slow");
 });

.flipClass.active {
  background: #fff;
  color: #4399CD;
  cursor: pointer;
  transition: all .1s ease-out;
}
.flipClass.active:before {
  content: '\f102';
  font-family: FontAwesome;
  font-style: normal;
  font-weight: normal;
  text-decoration: inherit;
  padding-left: 6px;
  padding-right: 8px;
  transition: all .3s;
}

:active 仅在鼠标按钮按下时应用样式。唯一的方法是使用一些 JavaScript 来应用样式并在单击后保持其应用。

(引用来源:我可以在 CSS 中拥有 onclick 效果吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接