如何从外部 link 打开(单选按钮)选项卡?

How can I open (radio button) tabs from an outside link?

我建立了一个网页,在两个选项卡中包含两张地图。我没有使用带 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 它仍然打开第二个标签!!

因为我已经使用这些单选按钮构建了我的网页,所以如果可能的话,我正在寻找具有该结构的解决方案。

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

解决方案 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 不会再改变。
  • 另外,tab在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 的答案是使用

'different id for the target element than what is specified in the anchor.'

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

 $(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 并且不再有 "jump to anchor" 故障效果。

有一个解决方案可以使用 PHP 与现有单选按钮标记一起使用,通过从 button/tab 中的查询字符串传递的变量来控制哪个 button/tab 处于 'checked' 状态=43=]。这个例子基于“workotabs”,我觉得它简洁、健壮而且 flex-friendly。这是原始标记:

<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 片段检查变量“$tab”的值。如果为空,则第一个选项卡默认为 'checked';如果值为 2 或 3 等(根据需要添加其他选项卡)'checked' 将添加到相应的选项卡标记中。 'else' 条件确保为页面加载时不正确的状态清除 $tab 值,以防止缓存问题。 (注意:将相同的代码添加到选项卡面板,但将 'active' 而不是 'checked' 添加到相关标记中。您只需更改选项卡面板的样式即可 'active'。否则你可以从那个部分省略 PHP 插入。

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

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

这将创建 $tab 变量并从引用的 URL 查询字符串中获取其值。 ('filter/sanitize' 位对于安全性很重要)。

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