Делаем navbar
Иногда нужно сделать navbar и переключать класс active на выбранной ссылке. Это можно сделать по-разному, расскажу об одном решении. Допустим у нас есть простое Flask - приложение:
1 from flask import Flask, render_template 2 app = Flask(__name__) 3 4 5 @app.route('/') 6 def main(): 7 return render_template('base.html') 8 9 10 @app.route('/about') 11 def about(): 12 return render_template('base.html')
И base.html:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous"> 7 <link rel="stylesheet" href="{{ url_for('static',filename='css/mysite.css') }}"> 8 </head> 9 <body> 10 11 <nav class="nav"> 12 <a class="nav-link" href="/">Блог</a> 13 <a class="nav-link" href="/about">Об авторе</a> 14 </nav> 15 16 <script 17 src="https://code.jquery.com/jquery-3.2.1.slim.min.js" 18 integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g=" 19 crossorigin="anonymous"></script> 20 <script src="{{ url_for('static',filename='js/mysite.js') }}"></script> 21 </body> 22 </html>
mysite.css:
1 .active { 2 background-color: grey; 3 }
И хочется добавлять класс active при клике на каждую ссылку в navbar'e. Можно использовать передачу переменных в шаблон:
1 @app.route('/') 2 def main(): 3 return render_template('base.html', tab="") 4 5 6 @app.route('/about') 7 def about(): 8 return render_template('base.html', tab="about")
1 <nav class="nav"> 2 <a class="nav-link {% if tab == "" %}active{% endif %}" href="/">Блог</a> 3 <a class="nav-link {% if tab == "about" %}active{% endif %}" href="/about">Об авторе</a> 4 </nav>
Но можно ведь использовать js, сначала хочется сделать что-то вроде (mysite.js):
1 var selector = '.nav-link'; 2 $(selector).on('click', function(){ 3 $(selector).removeClass('active'); 4 $(this).addClass('active'); 5 });
Но это не будет работать, потому что после переключения класса страница обновится, и класс исчезнет со ссылки. Можно сделать по-другому:
1 <nav class="nav"> 2 <a class="nav-link" href="/">Блог</a> 3 <a class="nav-link" href="/about">Об авторе</a> 4 </nav>
1 $(document).ready(function() { 2 const regex = /http:\/\/.*\/(.*)/g; 3 const match = regex.exec(window.location.href); 4 // iterate over all and find match 5 if (match) { 6 $(".nav-link").each(function() { 7 if ($(this).attr("href").slice(1) == match[1]) { 8 $(this).addClass("active"); 9 } 10 }); 11 } 12 // set active first element 13 else { 14 $(".nav-link:first").addClass("active"); 15 } 16 });
Тоесть используя window.location.href получаем текущий адрес, регулярным выражением пытаемся получить правую часть адреса, если не получается, то ставим active на первую ссылку, в другом случае находим соответствующую ссылку и ставим класс ей.
Говорят, что если у тебя есть проблема, и ты ее решаешь с помощью регулярных выражений, то у тебя две проблемы. Пожалуй, лучше переписать этот код, не используя регулярки:
1 $(document).ready(function() { 2 const href = window.location.href.split('/'); 3 const last = href[href.length - 1]; 4 // iterate over all and find match 5 if (last) { 6 $(".nav-link").each(function() { 7 if ($(this).attr("href").slice(1) == last) { 8 $(this).addClass("active"); 9 } 10 }); 11 } 12 // set active first element 13 else { 14 $(".nav-link:first").addClass("active"); 15 } 16 });
Есть разные способы решить данную проблему, я описал некоторые из них, надеюсь для кого-то это было полезно.