Javascript 函数参数,用于目标 html ID 并添加 CSS 类



我正在尝试通过显示带有名称的图像来在网页上显示教练库。我想启用一个弹出窗口 onClick,该窗口将通过切换 CSS 类 .-enable {} 来显示每个教练的更多信息,方法是使用其关联的 ID 定位特定的容器div。我设置了 html,以便通过切换该特定容器上的 css 类 .enable 来显示带有"关闭"按钮的弹出窗口。

我想使用一个非常简单的函数和一个参数来选择 id,然后在 id 上切换一个类。在我的示例中,默认情况下,第一个标签中包装的所有内容都是可见的,并且通过切换 css 类 .-enable 来激活以下div。我的示例"Chris"是一个教练,通过单击默认容器块,我激活函数"coachWindow(coach)"并将"Chris"作为函数中的参数传递,以选择ID为"chris"的div并切换CSS类。

function coachWindow ( coach ) {
document.querySelector("#" + coach).classList.toggle("-enable");
}
.-enable {
display:block;
}
<a onclick="coachWindow(chris)"><div>
<div class="enlarge">
<div class="chris-img coach-img-sizing">
<div class="coach-overlay">
<h3 class="coach-name">Chris</h3>
</div>
</div>
</div>
</a>
<div id="chris" class="coach"> <!--(-enable class appears here)-->
<div class="lightwindow"></div>
<div class="coach-box">
<div class="coach-container">
<h3 class="coach-heading">Chris</h3>
<div class="image-container chris-img coach-img-sizing"></div>
<div class="coach-text">
<p>
Text block on this coach.
</p> 
</div>
<button onclick="coachWindow(chris)" class="coach-button">Close</button>
</div>
</div>
</div>

我不确定querySelector选项,但我看到了一个jQuery的例子,看起来$('#' + parameter)能够针对parameterID的。

当我从控制台运行document.querySelector(chris).classList.toggle("-enable");时,会出现弹出框,但是通过函数 coachWindow 运行相同的 id 会返回未定义和类型错误的结果。

如何编写函数,以便可以传递任何教练 ID 并显示相应教练的弹出窗口?

这比你想象的要简单得多。首先,不要专注于id,因为这会使解决方案更加复杂和脆弱。如果您正确构建了 HTML,只需显示或隐藏适当的div即可使用 DOM.closest().nextElementSibling()方法定位它,然后添加和删除带有.classList.add.classList.Remove的预设类。使用这种方法,id是什么并不重要(您甚至不需要使用它们),您可以随时添加/删除教练,而无需修改 JavaScript。只需保持正确的 HTML 结构即可。

此外,不要将<a>元素仅用作click事件触发器。仅在导航时使用它们,否则在语义上不正确。几乎任何可见元素都可以在其上设置click事件,如下所示。同样,您可以将任何内容样式设置为看起来像任何内容,因此即使是非链接元素也可以看起来像链接或按钮或其他任何东西。

说到语义,不要使用标题(h1...h6),因为它们使文本看起来如何。事实上,永远不要使用任何 HTML 元素,因为它附带了内置样式。使用正确的标记来描述您的内容,并在以后使用 CSS 设置元素的样式。h3只能用于描述层次结构中第三个子级别的内容。这意味着他们应该只作为h2的孩子出现,并且h2需要在h1中。

