悬停父元素后,使用香草javascript将类添加/删除到其他元素

时间:2018-10-27 18:22:26

标签: javascript jquery

我已经浏览了许多类似的问题,但是找不到一个具体的示例来回答原始JS如何将类添加和删除到与悬停的元素不同的元素。我知道这与设置循环和遍历元素有关,但是我迷失了确切的过程。

基本上,我的卡片上有一个关闭按钮,我希望只有当有人将鼠标悬停在卡片上时才显示关闭按钮。我添加了2个不同的类来显示和隐藏它,但是,我的脚本不起作用。

不幸的是,我不允许使用JQuery。

     var closeButton = document.getElementsByClassName('close');
        var card = document.getElementsByClassName('.card')
        for (var i = 0; i < card.length; i++) {
            card[i].addEventListener("mouseover", function() {
                for (var i = 0; i < closeButton.length; i++) {
                    closeButton[i].classList.add('shown');
                    closeButton[i].classList.remove('hidden');
                }
            });
            card[i].addEventListener("mouseout", function() {
                for (var i = 0; i < closeButton.length; i++) {
                    closeButton[i].remove('shown');
                    closeButton[i].add('hidden');
                }
            });
        }
/*! normalize.css v1.1.0 | MIT License | git.io/normalize */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
nav,
section,
summary {
    display: block
}

audio,
canvas,
video {
    display: inline-block;
    *display: inline;
    *zoom: 1
}

audio:not([controls]) {
    display: none;
    height: 0
}

[hidden] {
    display: none
}

html {
    font-size: 100%;
    -webkit-text-size-adjust: 100%;
    -ms-text-size-adjust: 100%
}

html,
button,
input,
select,
textarea {
    font-family: sans-serif
}

body {
    margin: 0
}

a:active,
a:hover {
    outline: 0
}

h1 {
    font-size: 2em;
    margin: .67em 0
}

h2 {
    font-size: 1.5em;
    margin: .83em 0
}

h3 {
    font-size: 1.17em;
    margin: 1em 0
}

h4 {
    font-size: 1em;
    margin: 1.33em 0
}

h5 {
    font-size: .83em;
    margin: 1.67em 0
}

h6 {
    font-size: .67em;
    margin: 2.33em 0
}

abbr[title] {
    border-bottom: 1px dotted
}

b,
strong {
    font-weight: bold
}

blockquote {
    margin: 1em 40px
}

dfn {
    font-style: italic
}

hr {
    -webkit-box-sizing: content-box;
    box-sizing: content-box;
    height: 0
}

mark {
    background: #ff0;
    color: #000
}

p,
pre {
    margin: 1em 0
}

code,
kbd,
pre,
samp {
    font-family: monospace, serif;
    _font-family: 'courier new', monospace;
    font-size: 1em
}

pre {
    white-space: pre;
    white-space: pre-wrap;
    word-wrap: break-word
}

q {
    quotes: none
}

q:before,
q:after {
    content: '';
    content: none
}

small {
    font-size: 80%
}

sub,
sup {
    font-size: 75%;
    line-height: 0;
    position: relative;
    vertical-align: baseline
}

sup {
    top: -0.5em
}

sub {
    bottom: -0.25em
}

dl,
menu,
ol,
ul {
    margin: 1em 0
}

dd {
    margin: 0 0 0 40px
}

menu,
ol,
ul {
    padding: 0 0 0 40px
}

nav ul,
nav ol {
    list-style: none;
    list-style-image: none;
    padding: 0;
    margin: 0
}

img {
    border: 0;
    -ms-interpolation-mode: bicubic
}

svg:not(:root) {
    overflow: hidden
}

figure {
    margin: 0
}

form {
    margin: 0
}

fieldset {
    border: 1px solid #c0c0c0;
    margin: 0 2px;
    padding: .35em .625em .75em
}

legend {
    border: 0;
    padding: 0;
    white-space: normal;
    *margin-left: -7px
}

button,
input,
select,
textarea {
    font-size: 100%;
    margin: 0;
    vertical-align: baseline;
    *vertical-align: middle
}

button,
input {
    line-height: normal
}

button,
select {
    text-transform: none
}

button,
html input[type="button"],
input[type="reset"],
input[type="submit"] {
    -webkit-appearance: button;
    cursor: pointer;
    *overflow: visible
}

button[disabled],
html input[disabled] {
    cursor: default
}

input[type="checkbox"],
input[type="radio"] {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    padding: 0;
    *height: 13px;
    *width: 13px
}

input[type="search"] {
    -webkit-appearance: textfield;
    -webkit-box-sizing: content-box;
    box-sizing: content-box
}

input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
    -webkit-appearance: none
}

