我在下面的代码中提供了一些使用HTML和CSS创建的信息框。是否可以让悬停div保持打开,直到单击关闭按钮?这可以在Vanilla JavaScript中做到吗?我是JavaScript的新手,所以任何事情都有帮助,欢呼!
.everything {
text-align: center;
height: 1000px;
}
.everything:hover {
cursor: default;
}
.infobox-list {
display: inline-block;
text-align: center;
}
ul,
ol,
li {
margin: 0;
padding: 0;
list-style-position: outside;
list-style-type: none;
}
h1,
h2,
h3,
h4,
h5,
h6,
ul,
li,
ol,
form,
fieldset {
margin: 0;
padding: 0;
}
*,
*:before,
*:after {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
ul,
menu,
dir {
display: block;
list-style-type: disc;
-webkit-margin-before: 1em;
-webkit-margin-after: 1em;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;
-webkit-padding-start: 0px;
}
.hr {
border-color: rgba(255, 255, 255, 0.3);
margin-left: 9px;
width: 210px;
}
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
padding: 0;
margin: 0;
background-color: #fcfcfc;
color: #555;
min-width: 20em;
}
.info-boxes li {
width: 310px;
height: 535px;
background: #f2f2f2;
border: 0px solid #efefef;
border-radius: 4px;
margin: 0 0px 0px;
cursor: pointer;
position: relative;
overflow: hidden;
transform: scale(0.75);
}
.ptext {
text-align: center;
font-size: 20px;
}
.profile {
margin-top: 10%;
margin-left: 1px;
width: 75px;
height: 75px;
}
.performance {
margin-left: 1px;
margin-top: 10%;
width: 75px;
height: 75px;
}
.learning {
margin-top: 10%;
width: 75px;
height: 75px;
}
.team {
margin-top: 10%;
width: 75px;
height: 75px;
}
.smallicons {
width: 50px;
height: 50px;
}
.profileclose {
margin-top: 215px;
}
.infobox-list li {
display: inline-block;
}
a {
color: white;
text-decoration: none;
font-weight: lighter;
}
.info-boxes li .infobox {
display: table-cell;
text-align: center;
vertical-align: middle;
height: 535px;
width: 310px;
}
.info-boxes li .infobox:before {
content: '';
position: absolute;
left: 20%;
width: 160%;
height: 188%;
background-color: rgb(255, 255, 255);
/* fallback */
background-color: rgba(255, 255, 255, 0.2);
top: 0;
-webkit-transform: rotate(46deg);
-moz-transform: rotate(46deg);
transform: rotate(30deg);
}
.info-boxes li:hover .shade {
animation-name: windowshade;
cursor: pointer;
}
.info-boxes li .shade,
.info-boxes li:hover .shade {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
animation-duration: 1s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
section p {
line-height: 1.3em;
color: #6d6e71;
width: 100%;
padding: 0 10px;
margin-top: 5px;
margin-left: 0px;
text-align: left;
}
p {
display: block;
}
.info-boxes li .shade {
position: absolute;
width: 310px;
height: 555px;
left: 0;
top: 0;
background-color: #6caf46;
color: #fff;
display: table;
vertical-align: middle;
padding: 20px 10px 0;
transform: translateY(-340px);
animation-name: windowshade-out;
}
.info-boxes li .shade h3 {
color: #fff;
padding: 10px;
font-weight: bold
}
.info-boxes li .shade p {
color: #fff;
line-height: 3em;
font-weight: lighter;
}
.ie9 .info-boxes li:hover .shade {
top: 245px
}
.info-boxes li:hover a {
text-decoration: none
}
@keyframes windowshade {
0% {
transform: translateY(-535px)
}
100% {
transform: translateY(0)
}
}
@keyframes windowshade-out {
0% {
transform: translateY(0)
}
100% {
transform: translateY(-535px)
}
}
#wrapper {
margin: 0 auto;
}
#wrapper img {
width: 100%;
/* the image will now scale down as its parent gets smaller */
}

