обычно вы хотите использовать переменные url вместо хеша местоположения, чтобы достичь этого. но недостатком является то, что история браузера не распознает, как вы перебираете страницы с разными героями (что позволяет вам использовать кнопки вперед / назад). поэтому вам придется создать дополнительный код, чтобы это работало.
так что вот решение, где мы «храним» всю необходимую информацию в хеше местоположения. чтобы упростить синтаксический анализ, мы используем специальные символы в качестве разделителей (что происходит так же, как если бы вы использовали переменные url): &
для различия между различными переменными и =
для разделения пар ключ-значение.
хэш нового местоположения будет выглядеть так: #universe=dc&hero=aquaman
скрипт преобразует это в объект с именем selectedHero
, так что значения доступны с selectedHero.universe
и selectedHero.hero
как обычно, код помещается в функцию $( document ).ready(function(){
.
создать функцию для чтения хеша местоположения и возврата данных в виде объекта.
function getSelectedHero() {
var mySelectedHero = {}; //initialize a new empty object
var currentLocationHashValue = window.location.hash //read the location hash
.replace("#", "") //trim the '#' out of the string
.split(/[&]+/); //split the string into an array
$(currentLocationHashValue).each(function() { //loop through the freshly created array
mySelectedHero[this.split(/[=]+/)[0]] = this.split(/[=]+/)[1]; //split the string into key/value pairs and assign them to the object, created at the beginning of the function
});
return mySelectedHero; //return the object
}
у нас есть основные части здесь. первый разбивает хеш из #universe=dc&hero=aquaman
в массив с [0]="universe=dc"
и [1]="hero=aquaman"
во второй части мы перебираем все элементы массива (в данном случае есть только два, упомянутых выше) и снова разделяем их, создавая пары key -> value
для нужного объекта. return
доставляет следующий объект:
object{
universe: "dc",
hero: "aquaman"
}
теперь это можно легко использовать, чтобы выбрать правильную вкладку для выбранного героя
function showSelectedHeroTab(selectedHero) {
//don't forget to 'reset' the page, hiding all currently visible tabs
$(".universe").hide();
$(".hero").hide();
//then open tab for selected hero
$("#" + selectedHero.universe).show();
$("#" + selectedHero.hero).show();
}
это довольно просто, функция получает переданный объект, поэтому вы можете получить доступ к значениям, затем вы создаете свой селектор jquery с помощью "#"+
и своим именем переменной.
при включении только вышеперечисленных функций ничего не произойдет. поэтому мы изначально должны вызывать функции:
var selectedHero = getSelectedHero();
showSelectedHeroTab(selectedHero);
и, кроме того, мы хотим «обновлять» страницу всякий раз, когда изменяется хэш местоположения:
$(window).on("hashchange", function() {
var selectedHero = getSelectedHero();
showSelectedHeroTab(selectedHero);
});
этот код полностью пропускает какую-то обработку ошибок. поэтому, если хэш местоположения пуст, пара юниверс / герой не совпадает (например, marvel + batman) - так что вам придется добавить какую-то логику для пересылки на вкладку по умолчанию, когда данные непригодны для использования!
для целей тестирования я создал отдельную HTML-страницу, поэтому она выглядит иначе, чем ваша разметка, но, думаю, вы поймете, как переместить необходимые части в ваш код.
вот полный файл, включая html-разметку, скрипт и jquery cdn. просто скопируйте и вставьте в пустой файл, откройте в браузере и посмотрите, как он работает ...
<html>
<body>
<div id="header">
<p>
<a href="#universe=dc&hero=superman">superman</a>
<a href="#universe=dc&hero=batman">batman</a>
<a href="#universe=dc&hero=aquaman">aquaman</a>
<a href="#universe=dc&hero=flash">flash</a>
</p>
<p>
<a href="#universe=marvel&hero=hulk">the hulk</a>
<a href="#universe=marvel&hero=wolverine">wolverine</a>
<a href="#universe=marvel&hero=ironman">iron man</a>
<a href="#universe=marvel&hero=spiderman">spiderman</a>
</p>
</div>
<div id="body">
<div id="marvel" class="universe">marvel: <br/>
<div class="hero" id="hulk">
hulk
</div>
<div class="hero" id="ironman">
ironman
</div>
<div class="hero" id="wolverine">
wolverine
</div>
<div class="hero" id="spiderman">
spiderman
</div>
</div>
<div id="dc" class="universe">dc: <br/>
<div class="hero" id="superman">
superman
</div>
<div class="hero" id="batman">
batman
</div>
<div class="hero" id="aquaman">
aquaman
</div>
<div class="hero" id="flash">
flash
</div>
</div>
</div>
</body>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="crossorigin="anonymous">
</script>
<script>
$( document ).ready(function() {
// we create a function to get the location hash 'data' as an object
function getSelectedHero() {
var mySelectedHero = {}; //initialize a new empty object
var currentLocationHashValue = window.location.hash //read the location hash -> e.g. "#universe=dc&hero=batman"
.replace("#", "") //trim the '#' out of the string -> "universe=dc&hero=batman"
.split(/[&]+/) //split the string into an array -> [0]="universe=dc" [2]="hero=batman"
$(currentLocationHashValue).each(function() { //loop through the freshly created array
mySelectedHero[this.split(/[=]+/)[0]] = this.split(/[=]+/)[1]; //split the string into key/value pairs and assign them to the object, created at the beginning of the function
});
return mySelectedHero; //return the object
}
// and we create a function, that opens the desired tab
function showSelectedHeroTab(selectedHero) {
//first make sure, nothing is shown
$(".universe").hide();
$(".hero").hide();
//then open tab for selected hero
$("#" + selectedHero.universe).show();
$("#" + selectedHero.hero).show();
console.log (selectedHero);
}
//then we initally call the functions, to read the hash and show the tab
var selectedHero = getSelectedHero();
showSelectedHeroTab(selectedHero);
// additionally bind the event handler 'onhashchange' to fire when the location hash changes, to call the first two functions
$(window).on("hashchange", function() {
var selectedHero = getSelectedHero();
showSelectedHeroTab(selectedHero);
});
});
</script>
</html>