【问题标题】:Simplify this javascript for Show one, Hide Rest为 Show one, Hide Rest 简化这个 javascript
【发布时间】:2014-11-19 14:08:42
【问题描述】:

我正在为一个图库使用脚本,在该脚本中单击导航中的一个元素只会显示一个 div,但会隐藏其他 div。

目前我的脚本非常具体,因为我需要为每个可能的实例添加一个新函数。见下文...您可以想象添加的图像越多,这种情况就越容易失控。

有人可以帮我使这段代码更通用和优雅吗?我对 Javascript/JQuery 不是很有经验,但这有点令人尴尬,哈哈

因此,如果从代码中不清楚:#li1、#li2、#li3 等是始终可见的导航缩略图。 #img1、#img2、#img3 等是变量显示的 div。当一个可见时,其余的应该隐藏。

其他问题:

  • 对于每个显示的 #img1,我还想在单独的 div 中显示一个标题,比如 #title1、#title2 等。我该怎么做?因此,例如单击#li1 将显示#img1 和#title1,但隐藏所有其他#img.. 和#title..

  • 所有 # 都包含图像。我注意到,当其中一个图像损坏时,整个脚本将停止正常工作(所有#img.. div 立即显示)。这是为什么呢?

  • 此脚本实际上不会隐藏所有图像,直到所有内容都加载完毕,在本地运行 HTML 时您不会注意到这一点,但在等待图像下载时会这样做。我怀疑是因为 $("#li1").load(function() 指的是文档中更靠后的 div。我该如何解决这个问题?

我希望我没有问太多,我自己试图理解这一点,但我无法弄清楚。

$("#li1").load(function() {
   $("#img2, #img3, #img4, #img5, #img6, #img7, #img8, #img9, #img10, #img0, #intro").hide();
   $("#img1").show();
});
$("#li1").on('click', function() {
   $("#img2, #img3, #img4, #img5, #img6, #img7, #img8, #img9, #img10, #img0").hide();
   $("#img1").show();
});
$("#li2").on('click', function() {
   $("#img1, #img3, #img4, #img5, #img6, #img7, #img8, #img9, #img10, #img0").hide();
   $("#img2").show();
});
$("#li3").on('click', function() {
   $("#img2, #img1, #img4, #img5, #img6, #img7, #img8, #img9, #img10, #img0").hide();
   $("#img3").show();
});

etc.

【问题讨论】:

  • 你应该把这个问题发到codereview.stackexchange.com
  • 我会为所有项目添加一个公共类。一个电话,您可以隐藏所有,然后显示 1
  • 您能否展示一些 HTML 示例,看看那些 #li 和一些父元素是什么?
  • 如果没有 HTML,您的代码 sn-p 将毫无用处。

标签: javascript jquery html css


【解决方案1】:

我可能会尝试这样的事情:

缩略图像:

<li class="thumbnail" data-imageId="0">
  ...thumbnail...
</li>
<li class="thumbnail" data-imageId="1">
  ...thumbnail...
</li>
<li class="thumbnail" data-imageId="2">
  ...thumbnail...
</li>

图片如下:

<div class="image" data-imageId="0">
  ...image...
</div>
<div class="image" data-imageId="1" style="display: none;">
  ...image...
</div>
<div class="image" data-imageId="2" style="display: none;">
  ...image...
</div>
<!-- The style attribute in these element hides the element by default,
     while still allowing jQuery to show them using show(). -->

然后是JS:

$(".thumbnail").click(function() {
   // Hides all images.
   $(".image").hide();

   // Shows appropriate one.
   var imageId = $(this).data("imageId"); // Fetches the value of the data-imageId attribute.
   $(".image[data-imageId="+imageId+"]").show();
});

【讨论】:

  • 完美,这正是我想要的!因此,如果我想为每张图片(包含标题)显示第二个 div,是否可以通过为该 div 提供与随附照片相同的类和 data-imageId 来实现?
  • 实际上,是的,这是一种方式。另一种方法是使 .image 元素成为您要为每个图像显示的整个“包”内容的根。最好的解决方案取决于您的 HTML 结构。 :-)
  • 为什么不使用$(this).data("imageId")
  • @TheVillageIdiot 好建议,谢谢。我实际上忘记了那个,当我写我的答案时,jQuery API 处于离线状态,所以我无法查阅它。
【解决方案2】:

我看到您的 li 的 id 为“li1”、“li2”等。为它们分配一个特定的类,例如“liLinks”。

