У меня есть вложенная прокручиваемая область, и проблема в том, что, когда я нажимаю на якорь хэша, основное окно прокручивается, но я хочу, чтобы прокручивалась только внутренняя область.
Мой код
{% extends "base.html" %}
{% load static %}
{% load humanize %}
{% block title %}
<title>Факторы</title>
{% endblock title %}
{% block content %}
<div class="ptop">
{% for factor in object_list %}
<div class="container mb-3 pb-3" >
<nav id="navbar-example{{factor.id}}" class="navbar navbar-light bg-light px-3 ">
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading1{{factor.id}}">Информация о факторе</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading2{{factor.id}}">Продукты</a>
</li>
</ul>
</nav>
<div data-bs-spy="scroll" data-bs-target="#navbar-example{{factor.id}}" data-bs-offset="0" class="scrollspy-example factor-card" tabindex="0">
<h4 id="scrollspyHeading1{{factor.id}}">Информация о факторе</h4>
<div>
<table class="table">
<thead>
<tr class="text-center">
<th scope="col">Идентификатор фактора</th>
<th scope="col">Сумма фактора</th>
<th scope="col">Дата и время</th>
<th scope="col">Статус доставки</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
<td>{{factor.id}}</td>
<td>{{factor.payment.amount}}</td>
<td>{{factor.payment.time}}</td>
<td>
{% if factor.delevery_status == 0 %}
Не отправлено
{% else %}
Отправлено
{% endif %}
</td>
</tr>
</tbody>
</table>
</div>
<h4 id="scrollspyHeading2{{factor.id}}">Продукты</h4>
<div>
<table class="table">
<thead>
<tr class="text-center">
<th scope="col">Название продукта</th>
<th scope="col">Количество продукта</th>
<th scope="col">Цена за единицу</th>
<th scope="col">Общая цена</th>
</tr>
</thead>
<tbody>
{% for product in factor.factoritem_set.all %}
<tr class="text-center">
<td>{{product.title}}</td>
<td>{{product.number}}</td>
<td>{{product.price}}</td>
<td>{{product.item_price}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% empty %}
<div class="noproduct">
Нет факторов для отображения
<br>
<i class="bi bi-card-list" style="font-size:65px;"></i>
</div>
{% endfor %}
</div>
{% endblock content %}
Я использую этот код в шаблонах Django, и каждый раз, когда я пытаюсь прокрутить основную страницу, она прокручивает вместе с внутренней прокруткой.
Что я хочу, выглядит так:
Пример
.myclass{
max-height: 250px;
overflow-y: auto;
border: #ffd036 solid 2px;
border-radius: 5px;
padding: 10px;
}
.myclass > div{
min-height: 195px !important;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<nav id="navbar-example21" class="navbar bg-body-tertiary pb-3 mt-3">
<a class="navbar-brand" href="#">Навигация</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading11">Первый</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading21">Второй</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">abc</a>
</li>
</ul>
</nav>
<div data-bs-spy="scroll" data-bs-target="#navbar-example21" data-bs-root-margin="0px 0px -40%" data-bs-smooth-scroll="true" class="scrollspy-example bg-body-tertiary p-3 myclass rounded-2" tabindex="0">
<h4 id="scrollspyHeading11">Первый заголовок</h4>
<div>
<table class="table">
<thead>
<tr class="text-center">
<th scope="col">Название продукта</th>
<th scope="col">Количество продукта</th>
<th scope="col">Цена за единицу</th>
<th scope="col">Общая цена</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
<td>title</td>
<td>number</td>
<td>price</td>
<td>item_price</td>
</tr>
</tbody>
</table>
</div>
<h4 id="scrollspyHeading21">Второй заголовок</h4>
<div>
<table class="table">
<thead>
<tr class="text-center">
<th scope="col">Идентификатор фактора</th>
<th scope="col">Сумма фактора</th>
<th scope="col">Дата и время</th>
<th scope="col">Статус доставки</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
<td>id</td>
<td>amount</td>
<td>time</td>
<td>
1234
</td>
</tr>
</tbody>
</table>
</div>
</div>
<nav id="navbar-example22" class="navbar bg-body-tertiary px-3 mt-3">
<a class="navbar-brand" href="#">Навигация</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading12">Первый</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading22">Второй</a>
</li>
</ul>
</nav>
<div data-bs-spy="scroll" data-bs-target="#navbar-example22" data-bs-root-margin="0px 0px -40%" data-bs-smooth-scroll="true" class="scrollspy-example bg-body-tertiary p-3 myclass rounded-2" tabindex="0">
<h4 id="scrollspyHeading12">Первый заголовок</h4>
<div>
<table class="table">
<thead>
<tr class="text-center">
<th scope="col">Название продукта</th>
<th scope="col">Количество продукта</th>
<th scope="col">Цена за единицу</th>
<th scope="col">Общая цена</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
<td>title</td>
<td>number</td>
<td>price</td>
<td>item_price</td>
</tr>
</tbody>
</table>
</div>
<h4 id="scrollspyHeading22">Второй заголовок</h4>
<div>
<table class="table">
<thead>
<tr class="text-center">
<th scope="col">Идентификатор фактора</th>
<th scope="col">Сумма фактора</th>
<th scope="col">Дата и время</th>
<th scope="col">Статус доставки</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
<td>id</td>
<td>amount</td>
<td>time</td>
<td>
1234
</td>
</tr>
</tbody>
</table>
</div>
</div>
<nav id="navbar-example23" class="navbar bg-body-tertiary px-3 mt-3">
<a class="navbar-brand" href="#">Навигация</a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading13">Первый</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading23">Второй</a>
</li>
</ul>
</nav>
<div data-bs-spy="scroll" data-bs-target="#navbar-example23" data-bs-root-margin="0px 0px -40%" data-bs-smooth-scroll="true" class="scrollspy-example bg-body-tertiary p-3 myclass rounded-2" tabindex="0">
<h4 id="scrollspyHeading13">Первый заголовок</h4>
<div>
<table class="table">
<thead>
<tr class="text-center">
<th scope="col">Название продукта</th>
<th scope="col">Количество продукта</th>
<th scope="col">Цена за единицу</th>
<th scope="col">Общая цена</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
<td>title</td>
<td>number</td>
<td>price</td>
<td>item_price</td>
</tr>
</tbody>
</table>
</div>
<h4 id="scrollspyHeading23">Второй заголовок</h4>
<div>
<table class="table">
<thead>
<tr class="text-center">
<th scope="col">Идентификатор фактора</th>
<th scope="col">Сумма фактора</th>
<th scope="col">Дата и время</th>
<th scope="col">Статус доставки</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
<td>id</td>
<td>amount</td>
<td>time</td>
<td>
1234
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
Я не знаю, как это исправить.
- python -> 3.12
- Django -> 5
- html -> 5
- bootstrap -> 5
Ответ
Чтобы добиться прокрутки внутренней области, а не основной страницы, когда вы кликаете на якорный элемент, можно использовать JavaScript для предотвращения стандартного поведения браузера при переходе по якорям. Вместо этого вы будете прокручивать только внутренний прокручиваемый контейнер. Вот пример кода на основе вашего шаблона Django, который должен помочь вам решить эту проблему.
HTML / Django Template
{% extends "base.html" %}
{% load static %}
{% load humanize %}
{% block title %}
<title>Факторы</title>
{% endblock title %}
{% block content %}
<div class="ptop">
{% for factor in object_list %}
<div class="container mb-3 pb-3">
<nav id="navbar-example{{factor.id}}" class="navbar navbar-light bg-light px-3">
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading1{{factor.id}}" class="inner-scroll">Информация о факторе</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#scrollspyHeading2{{factor.id}}" class="inner-scroll">Продукты</a>
</li>
</ul>
</nav>
<div id="scrolling-area{{factor.id}}" class="scrollspy-example factor-card" tabindex="0" style="max-height: 250px; overflow-y: auto;">
<h4 id="scrollspyHeading1{{factor.id}}">Информация о факторе</h4>
<div>
<table class="table">
<thead>
<tr class="text-center">
<th scope="col">Идентификатор фактора</th>
<th scope="col">Сумма фактора</th>
<th scope="col">Дата и время</th>
<th scope="col">Статус доставки</th>
</tr>
</thead>
<tbody>
<tr class="text-center">
<td>{{factor.id}}</td>
<td>{{factor.payment.amount}}</td>
<td>{{factor.payment.time}}</td>
<td>
{% if factor.delevery_status == 0 %}
Не отправлено
{% else %}
Отправлено
{% endif %}
</td>
</tr>
</tbody>
</table>
</div>
<h4 id="scrollspyHeading2{{factor.id}}">Продукты</h4>
<div>
<table class="table">
<thead>
<tr class="text-center">
<th scope="col">Название продукта</th>
<th scope="col">Количество продукта</th>
<th scope="col">Цена за единицу</th>
<th scope="col">Общая цена</th>
</tr>
</thead>
<tbody>
{% for product in factor.factoritem_set.all %}
<tr class="text-center">
<td>{{product.title}}</td>
<td>{{product.number}}</td>
<td>{{product.price}}</td>
<td>{{product.item_price}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% empty %}
<div class="noproduct">
Нет доступных факторов для отображения
<br>
<i class="bi bi-card-list" style="font-size:65px;"></i>
</div>
{% endfor %}
</div>
<!-- Ваш JavaScript код для прокрутки -->
<script>
document.querySelectorAll('.inner-scroll').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault(); // Предотвращаем стандартное поведение
const targetId = this.getAttribute('href').slice(1);
const targetElement = document.getElementById(targetId);
const parentElement = document.getElementById('scrolling-area' + targetId.match(/\d+/)[0]); // Находим родительский элемент
if (parentElement) {
const topPos = targetElement.getBoundingClientRect().top + parentElement.scrollTop;
parentElement.scrollTo({
top: topPos,
behavior: "smooth" // Плавная прокрутка
});
}
});
});
</script>
{% endblock content %}
Объяснение изменений:
-
JavaScript Для Прокрутки: Добавлен код, который перехватывает клик на ссылках с классом
inner-scroll
. Он предотвращает стандартное поведение браузера и вместо этого прокручивает только внутренний прокручиваемый элемент (scrolling-area
), который содержит все заголовки. -
Стили: Добавлен инлайновый стиль к
div
, чтобы ограничить его высоту и включить прокрутку. - Динамическое Извлечение ID: Используется регулярное выражение для извлечения идентификатора фактора из
href
, чтобы корректно прокрутить к целевому элементу.
Это решение должно полностью решить вашу проблему с прокруткой на внутренней области, вместо прокрутки основной страницы.