// Get all the "links" into an array
let links = Array.prototype.slice.call(document.querySelectorAll("h1.coach-name"));
// Loop over the array of links
links.forEach(function(link){
// Set up a click event handler for each link
link.addEventListener("click", function(){
// Locate the outermost div of the clicked element and
// remove the hidden class from the following element
link.closest(".enlarge").nextElementSibling.classList.remove("hidden");
});
});
// Get all the close buttons into an array
let closeButtons = Array.prototype.slice.call(document.querySelectorAll(".coach-button"));
// Loop through all the close buttons
closeButtons.forEach(function(btn){
// Set up a click event handler for each
btn.addEventListener("click", function(){
// Locate the nearest ancestor div that holds the popup
// and add back the hidden class to hide the current popup
btn.closest(".coach").classList.add("hidden");
});
});
.coach { 
border:6px double #e0e0e0; 
padding:5px; position:absolute; 
top:25px; left:25px; 
background-color:#55f; 
color:#ff0;
padding:10px;
border-radius:3px;
}
.enlarge h1, .coach h1 {
font-size:1em; 
margin-top:.5em;
padding:3px;
text-align:center;
}
.enlarge h1 { 
border:1px solid #808080;
background-color:#e0e0e0;
display:inline-block;
border-radius:2px;
width:75px;
cursor:pointer;
}
.enlarge h1:hover { box-shadow:0 0 1px #606060; }
/* This will be set on the popups by default
and then removed as needed. */
.hidden { display:none; }
<div class="enlarge">
<div class="chris-img coach-img-sizing">
<div class="coach-overlay">
<h1 class="coach-name">Chris</h1>
</div>
</div>
</div>
<div id="chris" class="coach hidden"> <!-- each popup is hidden by default via CSS -->
<div class="lightwindow"></div>
<div class="coach-box">
<div class="coach-container">
<h1 class="coach-heading">Chris</h1>
<div class="image-container chris-img coach-img-sizing"></div>
<div class="coach-text">
<p>Text block on this coach.</p> 
</div>
<button class="coach-button">Close</button>
</div>
</div>
</div>
<!-- ********************************************** -->
<div class="enlarge">
<div class="chris-img coach-img-sizing">
<div class="coach-overlay">
<h1 class="coach-name">Mary</h1>
</div>
</div>
</div>
<div id="chris" class="coach hidden">
<div class="lightwindow"></div>
<div class="coach-box">
<div class="coach-container">
<h1 class="coach-heading">Mary</h1>
<div class="image-container chris-img coach-img-sizing"></div>
<div class="coach-text">
<p>Text block on this coach.</p> 
</div>
<button class="coach-button">Close</button>
</div>
</div>
</div>
<!-- ********************************************** -->
<div class="enlarge">
<div class="chris-img coach-img-sizing">
<div class="coach-overlay">
<h1 class="coach-name">Steve</h1>
</div>
</div>
</div>
<div id="chris" class="coach hidden">
<div class="lightwindow"></div>
<div class="coach-box">
<div class="coach-container">
<h1 class="coach-heading">Steve</h1>
<div class="image-container chris-img coach-img-sizing"></div>
<div class="coach-text">
<p>Text block on this coach.</p> 
</div>
<button class="coach-button">Close</button>
</div>
</div>
</div>
<!-- ********************************************** -->
<div class="enlarge">
<div class="chris-img coach-img-sizing">
<div class="coach-overlay">
<h1 class="coach-name">Alice</h1>
</div>
</div>
</div>
<div id="chris" class="coach hidden">
<div class="lightwindow"></div>
<div class="coach-box">
<div class="coach-container">
<h1 class="coach-heading">Alice</h1>
<div class="image-container chris-img coach-img-sizing"></div>
<div class="coach-text">
<p>Text block on this coach.</p> 
</div>
<button class="coach-button">Close</button>
</div>
</div>
</div>

我认为您的代码不完整,因为我看不到隐藏您的div 的 css 样式。 我假设它是这样的:

.coach {
display:none;
/* more styling... */
}

发生这种情况是因为 CSS 优先级。当 DOM 遇到更改并且元素再次呈现时,它会同时采用 CSS 类并处理它们。但是,由于这两个类(您为 coach 和 -enable 定义的内容)在一起,并且都尝试将显示设置为不同的值,因此最终处理了规则。

因此,为了解决此问题,您需要按以下方式对 CSS 规则进行排序:

.coach {
display:none;
}
.-enable {
display:block;
}

这样,如果存在 -enable ,它将是应用 .coach 后应用的最后一个样式。

关于这一点还有更多规则,例如,如果您基于 ID 或元素名称应用 CSS 样式,则有不同的优先级规则。您可以在此处阅读更多内容

最新更新