然后,为该类添加一个事件处理程序,如下所示:

$(".liLinks").click(function(){    
var ImageToShow = $(this).prop("id").replace("li", ""); // This gets the number of the li

    for (i=0; i<= 10; i++){ //or however many images you have
        if (i != ImageToShow)
            $("#img" + i).hide();
        else
            $("#img" + i).show();
    } 
});

哦,您可以使用上面使用的相同方法显示和隐藏任何其他元素。只要确保它们的命名约定相同,您就应该准备就绪!

【讨论】:

    【解决方案3】:

    所以,我有两个解决方案给你:

    第一个选项:编辑 HTML 代码以修复此逻辑:

    <li class="nav" data-image="0">0</li>
    <li class="nav" data-image="1">2</li>
    <li class="nav" data-image="2">3</li>
    ...
    

    ...等等。

    现在 JavaScript 代码将变得非常简短和容易,这里是:

    function showOne(e) {
        var max = 5, // assuming that there are 5 images, from #img0 to #img4
            toShow = e.target.dataset.image;
    
        for (var i=0; i < max; i++) {
            if (i == toShow) $('#img'+i).hide();
            else $('#img'+i).show();
        }
    }
    
    $('.nav').bind('click', showOne);
    

    如果你的逻辑不是这个,那么我建议你编辑 HTML 来修复这个逻辑,这是做你想做的最简单的方法。


    第二种选择:我假设你使用这样的逻辑:

    • #li0 显示#img0
    • #li1 显示#img1
    • #li2 显示#img2
    • ...
    • #liN 显示数组的第 N 个 img

    下面是代码:

    function showOne() {
        var max = 4, // assuming that there are 5 images, from #img0 to #img4
            toShow = this.id.substr(2);
    
    
        $('#img'+toShow).show();
        for (var i=0; i < max; i++) {
            if (i != toShow) $('#img'+i).hide();
        }
    }
    
    $('#li0, #li1, #li2, #li3, #li4').bind('click', showOne);
    

    在这个 sn-p 中,我只使用了 5 张图片,但您可以添加更多图片,更改 max 的值并在 $('#li0, #li1, ...) 选择器中添加相关的 li 元素。

    【讨论】:

    • 这是极其昂贵和浪费的,并且不会原子地执行更改,这可能会导致动画显着不同步。你可以把它变成一个单一的原子类更改。没有理由涉及 jQuery、绑定或 dom walk。
    【解决方案4】:

    只需使用 CSS 将它们全部隐藏,然后覆盖您想要显示的那个。

    <!doctype html>
    <html>
    
      <head>
        <style type="text/css">
    
          #showbox img { display: none; width: 300px; }
    
          #showbox.show1 img#img1,
          #showbox.show2 img#img2,
          #showbox.show3 img#img3,
          #showbox.show4 img#img4 { display: block; }
    
        </style>
      </head>
    
      <body>
    
        <div id="showbox" class="3">
          <img id="img1" src="http://upload.wikimedia.org/wikipedia/commons/6/6f/ChessSet.jpg">
          <img id="img2" src="http://upload.wikimedia.org/wikipedia/commons/c/c3/Chess_board_opening_staunton.jpg">
          <img id="img3" src="http://www.umbc.edu/studentlife/orgs/chess/images/News%20and%20Events/chess_sets.jpg">
          <img id="img4" src="http://upload.wikimedia.org/wikipedia/commons/thumb/9/97/Russisches_festungsschach.PNG/350px-Russisches_festungsschach.PNG">
        </div>
    
        <input onchange="document.getElementById('showbox').className = 'show' + this.value;">
    
      </body>
    
    </html>
    

    【讨论】:

      【解决方案5】:

      在加载图像时,您的图像没有隐藏,因为您没有使用 $(函数(){ $("imgs").hide (); }); 当加载 DOM (HTML) 而不是图像时,将执行此功能。 代码将是“HTML”: 链接1 链接2 链接3 ...

      jQuery: $(函数(){ $(".img").hide (); $(".nav").click (函数 (e) { $(".img").show (); }); });

      正如您可能期望的那样,您需要将此代码更改为更渐进式,但您现在有了在页面结束时隐藏它们而不是在图像完成下载时隐藏它们的想法。祝你好运;)。

      【讨论】:

        【解决方案6】:

        var $img = $('#images img'); /* Cache your selector */
        $('#nav li').click(function(){
          $img.fadeOut().eq( $(this).index() ).stop().fadeIn();
        });
        #images{ position:relative; }
        #images img{ position:absolute; left:0; }
        #images img + img {display:none; } /* hide all but first */
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <ul id=nav>
          <li>1</li>
          <li>2</li>
          <li>3</li>
        </ul>
        
        <div id=images>
          <img src="//placehold.it/50x50/cf5" alt="">
          <img src="//placehold.it/50x50/f0f" alt="">
          <img src="//placehold.it/50x50/444" alt="">
        </div>

        【讨论】:

          【解决方案7】:

          以下是一种方法:

          1. 添加特殊类来识别图像。
          2. 使用类来显示/隐藏图像,例如:.showing{display:block;}
          3. 使用data 属性存储标题,如:data-title="title"
          4. 添加类以识别li,并使用另一个类(如active)标记选中的li

          $(function() {
            $("li.switch").click(function() {
              var liActive = $("li.active");
              var imgActive = liActive.data("image");
              $(imgActive).removeClass("showing").addClass("hidden");
              $(liActive).removeClass("active");
          
              //currently clicked li
              var $this = $(this);
              $this.addClass("active");
              var d = $this.data("image");
              $(d).removeClass("hidden").addClass("showing");
              $("#imgTitle").text($(d).data("title"));
            });
          });
          .gallery {
            width: 250px;
            height: 250px;
            padding: 10px;
          }
          img {
            height: 200px;
            width: 200px;
            margin: auto auto;
          }
          .hidden {
            display: none;
          }
          .showing {
            display: inline-block;
          }
          ul {
            list-style: none none outside;
            display: inline;
          }
          li {
            list-style: none none outside;
            display: inline-block;
            padding: 3px 6px;
            border: 1px solid grey;
            color: #0f0;
            cursor: pointer;
          }
          li.active {
            border: 2px solid red;
            background-color: #c0c0c0;
            color: #f00;
          }
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
          
          <div class="gallery">
            <img src='https://c2.staticflickr.com/4/3862/15320672416_65b28179b4_c.jpg' class='gimage showing' id='img1' data-title="This is image 1" />
            <img src='https://c2.staticflickr.com/4/3893/15156335390_16e16aa1c9_c.jpg' class='gimage hidden' id='img2' data-title="This is image 2" />
            <img src='https://c1.staticflickr.com/3/2942/15341799225_09d0f05098_c.jpg' class='gimage hidden' id='img3' data-title="This is image 3" />
            <img src='https://c2.staticflickr.com/4/3907/15339877992_695dd1daae_c.jpg' class='gimage hidden' id='img4' data-title="This is image 4" />
            <img src='https://farm3.staticflickr.com/2942/15333547162_325fefd6d1.jpg' class='gimage hidden' id='img5' data-title="This is image 5" />
          </div>
          <div id="imgTitle"></div>
          <ul>
            <li class="switch active" id="li1" data-image="#img1">1</li>
            <li class="switch" id="li1" data-image="#img2">2</li>
            <li class="switch" id="li1" data-image="#img3">3</li>
            <li class="switch" id="li1" data-image="#img4">4</li>
            <li class="switch" id="li1" data-image="#img5">5</li>
          </ul>

          在这个fiddle

          中试试

          【讨论】:

            【解决方案8】:

            修复 Ricardo van den Broek的代码,因为

            var imageId = $(this).data("imageId");
            

            似乎不起作用。它返回“未定义”。所以我们需要把它改成

            var imageId = $(this).attr("data-imageId");
            

            这里是所有代码,

            HTML(缩略图部分)

            <ul>
                <li class="thumbnail" data-imageId="0">
                    Thumbnail 0
                </li>
                <li class="thumbnail" data-imageId="1">
                    Thumbnail 1
                </li>
                <li class="thumbnail" data-imageId="2">
                    Thumbnail 2
                </li>
            </ul>
            

            HTML(图片部分)

            <div class="image" data-imageId="0">
                Image 0
            </div>
            <div class="image" data-imageId="1" style="display: none;">
                Image 1
            </div>
            <div class="image" data-imageId="2" style="display: none;">
                Image 2
            </div>
            

            JavaScript (jQuery)

            $(".thumbnail").click(function() {
                $(".image").hide();
            
                // Shows the appropriate one.
                var imageId = $(this).attr("data-imageId");
            
                $(".image[data-imageId="+imageId+"]").show();
            });
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-12-08
              相关资源
              最近更新 更多