使用CSS和Javascript使多个数据“可见”或“隐藏”

时间:2016-07-13 03:02:46

标签: javascript html css logic

我需要你的支持来选择一个逻辑。我的脚本从数据库中抽取几行并显示在屏幕上。我想为每个数据提供一份反馈表。这些反馈表必须隐藏,并且应该在点击文本时可见(如回复此内容) - 请参考图片。

Sample record

我在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为此运行。还有其他更好的逻辑吗? (我确定也是)

2 个答案:

答案 0 :(得分:4)

元素ID必须是唯一的,但只要您发现自己为重复元素生成唯一ID,就可能有更简单,更通用的方式来实现您正在做的任何事情。

对于这种类型的功能,您根本不需要ID,您可以使用类和DOM导航从单击的项目到相关的跨度,使用单个委派的事件处理程序,如下所示:

&#13;
&#13;
// 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;
&#13;
&#13;

我在上面的JS中写了一些评论来解释它在做什么,但重要的是这一行:

var target = e.target.parentNode.querySelector(".target");

在事件监听器中,e参数是event对象,它包含有关正在处理的事件的各种信息。 e.target告诉我点击了哪个元素。已经测试了该元素的类,看它是否是&#34;回复&#34;然后,我们使用.parentNode属性来获取对我添加到标记的包装div的引用,然后从那里.querySelector(".target")找到具有类target的div的后代

正如您所看到的,我已修改您的html以支持上述内容,如下所示:

  1. 将span id更改为类
  2. 鉴于锚点class="reply"
  3. 为每个组添加了包装div元素,使DOM导航变得简单可靠。您可以使用e.target.nextSibling从锚点导航到范围,除非您必须添加额外的代码才能跳过任何文本节点。我发现一个更容易使用的包装元素。当然,如果您的元素已经在某种包装中用于其他目的,那么您可以使用现有的包装器。
  4. 注意:最好删除内联样式,并通过添加和删除类来显示和隐藏跨度,而不是直接更新它们的样式,但这不是主要问题,所以我&#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()或你喜欢的任何东西。

的JavaScript

$('.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