[comento]가상회사 인턴십 #1 :메인페이지를 뒤~집어 지게 JavaScript

우애옹·2024년 9월 27일
post-thumbnail

Python

먼저 근간이 되는 뼈대를 잡아 줘야 한다 "Hello world!"로 테스트를 해 보았지만 진짜는 이제부터!


admin.py


from django.contrib import admin
from django.utils.html import format_html
from .models import BannerImage, ReviewImage, SpecialOffer,CompanyInfo,CompanyVideo, ReviewImage2


@admin.register(BannerImage)
class BannerImageAdmin(admin.ModelAdmin):
    list_display = ('alt_text',)

@admin.register(ReviewImage)
class ReviewImageAdmin(admin.ModelAdmin):
    list_display = ('alt_text',)


@admin.register(ReviewImage2)
class ReviewImageAdmin(admin.ModelAdmin):
    list_display = ('alt_text',)

@admin.register(SpecialOffer)
class SpecialOfferAdmin(admin.ModelAdmin):
    list_display = ('description',)

@admin.register(CompanyInfo)
class CompanyInfoAdmin(admin.ModelAdmin):
    list_display = (('title', 'description') )

@admin.register(CompanyVideo)
class CompanyVideoAdmin(admin.ModelAdmin):
    list_display = ('company_info', 'description', 'video_link')

    def video_link(self, obj):
        if obj.video:
            return format_html('<a href="{0}" target="_blank">View Video</a>', obj.video.url)
        return 'No Video'
    video_link.short_description = 'Video'

view.py

from django.shortcuts import render
from .models import BannerImage, ReviewImage, ReviewImage2, SpecialOffer
from .models import CompanyInfo

def mainpage(request):
    banners = BannerImage.objects.all()
    reviews = ReviewImage.objects.all()
    reviews2 = ReviewImage2.objects.all()
    special_offers = SpecialOffer.objects.all()

    context = {
        'banners': banners,
        'reviews': reviews,
        'reviews2': reviews2,
        'special_offers': special_offers,
    }
    return render(request, 'home/mainpage.html', context)

def company(request):
    company_info = CompanyInfo.objects.first()
    return render(request, 'home/company_info.html', {'company_info': company_info})

apps.py

from django.apps import AppConfig


class HomeConfig(AppConfig):
    default_auto_field = "django.db.models.BigAutoField"
    name = "home"

urls.py

