#javascript #php #html #css
Вопрос:
У меня есть общая боковая панель навигации, где я связал с ней несколько страниц. Я включил его на все страницы, используя приведенную ниже инструкцию php include.
<?php include '../php/playersidenav.php';?>
Боковое перемещение выглядит следующим образом.
<div class="column sidenav">
<div class="row">
<img src="../images/avatar.png" alt="Avatar">
<h1 style="color:white;float:right;padding-top:7%">Hello John!</h1>
</div>
<a class="normal" href="news.php" onclick="makeActive(event)">NEWS</a>
<a class="normal" href="schedule.php" onclick="makeActive(event)">SCHEDULE</a>
<a class="normal" href="partners.php" onclick="makeActive(event)">PARTNERS</a>
<a class="normal" href="coaches.php" onclick="makeActive(event)">COACHES</a>
<a class="normal" href="tournaments.php" onclick="makeActive(event)">TOURNAMENTS</a>
<a class="normal" href="events.php" onclick="makeActive(event)">EVENTS</a>
<a class="normal" href="shops.php" onclick="makeActive(event)">SHOPS</a>
</div>
Этот код работает нормально, за исключением того, что он не делает класс ссылок активным. Я использовал функцию javascript, чтобы сделать ссылки активными. Однако это не работает.
function makeActive(evt) {
var i, normal;
normal = document.getElementsByClassName("normal");
for (i = 0; i < normal.length; i ) {
normal[i].className = normal[i].className.replace(" active", "");
}
evt.currentTarget.className = " active";
}
И это код css, который я использовал для оформления ссылок, когда они были активированы.
.sidenav a.active {
background-color: #001F5A;
color: white;
border-radius: 5px;
}
Я пытался найти, что не так с моим кодом, но, похоже, не могу найти то, что я упускаю здесь. Пожалуйста, помогите! Спасибо Тебе!
Комментарии:
1. Разве это не нормальное действие, когда вы нажимаете на ссылку, чтобы перейти по этой ссылке? Код
onclick
события будет выполнен до перехода по ссылке, а не после перехода по ней. Это означает, что даже если ваш код работает, вы не увидите его очень долго. (Я не понимаю, почему люди отвергают этот вопрос? Более того, даже не оставив комментария…)
Ответ №1:
Одним из способов, которым вы могли бы это сделать, было бы использовать браузер localStorage
— Если вы playersidenav.php
немного измените вышесказанное, удалив встроенный обработчик событий, подобный этому, а затем включив в этот файл некоторый Javascript, чтобы он выглядел следующим образом:
<div class="column sidenav">
<div class="row">
<img src="../images/avatar.png" alt="Avatar">
<h1 style="color:white;float:right;padding-top:7%">Hello John!</h1>
</div>
<a class="normal" href="news.php">NEWS</a>
<a class="normal" href="schedule.php">SCHEDULE</a>
<a class="normal" href="partners.php">PARTNERS</a>
<a class="normal" href="coaches.php">COACHES</a>
<a class="normal" href="tournaments.php">TOURNAMENTS</a>
<a class="normal" href="events.php">EVENTS</a>
<a class="normal" href="shops.php">SHOPS</a>
</div>
<script>
//The name of the store in localStorage
const store='LINK_ACTIVATED_MEMORY';
// the class to add to indicate active state
const cn='active';
// nodelist of all sidenav links
const links=document.querySelectorAll('.sidenav > a.normal');
// ensure any "active" links have class removed and then
// save new hyperlink to localStorage
const makeActive=(e)=>{
e.preventDefault();
links.forEach(a=>a.classList.remove(cn));
localStorage.setItem( store, e.target.href );
location.href=e.target.href;
};
// on page load run this function - check the store
// and iterate through nodelist to match saved value and
// node value.
const loadActive=()=>{
let stored=localStorage.getItem( store );
if( stored==null )return;
Array.from( links ).some(a=>{
if( stored==a.href ){
a.classList.add(cn)
return true;
}
});
};
//bind the event handler
links.forEach(a=>a.addEventListener('click',makeActive));
// load active link class
loadActive();
</script>
Ссылка, по которой вы нажмете, будет сохранена, localStorage
а затем, когда будет загружена новая страница loadActive
, будет вызвана функция для задания active
класса. Согласно комментарию @Kiko Software — действие по умолчанию при нажатии на гиперссылку в любом случае замаскирует любую попытку выделения, поэтому фактическая настройка класса должна выполняться при загрузке/перезагрузке страницы.
Подумав о предложении @Kiko Software о том, что это можно сделать с помощью PHP и полностью отказаться от Javascript, я написал это в качестве альтернативного решения.
Включенный файл playersidenav.php
:
<?php
$cn='active';
$links=array(
'home.php' => 'TEST PAGE HOME',
'news.php' => 'NEWS',
'schedule.php' => 'SCHEDULE',
'partners.php' => 'PARTNERS',
'coaches.php' => 'COACHES',
'tournaments.php' => 'TOURNAMENTS',
'events.php' => 'EVENTS',
'shops.php' => 'SHOPS'
);
?>
<div class="column sidenav">
<div class="row">
<img src="../images/avatar.png" alt="Avatar" />
<h1 style="color:white; float:right; padding-top:7%">Hello John!</h1>
</div>
<?php
foreach( $links as $href => $text ){
printf(
'<a href="%s" class="normal %s">%s</a>',
$href,
( basename( $_SERVER['SCRIPT_FILENAME'] )==$href ? $cn : '' ),
$text
);
}
?>
</div>
И пример страницы, вызывающей указанный файл, называется home.php
:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
<style>
.sidenav a.active {
background-color: #001F5A;
color: white;
border-radius: 5px;
}
a{margin:1rem;}
</style>
</head>
<body>
<?php
require sprintf('%s/playersidenav.php',__DIR__);
?>
<h1>Hello World!</h1>
</body>
</html>
Файл включения PHP сравнивает ключ массива с базовым именем из текущей SCRIPT_FILENAME
переменной сервера и соответственно добавляет класс и полностью устраняет необходимость в Javascript. Просто подтверждает старую поговорку — "There's more than one way to skin a cat"
Комментарии:
1. Да, так лучше. Я не уверен, что для этого вам нужно использовать localStorage. Что-то вроде
$_SERVER['PHP_SELF']
или__FILE__
может быть использовано для поиска текущего активного сценария и не зависит от хранилища на стороне клиента.2. Вероятно, лучше никогда не использовать
$_SERVER['PHP_SELF']
, так как это может привести к появлению вредоносного кода, но я согласен, что это можно сделать с помощью PHP и не полагаться на localStorage3. Да,
$_SERVER['PHP_SELF']
может быть изменен пользователем и несет в себе риск. См.: Межсайтовые сценарии (XSS) и использование $_SERVER[‘PHP_SELF’]4. Есть ли способ установить активный класс на целевую страницу по умолчанию в первом предлагаемом решении, когда ссылка не нажата? (Может быть, я хочу сделать news.php активен сразу после входа игрока в систему.)
Ответ №2:
Решение № 1
function makeActive(evt) {
var i, normal;
normal = document.getElementsByClassName("normal")
for (i = 0; i < normal.length; i ) {
normal[i].className = "normal"
}
evt.target.className = "normal active"
}
Решение № 2
function makeActive(evt) {
var i, normal;
normal = document.getElementsByClassName("normal")
for (i = 0; i < normal.length; i ) {
normal[i].classList.remove('active')
}
evt.target.classList.add("active")
}