<div class="everything">
<div class="everything">
<br style="line-height:35px;">
<section class="info-boxes">
<ul class="infobox-list">
<li>
<a href="#">
<div class="infobox">
<table>
<tr>
<img class="profile" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497637065/profile_i0evlz.png"></tr>
<tr>
<p class="ptext">Profile</p>
</tr>
</table>
</div>
<div class="shade">
<table>
<tr>
<td>
<img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497301295/About-Me_dudglr.png">
</td>
<td>
<p>About Me</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497284615/Resume_tb7t02.png"> </td>
<td>
<p>Resume</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497280574/Accountabilities_qfdcns.png"> </td>
<td>
<p>Accountabilities
<p/>
<hr class="hr">
</td>
</tr>
</table>
<div class="profileclose">Close</div>
</div>
</a>
</li>
<li>
<div class="infobox">
<table>
<tr>
<img class="learning" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497637065/Learning-Icon_hqtc2k.png"></tr>
<tr>
<p class="ptext">Learning</p>
</tr>
</table>
</div>
<div class="shade">
<table>
<tr>
<td>
<img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497297687/Training-Plan_v43ne7.png">
</td>
<td>
<p>Training Plan</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497297687/Training-History_czttv1.png"> </td>
<td>
<p>Training History</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497298863/coursefeedback_qdh1wm.png"> </td>
<td>
<p>Course Feedback</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497299106/Favourites_y9gkce.png"> </td>
<td>
<p>Training Favourites
<p/>
<hr class="hr">
</td>
</tr>
</table>
</div>
</li>
<li>
<a href="#">
<div class="infobox">
<table>
<tr>
<img class="performance" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497637065/Performance-Icon_ozaldt.png"></tr>
<tr>
<p class="ptext">Performance</p>
</tr>
</table>
</div>
<div class="shade">
<table>
<tr>
<td>
<img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497284615/Goals_aw4nso.png">
</td>
<td>
<p>Goals</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497284934/EA_n8lvj1.png" </td>
<td>
<p>Effectiveness Assessment</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497284615/development_yfv6o1.png" </td>
<td>
<p>Development Plan</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497285433/resources_b3r88g.png"> </td>
<td>
<p>Resources
<p/>
<hr class="hr">
</td>
</tr>
</table>
</div>
</a>
</li>
<li>
<div class="infobox">
<table>
<tr>
<img class="team" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497637065/team_nl2cwh.png"></tr>
<tr>
<p class="ptext">Team</p>
</tr>
</table>
</div>
<div class="shade">
<table>
<tr>
<td>
<img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497300652/Team_iovnl5.png">
</td>
<td>
<p>Team</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497284615/Goals_aw4nso.png"> </td>
<td>
<p>Team Goals</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497284615/development_yfv6o1.png"> </td>
<td>
<p>Team Development</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497297687/Training-Plan_v43ne7.png"> </td>
<td>
<p>Team Training</p>
<hr class="hr">
</td>
</tr>
<tr>
<td><img class="smallicons" src="http://res.cloudinary.com/djxai1v1e/image/upload/v1497301295/Approval_f9y1da.png"> </td>
<td>
<p>Approvals
<p/>
<hr class="hr">
</td>
</tr>
</table>
</div>
</li>
</ul>
</section>
</div>
&#13;
答案 0 :(得分:1)
这有点长,但这里是fiddle。
基本上,您要为mouseenter(打开)和单击(关闭)事件定义几个事件处理程序,然后更改CSS以解决此问题。我会立即发布并解释更新中的每一位。
对于打开和关闭处理,您只需添加和删除&#34; hover&#34; class(而不是使用伪类):
function open(e){
let li = e.target;
li.classList.add('hover');
}
function close(e){
const hoverable = e.target.closest('li.hover');
hoverable.classList.remove('hover');
}
然后在CSS中更改你的:hover pseudoclass以改为使用.hover:
.info-boxes li.hover .shade {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
animation-duration: 1s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
}
添加事件处理程序等很简单:
const infoBoxListItems = document.querySelectorAll('.info-boxes li');
const closeButtons = document.querySelectorAll('.profileclose');
infoBoxListItems.forEach(li => {
li.addEventListener('mouseenter', open);
});
closeButtons.forEach(btn => {
btn.addEventListener('click', close);
});
我的完整示例包含closest()
的polyfill,但这是来自MDN的直接副本,因此您可以在那里阅读。