【问题标题】:How can I open (radio button) tabs from an outside link?如何从外部链接打开(单选按钮)选项卡?
【发布时间】:2020-10-22 17:40:06
【问题描述】:

我已经建立了一个网页,其中两个选项卡内有两个地图。我没有使用带有 href 和锚点的“ul>li>a”的经典结构,而是使用单选按钮。我的结构如下:

<div class="tabs">
  <input type="radio" name="tabs" id="tabone" checked="checked">
  <label for="tabone">title</label>
  <div class="tab">Content</div>

  <input type="radio" name="tabs" id="tabtwo">
  <label for="tabtwo">title</label>
  <div class="tab">Content</div>
</div>

要打开和隐藏内容面板,我使用以下 css:

.tabs .tab {
  border: 0;
  clip: rect(0 0 0 0);
  height: 1px;
  margin: -1px;
  overflow: hidden;
  padding: 0;
  position: absolute;
  width: 1px;
  -webkit-box-ordinal-group:3;
      -ms-flex-order:2;
          order:2;
}
.tabs input[type="radio"]:checked + label + .tab {
  clip: auto;
  height: auto;
  margin: 0;
  overflow: visible;
  position: static;
  width: 100%;
}

这里是 jquery 部分:

 $('#tabone').click(function() {
        $(this).attr('checked', true);
        $('#tabtwo').attr('checked', false);
    })
    $('#tabtwo').click(function() {
        $(this).attr('checked', true);
        $('#tabone').attr('checked', false);
    })

现在我正在尝试根据 url 打开选项卡:如果我输入:mysite.com/#tabtwo 我想在打开 tabtwo 的情况下直接加载页面。

我设法添加了哈希部分,现在我的 jquery 看起来像这样:

$("input[type=radio]").click(function() {
    window.location.hash = $(this).attr("data-href");
    if(window.location.hash === "#tabone"){
        $(this).attr('checked', true);
        $('#tabtwo').attr('checked', false);
    }else if(window.location.hash === "#tabtwo"){
        $(this).attr('checked', true);

        $('#tabone').attr('checked', false);
    }
});

单击的单选按钮将选中的属性添加到选项卡,但它始终以第一个选项卡打开。 如果我将“checked=checked”添加到两个单选按钮,它可以工作,我可以从外部输入 mysite.com/#tabtwo 并直接打开第二个选项卡。但是当然现在即使我输入 mysite.com/#tabone 它仍然会打开第二个标签!!

由于我已经使用这些单选按钮构建了我的网页,因此如果可能的话,我正在寻找具有这种结构的解决方案..

