【问题标题】:Jquery - determining which link was clickedJquery - 确定点击了哪个链接
【发布时间】:2012-01-18 01:20:32
【问题描述】:

我有几个类似的链接会触发不同的导航 div 出现。我试图在 JQuery 中找到一种方法来确定单击了哪些链接,然后触发适当的打开/关闭功能。 html是:

<a href="" id="nav1">1</a>
<a href="" id="nav2">2</a>
<a href="" id="nav3">3</a>

<div id="hidden1">nav links 1</div>
<div id="hidden2">nav links 2</div>
<div id="hidden3">nav links 3</div>

目前我使用分配给每一对的简单切换,但想设置它,以便当有人打开隐藏的 div 然后单击另一个时,第一个将关闭。

已添加... 我很抱歉没有更详细地解释我的目标......导航菜单有三个项目需要在单击链接时进行更改。链接本身将 css 从文本更改为活动的“选项卡”,隐藏的导航在隐藏和显示之间切换,覆盖 div 也在隐藏和显示之间切换。当有人单击链接时,它应该显示覆盖和隐藏的 div 并将链接 css 更改为活动。如果他们再次单击该链接,它应该切换回来。这部分很容易做到。挑战来了(对我来说最不重要)是如果他们打开第一个隐藏然后单击第三个链接,我希望第一个隐藏关闭并将其链接更改为 css 恢复正常,第三个隐藏打开并将其链接更改为活动,但我希望白色保持打开状态(不打开/关闭创建闪烁)。 ...

我认为这可能有效,但不幸的是:

$("#nav1,#nav2,#nav3").click(function(e)
{ 
//determine nav id ...
var nav_id = $(this).attr('id').match(/\d+/);
});

最终的计划是确定点击的导航链接,然后检查背景覆盖是否可见。如果没有,则打开导航链接配对隐藏的 div 和覆盖。如果是,则检查是否打开了具有相同 nav_id 的隐藏 div,如果是,则关闭所有内容,如果没有,则关闭所有隐藏 div 并打开配对的隐藏 div。

