게시글 앱을 만들기 전에 게시글을 listing 해줄 때 핀터레스트를 따온 카드형 레이아웃을 구현할 방법으로 자바스크립트 라이브러리인 MagicGrid 를 살펴본다
python manage.py startapp articleapp
...
INSTALLED_APPS = [
...
'articleapp', # 추기
]
# pragmatic/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('accountapp.urls')),
path('profiles/', include('profileapp.urls')),
path('articles/', include('articleapp.urls')), # 추가
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
path에서 list/로 접근.
장고에서 제공하는 기본 view인 TemplateView
장점 : 템플릿만 지정해주면 나머진 자동으로 만들어준다.
# articleapp/urls.py
from django.urls import path
from django.views.generic import TemplateView
urlpatterns = [
path('list/', TemplateView.as_view(template_name = 'articleapp/list.html'), name='list')
]
list.html 파일 생성 -> 내부에 html, css 작성 ->
내부에 자바 스크립트 작성 -> static/js/magicgrid.js 디렉토리 및 파일 생성 -> [Magic-Grid -> dist -> magic-grid.cjs.js 자바스크립트 코드]를 복사 -> magicgrid.js에 붙여넣은후 맨 하단 module.exports = MagicGrid; 코드 줄을 삭제 -> 맨 하단에 다음 코드 추가
let magicGrid = new MagicGrid({
container: '.container',
animate: true,
gutter: 30,
static: true,
useMin: true
});
magicGrid.listen();
이후 list.html의 script 태그 내부 채우기
static을 사용하기 위해 {% load static %} 추가하고
static 폴더 안에 있는 'js/magicgrid.js'를 가져오는 코드
{% extends 'base.html' %}
{% load static %}
{% block content %}
<!--css-->
<style>
.container div {
width: 250px;
height: 500px;
background-color: antiquewhite;
display: flex;
justify-content: center;
align-items: center;
border-radius: 1rem;
}
</style>
<!--html-->
<div class="container">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
<div class="item4">4</div>
<div class="item5">5</div>
<div class="item6">6</div>
<div class="item7">7</div>
<div class="item8">8</div>
<div class="item9">9</div>
<div class="item10">10</div>
<div class="item11">11</div>
<div class="item12">12</div>
<div class="item13">13</div>
</div>
<!--js-->
<script src="{% static 'js/magicgrid.js'%}"></script>
{% endblock %}

Lorem Picsum 사용하여 화면에 아이템 표시
특정 너비와 높이를 정해서 https://picsum.photos/200/300이 url 로 요청을 보내면 랜덤한 이미지를 전달받을 수 있는 사이트 → 레이아웃 테스트 용도

※ css 수정
<style>
...
/* width 제거 */
. container img {
width: 100% /* 부모의 크기를 다 채우도록 */
border-radius: 1rem; /* 둥글둥글하게 만들기 */
}
</style>
<div class="container">
<div class="item1">
<img src="https://picsum.photos/200/300" alt="">
</div>
...
%to% 사진이 로딩이 되는 시간이 존재하기 때문에 자동적으로 레이아웃이 되지 않는다.
즉, 다음 자바스크립트 코드가 끝나고 그 뒤에 이미지 로딩이 완료되어서 실제로 Grid 를 배치시키는 것이 반영이 안됐기 때문.
html 안에 있는 모든 img 태그들을 전부 가져와서 벽돌 형태를 의미하는 masonrys라는 변수에 할당.
for 문을 사용해 masonrys 하나하나 마다 addEventListener를 사용하여 load가 되었을 때 function을 수행하도록 함.
그 function은 magicGrid의 positionItems()을 실행시키는 것.
즉, 모든 html 태그 내에 있는 이미지에 대해서 로드가 되었을 때 이 magicGrid를 다시 위치 시키라고 하는 EventListener를 추가하는 코드.
//static/js/magicgrid.js
...
let magicGrid = new MagicGrid({
container: '.container',
animate: true,
gutter: 30,
static: true,
useMin: true
});
//추가
var masonrys = document.getElementsByTagName("img")
for (let i=0; i<masonrys.length; i++){
masonrys[i].addEventListener('load', function () {
magicGrid.positionItems();
}, false);
}
magicGrid.listen();