【问题讨论】:

    标签: jquery tabs


    【解决方案1】:

    最后,我看到了this topic,并使用提供的代码使其工作。

    解决方案 1

    我不得不将我的单选按钮更改为经典的 ul>li 选项卡。

     <div class="tabs">
       <ul class="nav nav-tabs" id="myTab" role="tablist">
          <li class="nav-item">
            <a class="nav-link active" id="left-tab" data-toggle="tab" href="#tab1" role="tab" aria-controls="log-in" aria-selected="true">My first tab</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" id="right-tab" data-toggle="tab" href="#tab2" role="tab" aria-controls="forgot-password" aria-selected="false">My second tab</a>
          </li>
        </ul>
         <div class="tab active" id="tab1"></div>
         <div class="tab" id="tab2"></div>
    </div>
    

    并像这样更改了我的 js 代码:

    1-首先,在标签内正确显示地图

     $('.nav-item a').on('click', function() {
                setTimeout(function() {
                    map.invalidateSize();
                    map2.invalidateSize();
                }, 0);
            });
    

    2-然后,切换选项卡并让外部 url 打开所需的选项卡

    $(document).ready(function() {
    
        $('#left-tab').click(function(event) {
            event.preventDefault();
            $('.tabs .nav-item a').removeClass('active');
            $('.tabs .tab').removeClass('active');
            $(this).addClass('active');
            $('#tab1').addClass('active');
        })
        $('#right-tab').click(function(event) {
            event.preventDefault();
            $('.tabs .nav-item a').removeClass('active');
            $('.tabs .tab').removeClass('active');
            $(this).addClass('active');
           $('#tab2').addClass('active');
        })
        function onHashChange() {// this let me open tabs from an external url
            var hash = window.location.hash;
    
            if (hash) {
    
                $(`[data-toggle="tab"][href="${hash}"]`).trigger('click');
            }
        }
    
        window.addEventListener('hashchange', onHashChange, false);
        onHashChange();
    });
    

    问题已部分解决。

    • 进入页面后,如果我单击选项卡,则 url/hash 不再更改。
    • 另外,选项卡会在 ID 所在的位置打开,这很正常,但在我的示例中,我相反希望禁用锚点跳转。

    解决方案 2:

    所以我不得不做一些改变:

    $(document).ready(function() {
    
    
        $('#left-tab').click(function(e) {
            window.location.hash = $(this).attr("href"); //this put back the hash
            if (location.hash) { // this allow to stay on top of the page
                  setTimeout(function() {
    
                    window.scrollTo(0, 0);
                  }, 1);
                }
            e.preventDefault()
    
            $('.tabs .nav-item a').removeClass('active');
            $('.tabs .tab').removeClass('active');
            $(this).addClass('active');
            $('#tab1').addClass('active');
        })
        $('#right-tab').click(function(e) {
    
            window.location.hash = $(this).attr("href");
                if (location.hash) {
                  setTimeout(function() {
    
                    window.scrollTo(0, 0);
                  }, 1);
                }
            e.preventDefault();
    
            $('.tabs .nav-item a').removeClass('active');
            $('.tabs .tab').removeClass('active');
            $(this).addClass('active');
           $('#tab2').addClass('active');
        })
        function onHashChange() { // this let me open tabs from an external url
    
            var hash = window.location.hash;    
    
            if (hash) {
                // using ES6 template string syntax
                $(`[data-toggle="tab"][href="${hash}"]`).trigger('click');
            }
        }
    
        window.addEventListener('hashchange', onHashChange, false);
        onHashChange();
    
    });
    

    现在效果更好了。当我来自外部 URL 时,例如 mysite.com#tab2,它会加载打开 tab2 的页面。然后,当我单击 tab1 时,它会打开 tab1,并停留在页面顶部。但是,它仍然不完美,仍然存在故障。

    解决方案 3:

    于是我寻找其他解决方案,发现this topic 和@jumois 的答案在于使用

    '目标元素的 id 与 锚。'

    所以我再次像这样更改了我的代码:

     $(document).ready(function() {
    
    
            $('#lefttab').click(function(e) {
                   $(window).on("hashchange", function(){
                var hash = this.location.hash;
                var mytab = $(hash + "-tab");
            });
                $('.tabs .nav-item a').removeClass('active');
                $('.tabs .tab').removeClass('active');
                $(this).addClass('active');
                $('#tab1-tab').addClass('active');
            })
            $('#righttab').click(function(e) {
    
               $(window).on("hashchange", function(){
                var hash = this.location.hash;
                var mytab = $(hash + "-tab");
            }); 
                $('.tabs .nav-item a').removeClass('active');
                $('.tabs .tab').removeClass('active');
                $(this).addClass('active');
               $('#tab2-tab').addClass('active');
            })
    
            function onHashChange() {    
                var hash = window.location.hash;    
                if (hash) {
                    // using ES6 template string syntax
                    $(`[data-toggle="tab"][href="${hash}"]`).trigger('click');
                }
            }
            window.addEventListener('hashchange', onHashChange, false);
            onHashChange();
    
        });
    

    当然,我也必须更改 html 部分:

    <div class="tabs">
        <ul class="nav nav-tabs" id="myTab" role="tablist">
                <li class="nav-item">
                    <a class="nav-link active" id="lefttab" data-toggle="tab" href="#tab1" role="tab" aria-controls="log-in" aria-selected="true">My first tab </a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" id="righttab" data-toggle="tab" href="#tab2" role="tab" aria-controls="forgot-password" aria-selected="false">My second tab</a>
                </li>
            </ul>
    <div class="tab active" id="tab1-tab"></div>
    <div class="tab " id="tab2-tab"></div>
    </div>
    

    现在看起来好多了。我可以从外部 url 打开一个标签,比如 mysite.com#tab2 并且不再有“跳转到锚点”的故障效果。

    【讨论】:

      【解决方案2】:

      有一种解决方案可以与现有的单选按钮标记一起使用 PHP 来通过从 url 中的查询字符串传递的变量来控制哪个按钮/选项卡处于“已检查”状态。这个例子基于“workotabs”,我觉得它简洁、健壮和灵活友好。这是原始标记:

      <div class="worko-tabs">
          <input class="state" type="radio" title="tab-one" name="tabs-state" id="tab-one" checked/>
          <input class="state" type="radio" title="tab-two" name="tabs-state" id="tab-two" />
          <input class="state" type="radio" title="tab-three" name="tabs-state" id="tab-three  /> 
          <div class="tabs flex-tabs">
              <label for="tab-one" id="tab-one-label" class="tab">TAB 1</label>
              <label for="tab-two" id="tab-two-label" class="tab"> TAB 2</label>
              <label for="tab-three" id="tab-three-label" class="tab">TAB 3</label>
      <div id="tab-one-panel" class="panel active"></div>
      <div id="tab-two-panel" class="panel"></div>
      <div id="tab-three-panel" class="panel"></div>
      </div>
      

      (https://codepen.io/axelaredz/pen/KJzVXK)

      修改为:

          <input class="state" type="radio" title="tab-one" name="tabs-state" id="tab-one" <?php if ($tab == '') { echo 'checked'; } else { echo ''; } ?> />
          <input class="state" type="radio" title="tab-two" name="tabs-state" id="tab-two" <?php if ($tab == '2') { echo 'checked'; } else { echo ''; } ?> />
          <input class="state" type="radio" title="tab-three" name="tabs-state" id="tab-three" <?php if ($tab == '3') { echo 'checked'; } else { echo ''; } ?> /> 
          <div class="tabs flex-tabs">
              <label for="tab-one" id="tab-one-label" class="tab">TAB 1</label>
              <label for="tab-two" id="tab-two-label" class="tab">TAB 2</label>
              <label for="tab-three" id="tab-three-label" class="tab">TAB 3</label>
      <div id="tab-one-panel" class="panel <?php if ($tab == '') { echo 'active'; } else { echo ''; } ?>"></div>
      <div id="tab-two-panel" class="panel <?php if ($tab == '2') { echo 'active'; } else { echo ''; } ?>"></div>
      <div id="tab-three-panel" class="panel <?php if ($tab == '2') { echo 'active'; } else { echo ''; } ?>"></div>
      

      插入的 PHP sn-ps 检查变量 '$tab' 的值。如果为空,则第一个选项卡默认为“选中”;如果值为 2 或 3 等(根据需要添加其他选项卡)“已选中”将添加到相应的选项卡标记中。 'else' 条件确保在页面加载时为不正确的状态清除 $tab 值,以防止出现缓存问题。 (注意:相同的代码被添加到选项卡面板中,但在相关标记中添加了“活动”而不是“选中”。您只需要在“活动”时更改选项卡面板的样式。否则您可以省略该部分中的 PHP 插入)。

      然后将下面这行PHP放到html标签上方的页眉中:

      <?php $tab = filter_var($_GET['tab'], FILTER_SANITIZE_SPECIAL_CHARS, 'UTF-8') ?>
      

      这将创建 $tab 变量并从引用 URL 查询字符串中获取其值。 (“过滤/清理”位对安全很重要)。

      现在您需要做的就是将 ?tab=2 或 ?tab=3 等附加到您的目标 URL,然后在页面加载时会打开正确的选项卡。默认情况下,没有任何查询字符串的引用 URL 仍将提供第一个选项卡。

      【讨论】:

      • 非常感谢您的详细解答;;我最终选择了 jquery 解决方案,但我会看看您的解决方案!谢谢!
      猜你喜欢
      • 1970-01-01
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-09
      • 2022-07-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多