a:link {
    text-decoration: none !important;
}

button::-moz-focus-inner,
input::-moz-focus-inner {
    border: 0;
    padding: 0
}

textarea {
    overflow: auto;
    vertical-align: top
}

table {
    border-collapse: collapse;
    border-spacing: 0
}

* {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    -webkit-transition: all 1s ease;
    transition: all 1s ease;
}

html {
    font-size: 100%;
    font-family: sans-serif;
    height: 100%;
}

body {
    min-height: 100%;
    margin: 0;
    padding: 0;
    background: #f8f8f8;
}

#wrapper {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    margin: 0 auto;
    padding: 20px;
    max-width: 980px;
    background: #fff;
    -webkit-box-shadow: 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);
    box-shadow: 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);
    border-radius: 2px;
}

.clearfix {
    overflow: auto;
}

.clearfix::after {
    content: "";
    clear: both;
    display: table;
}

.headline {
    padding: 0 10px;
}

.headline .promoted-stories {
    font-weight: bold;
    color: #404040;
}

.headline .taboola-link {
    float: right;
}

.headline .taboola-link a {
    font-weight: 300;
    line-height: normal;
    text-align: right;
    color: #888888;
    font-size: 11px;
}

.cards {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
}

.card {
    display: block;
    min-height: 1px;
    margin: 1%;
    -webkit-box-flex: 0;
    -ms-flex: 0 0 31.33333333%;
    flex: 0 0 31.33333333%;
    -webkit-box-shadow: 0px 0px 1px -2px rgba(0, 0, 0, 0.2), 0px 0px 2px 0px rgba(0, 0, 0, 0.14), 0px 0px 0px 0px rgba(0, 0, 0, 0.12);
    box-shadow: 0px 0px 1px -2px rgba(0, 0, 0, 0.2), 0px 0px 2px 0px rgba(0, 0, 0, 0.14), 0px 0px 0px 0px rgba(0, 0, 0, 0.12);
    -webkit-transition: all .25s;
    transition: all .25s;
    position: relative;
}

.card:hover {
    -webkit-transform: translate(0, -2px);
    transform: translate(0, -2px);
    -webkit-box-shadow: 0px 1px 2px -1px rgba(0, 0, 0, 0.2), 0px 3px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);
    box-shadow: 0px 1px 2px -1px rgba(0, 0, 0, 0.2), 0px 3px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);
}

.overlay {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;
}

.card .thumbnail {
    display: block;
    height: 130px;
}

.card img {
    height: 100%;
    width: 100%;
    border: none;
    -o-object-fit: cover;
    object-fit: cover;
    -o-object-position: 50% 50%;
    object-position: 50% 50%;
}

.card-content {
    padding: 5px 10px 25px;
}

.card .card-content .card-title {
    margin: 5px 0 0 0;
    overflow: hidden;
    color: #000;
    font-weight: bold;
    max-height: 72px;
    font-size: .875rem;
    line-height: 1.5rem;
    text-decoration: none;
}

.card .card-content .category {
    color: #999999;
    font-size: 11.0px;
    font-weight: bold;
    text-decoration: none;
    margin: 5px 0 0 0;
    overflow: hidden;
    max-height: 52px;
}

.close {
    position: absolute;
    right: 15px;
    top: 5px;
}

.shown {
    display: block;
}

.hidden {
    display: none;
}

.close:before,
.close:after {
    position: absolute;
    left: 0;
    right: 0;
    content: ' ';
    height: 15px;
    width: 2px;
    background-color: #fff;
}

.close:before {
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
}

.close:after {
    -webkit-transform: rotate(-45deg);
    transform: rotate(-45deg);
}

@media only screen and (max-width: 768px) {
    .card {
        -webkit-box-flex: 0;
        -ms-flex: 0 0 48%;
        flex: 0 0 48%;
    }
}

@media only screen and (max-width: 480px) {
    .card {
        -webkit-box-flex: 0;
        -ms-flex: 0 0 98%;
        flex: 0 0 98%;
        margin: 2%;
    }

    .card .thumbnail,
    .card .thumbnail a:first-of-type {
        height: 170px;
    }
}
    <section id="wrapper">
        <div class="headline clearfix">
            <span class="promoted-stories">Promoted stories</span>
            <span class="taboola-link"><a href="#">Sponsored Links by Taboola</a></span>
        </div>
        <div class="cards clearfix">
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="3 Reasons Why You Haven't Found Your Match Yet">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">3 Reasons Why You Haven't Found Your Match Yet</h2>
                    <p class="category">Dating life</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="Harry And Meghan Announce Baby On The Way">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">Harry And Meghan Announce Baby On The Way</h2>
                    <p class="category">Royals</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="Things Get Seriously Real As RuPaul Cast Open Up">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">Things Get Seriously Real As RuPaul Cast Open Up</h2>
                    <p class="category">Celebrities</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="A Tiger Collapsed In A Russian Circus Mid-Show">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">A Tiger Collapsed In A Russian Circus Mid-Show</h2>
                    <p class="category">Circus</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="Engagement On The Cards For Jack And Dani">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">Engagement On The Cards For Jack And Dani</h2>
                    <p class="category">Dating life</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="Attwood Hits Back At Rumours Of Dani Dyer Fued">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">Attwood Hits Back At Rumours Of Dani Dyer Fued</h2>
                    <p class="category">Gossip</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
        </div>
    </section>

