Я пытаюсь создать галерею.html, которая изменяет поведение изображения по идентификатору изображения, например, id="lightbox-1", id="lightbox-2", id="lightbox-3", а поведение галереи изменяется в соответствии с css, это хорошо работает с использованием путей к файлам в качестве примера кода ниже:
<div id = "gallery">
<div><img src = "images/12.jpg"/><a href = "#lightbox-1">512</a></div>
<div><img src = "images/13.jpg"/><a href = "#lightbox-2">513</a></div>
...
и
<div class = "lightbox" id = "lightbox-1">
<div class = "content"><img src = "images/12b.jpg"/>
<div class = "title">No. <b>512</b> from Picsum</div><a class = "close" href = "#gallery"></a>
</div>
</div>
Однако я получаю изображения из базы данных sql-alchemy и использую этот метод для получения изображений из БД, Изображения успешно извлекаются, но расположение бессистемно, и я решил, что идентификационный номер не увеличивается, поэтому я пытаюсь программно увеличить идентификационный номер. Вот мой код:
<h5>Gallery</h5>
{% set n = 1 %}
{% for image in image_list %}
<div id = "gallery">
<div>
<img src = "data:;base64,{{ image }}"/>
<a href = "#lightbox-{{n}}">{{n}}</a>
</div>
</div>
<div class = "lightbox" id = "lightbox-{{n}}">
<div class = "content"><img src = "data:;base64,{{ image }}"/>
</div>
</div>
{% set n = n+1 %}
{% endfor %}
Проще говоря, я хочу имитировать это поведение и дизайн, используя flask для обслуживания html и sql-алхимии для изображений. На данный момент я могу обслуживать и получать изображения, но не могу воспроизвести поведение css. заранее спасибо
Я думаю, что вы выполняете итерацию не в том месте и получаете другую структуру, которая не соответствует таблице стилей.
Чтобы получить текущий индекс в текущей итерации, я рекомендую вам использовать loop.index. Поэтому создание и увеличение собственной переменной не требуется.
from flask import (
Flask,
current_app,
redirect,
render_template,
request,
url_for
)
from flask_sqlalchemy import SQLAlchemy
import base64
app = Flask(__name__)
app.config.from_mapping(
SQLALCHEMY_DATABASE_URI='sqlite:///example.db',
SQLALCHEMY_TRACK_MODIFICATIONS=False,
UPLOAD_EXTENSIONS=('jpg',)
)
db = SQLAlchemy(app)
class GalleryImage(db.Model):
id = db.Column(db.Integer, primary_key=True)
mime = db.Column(db.String, nullable=False)
data = db.Column(db.LargeBinary(), nullable=False)
@property
def b64encoded(self):
return base64.b64encode(self.data).decode('ascii')
with app.app_context():
db.create_all()
@app.route('/')
def index():
images = GalleryImage.query.all()
return render_template('index.html', **locals())
def allowed_file(filename):
allowed_extensions = current_app.config.get('UPLOAD_EXTENSIONS', [])
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in allowed_extensions
@app.route('/upload', methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
files = request.files.getlist('file[]')
for file in files:
if file.filename != '' and allowed_file(file.filename):
image = GalleryImage(
mime=file.mimetype,
data=file.read()
)
db.session.add(image)
try:
db.session.commit()
except:
db.session.rollback()
return redirect(url_for('.index'))
return render_template('upload.html')
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1">
<title>Upload</title>
</head>
<body>
<form method = "post" enctype = "multipart/form-data">
<input type = "file" name = "file[]" accept = "image/jpeg" multiple />
<button type = "submit">Upload</button>
</form>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1">
<title>Index</title>
<link rel = "stylesheet" type = "text/css" href = "{{ url_for('static', filename='css/main.css') }}">
</head>
<body>
<h5>Gallery</h5>
<div id = "gallery">
{% for img in images -%}
<div id = "gallery-thumb-{{loop.index}}">
<img src = "data:;base64,{{ img.b64encoded }}" />
<a href = "#lightbox-{{ loop.index }}">{{ loop.index }}</a>
</div>
{% endfor -%}
</div>
{% for img in images -%}
<div class = "lightbox" id = "lightbox-{{ loop.index }}">
<div class = "content">
<img src = "data:;base64,{{ img.b64encoded }}" />
<a class = "close" href = "#gallery-thumb-{{loop.index}}"></a>
</div>
</div>
{% endfor -%}
</body>
</html>
* {
box-sizing: border-box;
}
body {
margin: 5px;
position: relative;
}
#gallery {
display: grid;
/* height: calc(100vh - 10px);*/ /* !!! */
grid-template: repeat(6, 1fr) / repeat(6, 1fr);
grid-gap: 0.5em;
}
@media (max-width: 800px) {
#gallery {
display: flex;
align-items: flex-start;
flex-wrap: wrap;
justify-content: center;
}
#gallery > div {
width: 48%;
margin: 1%;
}
}
@media (max-width: 800px) and (max-width: 350px) {
#gallery > div {
width: 98%;
}
}
#gallery > div:nth-child(6n + 1) {
grid-column: span 2;
grid-row: span 2;
}
#gallery > div:nth-child(2) {
grid-column: span 3;
grid-row: span 3;
}
#gallery > div:nth-child(4) {
grid-column: span 1;
grid-row: span 2;
}
#gallery > div > a {
opacity: 0;
position: absolute;
color: #000;
background-color: #000;
font: bold 4em "Helvetica";
text-shadow: 0 -1px 5px #fff, -1px 0px 5px #fff, 0 1px 5px #fff, 1px 0px 5px #fff;
padding: 2rem;
mix-blend-mode: difference;
width: 100%;
height: 100%;
transition: all ease 1s;
}
#gallery > div > img {
width: 100%;
min-height: 100%;
transition: all ease 1s;
object-fit: cover; /* !!! */
}
#gallery > div:hover img {
filter: blur(4px);
}
#gallery > div:hover a {
opacity: 1;
}
#gallery > div {
overflow: hidden;
position: relative;
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.2), 0 3px 20px 0 rgba(0, 0, 0, 0.19);
}
#gallery div, #gallery a {
display: flex;
justify-content: center;
align-items: center;
text-decoration: none;
}
[id^ = "lightbox-"] {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
opacity: 0;
transition: opacity 450ms ease-in-out;
align-items: center;
justify-content: center;
pointer-events: none;
}
[id^ = "lightbox-"]:target {
opacity: 1;
pointer-events: inherit;
}
[id^ = "lightbox-"]:target img {
filter: blur(0);
}
[id^ = "lightbox-"] .content {
max-width: 90%;
position: relative;
color: #fff;
}
[id^ = "lightbox-"] .content:hover > a.close {
opacity: 1;
transform: scale(1, 1);
}
[id^ = "lightbox-"] .content:hover > .title {
opacity: 1;
transform: translateY(-3px);
}
[id^ = "lightbox-"] .content:hover > .title::after {
opacity: 1;
}
[id^ = "lightbox-"] .content > * {
transition: all 450ms ease-in-out;
}
[id^ = "lightbox-"] .title {
display: block;
margin: 0;
padding: 1em;
position: absolute;
bottom: 0;
width: 100%;
transform: translateY(50%);
font-size: 1.5em;
opacity: 0;
}
[id^ = "lightbox-"] .title::after {
content: ' ';
background-color: rgba(0, 0, 0, 0.4);
bottom: 0;
left: 0;
height: 100%;
width: 100%;
position: absolute;
transition: all 350ms ease-in-out 250ms;
opacity: 0;
transform-origin: bottom;
mix-blend-mode: soft-light;
}
[id^ = "lightbox-"] img {
max-height: 90vh;
max-width: 100%;
margin: 0;
padding: 0;
filter: blur(50px);
}
[id^ = "lightbox-"] a.close {
width: 2em;
height: 2em;
position: absolute;
right: 0;
top: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
transform: scale(0, 0);
opacity: 0;
transform-origin: right top;
text-decoration: none;
color: #fff;
}
[id^ = "lightbox-"] a.close::after {
content: "×";
}
Однако у меня есть другая проблема, пожалуйста, помогите, если у вас есть время, функция всплывающего окна работает только для первого изображения. Я пытался проверить обработку CSS, но безрезультатно <a href = "#lightbox-[index1]">image_text</a>
заставляет изображение всплывать, другие изображения не реагируют на это
К сожалению, я не могу сказать, почему это не работает должным образом для вас. Я проверил это, и это работает для меня. Пока атрибут href указывает на идентичный атрибут id другого элемента, якорь на странице работает. Остальное регулируется правилами таблицы стилей, которые начинаются с [id^ = "lightbox-"]
и должны одинаково применяться ко всем наложениям.
Я также пытаюсь прочитать [id^ = "lightbox-"]
его новый синтаксис, но я думаю, что все еще не могу его реализовать. Я собираюсь сделать еще одну попытку. Не могли бы вы также поделиться своим кодом на github, пожалуйста
Я добавил весь пример кода в ответ. Это должно сработать. Правило [id^ = "lightbox-"]
применяется ко всем элементам, атрибут id которых начинается с «lightbox-».
Гений! Функциональность безупречна. Спасибо, что поделились, вы действительно получили все тонкости технологии. Учитывая, что я буду много работать с веб-сайтами и Python, какие ресурсы вы могли бы мне предложить, чтобы получить некоторый уровень оценки связи js, css и python.
Для Flask я бы порекомендовал вам прочитать туториал Мигеля Гринберга . Для HTML, CSS и JS я бы порекомендовал взглянуть на документацию Mozilla Developer Network . В разделе CSS Tricks вы найдете отдельные статьи по макетам и конкретным проблемам. Не знаю, поможет ли это вам, но мне сложно дать рекомендацию по этим темам.
Спасибо, с вашим кодом мне удалось показать изображения из БД. Это был мой первый раз, когда я читал loop.index. Я пытался передать список и использовать вложенный цикл for, но он не выходил.