如何从外部 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 仍将服务于第一个选项卡。
我建立了一个网页,在两个选项卡中包含两张地图。我没有使用带 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 仍将服务于第一个选项卡。