【问题讨论】:

    标签: jquery html attr


    【解决方案1】:

    我将在这里冒险并建议不要持续编写围绕您的标记工作的代码,而是构建您的标记,以便您的代码自动运行。

    你应该用一个通用的类而不是一个 ID 来标记你的所有导航链接:

    <a href="#" class="navlink">Link 1</a>
    <a href="#" class="navlink">Link 2</a>
    <a href="#" class="navlink">Link 3</a>
    

    以及以类似方式隐藏的所有 div:

    <div class="navhidden">foo</div>
    <div class="navhidden">bar</div>
    <div class="navhidden">herp</div>
    

    现在您的代码可以很简单:

    jQuery(function($) {
    
        var $navlinks = $('.navlink'),
            $navhiddens = $('.navhidden'),
            $overlay = $('#overlay');
    
        $navlinks.on('click', function (e) {
    
            // this is your link
            $link = $(this);
    
            // get my hidden div + toggle
            $my_navhidden = $navhiddens
                .eq($navlinks.index(this))
                .toggle();
    
            // hide all the other navhiddens 
            $navhiddens.not($my_navhidden).hide();
    
            // hide or show the overlay?
            if ($navhiddens.filter(':visible').length > 0) {
                $overlay.show();
            } else {
                $overlay.hide();
            } 
    
        });
    
    });
    

    这具有能够在您的标记上添加更多链接 + navhiddens 的优势,而无需更改代码中的任何内容。此外,在 CSS 中添加 .navhidden { display:none; } 之类的内容来隐藏所有内容有多容易?

    当您添加新链接时,不要将$('#nav1,#nav2,#nav3') 更改为$('#nav1,#nav2,#nav3,#nav4') 等等,而是花时间给自己喝杯咖啡。无论如何,您都可以使用 Javascript / jQuery 来确定元素的序数索引;几乎不需要用诸如nav1nav2nav3 ...navn之类的序数序列来标记你的DOM元素。

    附带说明,.on 语法是 jQuery 1.7.x。如果您不使用它,请将其更改为 .bind。

    编辑

    添加了一些代码以在逻辑上打开和关闭覆盖。这不是最优雅的,但你明白了要点。

    【讨论】:

    • 简单优雅,谢谢。我可以让它为链接和隐藏的 div 工作,但还没有完全弄清楚如何添加覆盖控件(请参阅我在原始帖子中的附加组件)。
    • 查看编辑中的附加代码。您可能可以在最终代码中制作类似于的东西。 :)
    • 我可以学会自动爱上这些东西。就像一个魅力,与我们的原始版本相比,代码行数减少了很多。 谢谢!
    【解决方案2】:

    你可以使用rel

    html:

    <a rel="div_id_to_open1" class="expander">Click me</a>
    <a rel="div_id_to_open2" class="expander">Click me</a>
    <a rel="div_id_to_open3" class="expander">Click me</a>
    
    <div id="div_id_to_open1">Foo</div>
    <div id="div_id_to_open2">Foo</div>
    <div id="div_id_to_open3">Foo</div>
    

    javascript:

    $('.expander').click(function(e) {
       $('#' + $(this).attr('rel')).toggle();
       e.preventDefault();
       return false;
    });
    

    如果你想知道被点击的锚点的相对位置,你可以使用 .index() ,但是你需要包裹锚点:

    jsfiddle

    【讨论】:

    • 谢谢,但我已经让它通过切换功能运行,以便每个 navX 触发其相应的 hiddenX。我正在尝试确定单击了哪个导航并找到它的数字组件,以便我可以获取该数字组件并通过一些 if/then 函数运行它。
    • 已编辑,请检查 js fiddle 看看是否是您想要的
    【解决方案3】:

    like this jsFiddle 怎么样?

    当您点击一个链接时,相应的 div 会显示,而所有其他 div 会隐藏。

    $('#hidden1,#hidden2,#hidden3').hide();
    $("#nav1,#nav2,#nav3").click(function(e)
    {
        e.preventDefault();
        $('#hidden1,#hidden2,#hidden3').hide();
        $('div:eq('+$(this).index()+')').show();
    });
    

    【讨论】:

      【解决方案4】:

      Andreas 的建议是合理的 - rel 属性对于这类事情非常有用,如果您可以控制元素,这是正确的方法。

      至于您的原始方法,它应该也可以工作(尽管增加了正则表达式开销)。请记住,匹配将返回一个数组或空值。如果你放弃空检查,你会使用类似的东西:

      var nav_id = $(this).attr('id').match(/\d+/)[0];

      另一个提示:在 jQuery 选择器中指定元素类型是加快加载时间的好习惯。例如:$('a#nav1') vs $('#nav1'), $('a.expander') vs $('.expander')

      【讨论】:

      • 感谢关于指定元素类型的建议。总是希望加快速度。
      【解决方案5】:

      这是我的 html 页面(Django 模板):

      <div class="col">
          {% for blog in blogs %}
          <div class="post">
              <h3><a href="{% url 'blog:detail' pk=blog.pk %}">{{ blog.title }}</a></h3>
              <div class="date">
                  <p>Created: {{blog.date_created|date:'d M Y'}}</p>
              </div>
              <p>{{ blog.brief|safe }}</p>  
      
              <ul class="nav justify-content-end">
                  <li class="nav-item">
                    <a class="nav-link active" href="{% url 'blog:edit' pk=blog.pk %}">Edit</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" id="publish" href="{{blog.pk}}">Publish</a>
                  </li>
                  <li class="nav-item">
                      <a class="btn btn-danger" id="remove" href="{{blog.pk}}">Remove</a>
                  </li>
                </ul>
              <br>
          </div>
          {% endfor %}
      </div>
      

      在我的 javascript 文件中,这是有的并且可以工作的。

      $(document).ready(function() {
      
          console.log("document is ready!!!")
      
          $('#id_bloglist').on("click", 'a#publish,a#remove', function(e) {
      
          e.preventDefault()
      
          var pk = $(this).attr("href")
      
          if ($(this)[0].id == 'remove'){
              console.log("remove link clicked, calling deleteBlog with pk = " + pk)
          }
          else if ($(this)[0].id == 'publish'){
              console.log("publish link clicked, calling publishBlog with pk = " + pk)
          }
      
          return false;
         });
      });
      

      【讨论】:

      • 谢谢,大约 6 年前我问过这个问题,从那时起我就转向了直接的 js 并远离了框架。但也许未来的访问者可以从您的贡献中受益。
      猜你喜欢
      • 2012-06-05
      • 1970-01-01
      • 2012-04-17
      • 1970-01-01
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-18
      相关资源
      最近更新 更多