我需要你的支持来选择一个逻辑。我的脚本从数据库中抽取几行并显示在屏幕上。我想为每个数据提供一份反馈表。这些反馈表必须隐藏,并且应该在点击文本时可见(如回复此内容) - 请参考图片。
我在java脚本和CSS
的帮助下尝试过<script>
function hideElement()
{
document.getElementById("target").style.display="none";
}
function showElement()
{
document.getElementById("target").style.display="block";
}
</script>
// Data-1 fetched from DB goes here
<a href='#target'>Reply to this post</a>
<span id='target' style='display:none'>
// Feedback form for Data 1 here
</span>
// Data-2 fetched from DB goes here
<a href='#target'>Reply to this post</a>
<span id='target' style='display:none'>
// Feedback form for Data 2 here
</span>
但它仅适用于第一条记录, - Javascript找到名为“target”的第一个对象并设置display属性“none”或“block”
我可以使用什么逻辑来生成分配给每条记录的动态ID,并使java sript为此运行。还有其他更好的逻辑吗? (我确定也是)
答案 0 :(得分:4)
元素ID必须是唯一的,但只要您发现自己为重复元素生成唯一ID,就可能有更简单,更通用的方式来实现您正在做的任何事情。
对于这种类型的功能,您根本不需要ID,您可以使用类和DOM导航从单击的项目到相关的跨度,使用单个委派的事件处理程序,如下所示:
// bind click handler to the document
document.addEventListener("click", function(e) {
// test if the actual clicked item has the class "reply"
if (e.target.className.match(/\breply\b/)) {
e.preventDefault();
// find the related target span
var target = e.target.parentNode.querySelector(".target");
// update its visibility
target.style.display = target.style.display === "none" ? "block" : "none";
}
});
&#13;
<div> <!-- note added wrapper div -->
<a href='#target' class="reply">Reply to this post</a>
<span class='target' style='display:none'>
Feedback form for Data 1 here
</span>
</div>
<div> <!-- note added wrapper div -->
<a href='#target' class="reply">Reply to this post</a>
<span class='target' style='display:none'>
Feedback form for Data 2 here
</span>
</div>
&#13;
我在上面的JS中写了一些评论来解释它在做什么,但重要的是这一行:
var target = e.target.parentNode.querySelector(".target");
在事件监听器中,e
参数是event
对象,它包含有关正在处理的事件的各种信息。 e.target
告诉我点击了哪个元素。已经测试了该元素的类,看它是否是&#34;回复&#34;然后,我们使用.parentNode
属性来获取对我添加到标记的包装div的引用,然后从那里.querySelector(".target")
找到具有类target
的div的后代
正如您所看到的,我已修改您的html以支持上述内容,如下所示:
class="reply"
e.target.nextSibling
从锚点导航到范围,除非您必须添加额外的代码才能跳过任何文本节点。我发现一个更容易使用的包装元素。当然,如果您的元素已经在某种包装中用于其他目的,那么您可以使用现有的包装器。注意:最好删除内联样式,并通过添加和删除类来显示和隐藏跨度,而不是直接更新它们的样式,但这不是主要问题,所以我&#39 ;留下那个作为读者的练习。
答案 1 :(得分:0)
http://codepen.io/sheriffderek/pen/BzmAwg
第1步:抛弃这些ID
<ul class="item-list">
<li>
<p>default stuff</p>
<div class="hidden-thing">
hidden stuff
</div>
</li>
<li>
<p>default stuff</p>
<div class="hidden-thing">
hidden stuff
</div>
</li>
<li>
<p>default stuff</p>
<div class="hidden-thing">
hidden stuff
</div>
</li>
</ul>
第2步:隐藏CSS中的隐藏内容而不是内联
(这是手写笔语法......但同样重要)
.item-list
list-style: none
margin: 0
padding: 0
li
background: gray
padding: .5rem
margin-bottom: 1rem
cursor: pointer
.hidden-thing
display: none // hide it
第3步:使用jquery或使用vanilla JavaScript来获取要单击的内容 - 附加事件处理程序 - 使用this
来记录事件发生的元素 - 使用该元素...遍历DOM并查找事物你想要的 - 然后使用show方法,它设置display:block ...或fadeIn()或animate()或你喜欢的任何东西。
$('.item-list li').on('click', function() {
$(this).find('.hidden-thing').show();
});
// or...
$('.item-list li').on('click', function() {
$('.item-list li').find('.hidden-thing').hide();
$(this).find('.hidden-thing').show();
});
如果你想一次只打开一件隐藏的东西,你可以每次都隐藏所有的东西 - 这有点笨拙,但很平常。
但是......有一种更好的方法可以做到这一点,在这里你可以为整个项目添加一个活动的类。这使您可以在其中设置内容,通常可以为您提供更大的工作范围。这是一个例子。 :)它使用.closest - 并将事件传递给点击处理程序,以阻止外部点击操作冒泡:http://codepen.io/sheriffderek/pen/oLoqEy