3 个答案:

答案 0 :(得分:1)

尝试

function find( el, tagName ) {
    tagName = tagName.toUpperCase();
    let nsi = el.nextElementSibling;
    if ( nsi === null || nsi.children === null || nsi.children.length === 0 ) return null;
    for ( let c of nsi.children ) {
        if ( c.tagName === tagName ) return c;
    }
    return null;
};
let card = document.getElementsByClassName( 'card' );
for ( let c of card ) {
    c.addEventListener( "mouseover", function ( e ) {
        let el = find( e.target, "a" );
        if ( el === null ) return;
        el.classList.add( 'shown' );
        el.classList.remove( 'hidden' );
    }, false );
    c.addEventListener( "mouseout", function ( e ) {
        let open = document.querySelectorAll( ".close.shown" );
        if ( open !== null ) {
            for ( let obtn of open ) {
                obtn.classList.remove( 'shown' );
                obtn.classList.add( 'hidden' );
            }
        }
    }, false );
};

Run jsfiddle

  

您的错误JavaScript:
  i)closeButton[i].remove( 'shown' );将是运行时错误;在这里不是typeof("function"),您必须从classList中删除类
  ii)closeButton[i].add( 'hidden' );将是运行时错误; add不是typeof("function"),您必须将class添加到classList
  iii)var card = document.getElementsByClassName('.card') card的长度应为0,因为它将找到所有.card而不是card类的

编辑

//Correction
//closeButton[i].classList.remove( 'shown' ); 
//closeButton[i].classList.add( 'hidden' ); 
//var card = document.getElementsByClassName('card');

了解更多信息let of 遍历数组

答案 1 :(得分:0)

您的实际JavaScript问题是,您拥有嵌套的循环,这些循环声明并使用与父循环相同的变量,这会重置外部循环计数器,因此您不会按照需要的方式循环。在内部循环中使用不同的变量将是关键。

此外,当您在较高范围内声明的嵌套循环中访问同一变量时,它会在i变量周围设置ipd。这将导致所有卡共享相同的i值,并且当用户徘徊在任何卡上时,i比卡阵列的length多一个因此,无法找到任何匹配的卡片。解决方案是简单地用i声明let而不是var来声明块级范围并避免关闭。


现在,话虽如此,没有必要显示一个类,而隐藏一个类。您只需要一个隐藏类,就可以简单地应用或删除该类来控制按钮的可见性。


但是,实际上,您根本不需要任何JavaScript ,只需一个小的CSS,它根据祖先是否为“”来控制“按钮”的display卡”。

/* Default styling of "close" buttons is hidden */
.card a.close {
  display:none;
}

/* When ancestor "card" is hovered, change display to shown */
.card:hover a.close{
  display:block;
  font-weight:bold;
}

/* ******************************** */


/*! normalize.css v1.1.0 | MIT License | git.io/normalize */

figure {
    margin: 0
}

a:link {
    text-decoration: none !important;
}

* {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    -webkit-transition: all 1s ease;
    transition: all 1s ease;
}

html {
    font-size: 100%;
    font-family: sans-serif;
    height: 100%;
}

body {
    min-height: 100%;
    margin: 0;
    padding: 0;
    background: #f8f8f8;
}

#wrapper {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    margin: 0 auto;
    padding: 20px;
    max-width: 980px;
    background: #fff;
    -webkit-box-shadow: 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);
    box-shadow: 0px 2px 1px -1px rgba(0, 0, 0, 0.2), 0px 1px 1px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);
    border-radius: 2px;
}

.clearfix {
    overflow: auto;
}

.clearfix::after {
    content: "";
    clear: both;
    display: table;
}

.headline {
    padding: 0 10px;
}

.headline .promoted-stories {
    font-weight: bold;
    color: #404040;
}

.headline .taboola-link {
    float: right;
}

.headline .taboola-link a {
    font-weight: 300;
    line-height: normal;
    text-align: right;
    color: #888888;
    font-size: 11px;
}

.cards {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
}