# home/urls.py
from django.urls import path
from . import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('', views.mainpage, name='mainpage'),
    path('company/', views.company, name='company'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

상단배너

프론트 부분은 부트스트랩을 이용해서 불필요한 HTML 노가다를 줄여 줬다 프레임이 짜여 있어서 편했지만 처음 써 보는 나에게는 적응하기 까지 시간이 조금 걸리기는 했다.

https://getbootstrap.kr/docs/5.1/examples/
참고로 나는 여기서 받았다!

view

<header class="banner-fst">
    <div class="container px-lg-5">
        <div id="banner-slider">
            {% for banner in banners %}
                <div class="banner-slide">
                    <img src="{{ banner.image.url }}" alt="{{ banner.alt_text }}">
                </div>
            {% endfor %}
        </div>
    </div>
</header>

JS

2.5초에 한 번 자동으로 넘어가는 배너를 생성

document.addEventListener('DOMContentLoaded', function() {

    const bannerSlider = document.getElementById('banner-slider');
    let index = 0;

    function showBannerSlide() {
        const slides = bannerSlider.getElementsByClassName('banner-slide');
        for (let i = 0; i < slides.length; i++) {
            slides[i].style.display = i === index ? 'block' : 'none';
        }
        index = (index + 1) % slides.length;
        setTimeout(showBannerSlide, 2500);
    }

    showBannerSlide();

회전초밥(?) 이미지

view

<div class="wrap">
    <div class="rolling-list" id="roller1">
        <!-- 첫 번째 슬라이드 원본 -->
        {% for review in reviews %}
            <div class="review-slide">
                <img src="{{ review.image.url }}" alt="{{ review.alt_text }}">
            </div>
        {% endfor %}
        <!-- 첫 번째 슬라이드 클론 -->
        {% for review in reviews %}
            <div class="review-slide">
                <img src="{{ review.image.url }}" alt="{{ review.alt_text }}">
            </div>
        {% endfor %}
    </div>
</div>

<div class="wrap-2">
    <div class="rolling-list-2" id="roller2">
        <!-- 두 번째 슬라이드 원본 -->
        {% for review in reviews2 %}
            <div class="review-slide review-slide2">
                <img src="{{ review.image.url }}" alt="{{ review.alt_text }}">
            </div>
        {% endfor %}
        <!-- 두 번째 슬라이드 클론 -->
        {% for review in reviews2 %}
            <div class="review-slide review-slide2">
                <img src="{{ review.image.url }}" alt="{{ review.alt_text }}">
            </div>
        {% endfor %}
    </div>
</div>

JS

클론을 이용해서 이미지가 회전초밥처럼 무한히 움직이게 구현

document.addEventListener('DOMContentLoaded', function() {
    function setupRollingSlider(rollerId) {
        const roller = document.getElementById(rollerId);
        const clone = roller.cloneNode(true);

        clone.id = rollerId + '-clone';
        document.querySelector('.wrap').appendChild(clone);

        // 초기 위치 설정
        roller.style.position = 'absolute';
        clone.style.position = 'absolute';

        roller.style.left = '0px';
        clone.style.left = roller.scrollWidth + 'px';

        function animateSlider() {
            let pos1 = parseFloat(roller.style.left);
            let pos2 = parseFloat(clone.style.left);
            const rollerWidth = roller.scrollWidth;

            pos1 -= 1;
            pos2 -= 1;


            if (pos1 <= -rollerWidth) {
                 pos1 = pos2 + rollerWidth;
            }
            if (pos2 <= -rollerWidth) {
                 pos2 = pos1 + rollerWidth;
            }

            roller.style.left = pos1 + 'px';
            clone.style.left = pos2 + 'px';

            requestAnimationFrame(animateSlider);
        }

        animateSlider();
    }

    setupRollingSlider('roller1');
});
document.addEventListener('DOMContentLoaded', function() {
    function setupRollingSlider(rollerId) {
        const roller = document.getElementById(rollerId);
        const clone = roller.cloneNode(true);

        clone.id = rollerId + '-clone';
        document.querySelector('.wrap-2').appendChild(clone);

        roller.style.position = 'absolute';
        clone.style.position = 'absolute';

        roller.style.left = '0px';
        clone.style.left = '-' + roller.scrollWidth + 'px';

        function animateSlider() {
            let pos3 = parseFloat(roller.style.left);
            let pos4 = parseFloat(clone.style.left);
            const rollerWidth = roller.scrollWidth;

            pos3 += 1;
            pos4 += 1;

            if (pos3 >= rollerWidth) {
                 pos3 = pos4 - rollerWidth;
            }

            if (pos4 >= rollerWidth) {
                pos4 = pos3 - rollerWidth;
            }


             roller.style.left = pos3 + 'px';
             clone.style.left = pos4 + 'px';

            requestAnimationFrame(animateSlider);
        }

        animateSlider();
    }

    setupRollingSlider('roller2');
});

// 이 부분이 꽤나 난관 이었는데 클론도 잘 만들어 지지 않았고
이동이 자꾸 같은곳으로 가는등 문제가 많아 그냥 나누어 줬더니 잘 작동이 되었다

특가상품(카운트다운)

view

<div class="special-offers-container">
    <div class="text-section">
        <p class="p">✨오늘의 야세지 공구</p><br>
        <h5>오늘이 지나면 혜택이 사라져요</h5>
        <div id="countdown"></div>
    </div>

    <div class="offers-wrapper">
        <div id="special-offers">
            {% for offer in special_offers %}
                <div class="special-offer">
                    <img
                        src="{{ offer.image.url }}"
                        alt="{{ offer.description }}"
                        onclick="window.location.href='/mysite/recomm/{{ offer.id }}/';"
                        style="cursor: pointer;"/>
                </div>
            {% endfor %}
        </div>
    </div>
</div>

{% endblock content %}

JS

24시간 기준 아침11시 이벤트 종료 카운트다운 함수

function updateCountdown() {
        const now = new Date();
        const deadline = new Date();
        deadline.setHours(11, 0, 0, 0);
        if (now > deadline) {
            deadline.setDate(deadline.getDate() + 1);
        }

        const timeDiff = deadline - now;
        const hours = Math.floor((timeDiff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        const minutes = Math.floor((timeDiff % (1000 * 60 * 60)) / (1000 * 60));
        const seconds = Math.floor((timeDiff % (1000 * 60)) / 1000);

        document.getElementById('countdown').innerHTML =
            `종료까지 ${hours}시간 ${minutes}분 ${seconds}초`;
    }

    updateCountdown();
    setInterval(updateCountdown, 1000);
});

// 이 부분은 수정이 필요하다 만약 상품이 시간 내 품절 된 경우 품절 안내 문자 그리고 시간수정을 조금 해서 대기시간 안내를 해 줄 예정이다 이번프로젝트에서는 자바스크립트 맛보기로 카운트다운을 만들어 보았다


참고로 CSS는 알아서 예쁘게 하면 될거라 생각해서 코드에 안넣었다 템플릿보면 예쁜거 많으니 참고 하세요.....

profile
어른이 되면 하늘에 건담이 날아 다닐줄 알았어

0개의 댓글