.card {
    display: block;
    min-height: 1px;
    margin: 1%;
    -webkit-box-flex: 0;
    -ms-flex: 0 0 31.33333333%;
    flex: 0 0 31.33333333%;
    -webkit-box-shadow: 0px 0px 1px -2px rgba(0, 0, 0, 0.2), 0px 0px 2px 0px rgba(0, 0, 0, 0.14), 0px 0px 0px 0px rgba(0, 0, 0, 0.12);
    box-shadow: 0px 0px 1px -2px rgba(0, 0, 0, 0.2), 0px 0px 2px 0px rgba(0, 0, 0, 0.14), 0px 0px 0px 0px rgba(0, 0, 0, 0.12);
    -webkit-transition: all .25s;
    transition: all .25s;
    position: relative;
}

.card:hover {
    -webkit-transform: translate(0, -2px);
    transform: translate(0, -2px);
    -webkit-box-shadow: 0px 1px 2px -1px rgba(0, 0, 0, 0.2), 0px 3px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);
    box-shadow: 0px 1px 2px -1px rgba(0, 0, 0, 0.2), 0px 3px 10px 0px rgba(0, 0, 0, 0.14), 0px 1px 3px 0px rgba(0, 0, 0, 0.12);
}

.overlay {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;
}

.card .thumbnail {
    display: block;
    height: 130px;
}

.card img {
    height: 100%;
    width: 100%;
    border: none;
    -o-object-fit: cover;
    object-fit: cover;
    -o-object-position: 50% 50%;
    object-position: 50% 50%;
}

.card-content {
    padding: 5px 10px 25px;
}

.card .card-content .card-title {
    margin: 5px 0 0 0;
    overflow: hidden;
    color: #000;
    font-weight: bold;
    max-height: 72px;
    font-size: .875rem;
    line-height: 1.5rem;
    text-decoration: none;
}

.card .card-content .category {
    color: #999999;
    font-size: 11.0px;
    font-weight: bold;
    text-decoration: none;
    margin: 5px 0 0 0;
    overflow: hidden;
    max-height: 52px;
}

.close {
    position: absolute;
    right: 15px;
    top: 5px;
}

.close:before,
.close:after {
    position: absolute;
    left: 0;
    right: 0;
    content: ' ';
    height: 15px;
    width: 2px;
    background-color: #fff;
}

.close:before {
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
}

.close:after {
    -webkit-transform: rotate(-45deg);
    transform: rotate(-45deg);
}
<section id="wrapper">
        <div class="headline clearfix">
            <span class="promoted-stories">Promoted stories</span>
            <span class="taboola-link"><a href="#">Sponsored Links by Taboola</a></span>
        </div>
        <div class="cards clearfix">
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="3 Reasons Why You Haven't Found Your Match Yet">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">3 Reasons Why You Haven't Found Your Match Yet</h2>
                    <p class="category">Dating life</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="Harry And Meghan Announce Baby On The Way">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">Harry And Meghan Announce Baby On The Way</h2>
                    <p class="category">Royals</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="Things Get Seriously Real As RuPaul Cast Open Up">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">Things Get Seriously Real As RuPaul Cast Open Up</h2>
                    <p class="category">Celebrities</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="A Tiger Collapsed In A Russian Circus Mid-Show">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">A Tiger Collapsed In A Russian Circus Mid-Show</h2>
                    <p class="category">Circus</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="Engagement On The Cards For Jack And Dani">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">Engagement On The Cards For Jack And Dani</h2>
                    <p class="category">Dating life</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
            <article class="card">
                <a class="overlay" href="#overlay-link"></a>
                <figure class="thumbnail">
                    <img src="https://img.ohmymag.co.uk/headline/480/0f2af4ec6e8d3971480358d00e67e2e8117d994e.jpg" alt="Attwood Hits Back At Rumours Of Dani Dyer Fued">
                    <a href="#" class="close hidden"></a><!-- close hidden button -->
                </figure>
                <div class="card-content">
                    <h2 class="card-title">Attwood Hits Back At Rumours Of Dani Dyer Fued</h2>
                    <p class="category">Gossip</p>
                </div><!-- .card-content -->
            </article><!-- .card -->
        </div>
    </section>

答案 2 :(得分:0)

在您的代码document.getElementsByClassName('.card')中将查找 类名称为.card而不是card的元素。同样,您不需要两个类来实现此功能。只需删除hidden类即可完成工作。

以下是更新的JS代码:

(function() {
    document.querySelectorAll(".card").forEach(function(card) {
      card.addEventListener("mouseenter", function() {
        card.querySelector(".close").classList.remove("hidden");
      })
      card.addEventListener("mouseout", function() {
        card.querySelector(".close").classList.add("hidden");
      })
    })
  })()