楽天やヤフーのセールイベント用のカウントダウン付きページのサンプル
コード
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>CAMPAIGN PAGE TEMPLATE 2023</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
:root {
--main-key-color: #07a752;
--sub-key-color: #028641;
--global-margin: 8px;
--global-padding: 8px;
--global-border-color: #ccc;
--header-height: 76px;
}
* {
margin: 0;
padding: 0;
}
html {}
body {
overflow-x: hidden;
}
html,body {
position: relative;
width: 100%;
height: 100%;
font-size: 16px;
font-family: Arial, Helvetica, sans-serif;
}
#header {
position: fixed;
z-index: 10;
top: 0;
left: 0;
display: flex;
justify-content: flex-start;
align-items: center;
box-sizing: border-box;
width: 100%;
height: var(--header-height);
padding: 8px 60px 1rem;
background-color: #f1f1f1;
}
#header.scrolled {
box-shadow: 0 2px 4px #0000006e;
}
#header .hd-title {}
#header .hd-title .hd-shop-nm {
font-size: .5rem;
}
#header .hd-title .hd-cam-nm {
font-size: 1.2rem;
}
.cam-desc.header {
padding: 0 1rem;
}
.square-btn01 {
box-sizing: border-box;
width: 44px;
height: 44px;
padding: .35rem;
background-color: #5c5c5c;
border: 4px solid #9b9b9b;
border-radius: 4px;
color: #fff;
cursor: pointer;
transition: all .1s linear;
}
.square-btn01.ico-new {
position: relative;
}
.square-btn01.ico-new::after {
content: "NEW";
position: absolute;
top: 0;
right: calc(50% + 4px);
display: flex;
box-sizing: border-box;
padding: 0.125rem 0.35rem;
background: #cd0000;
font-size: .5rem;
border-radius: .5rem;
}
.square-btn01:hover {
box-shadow: 2px 2px 4px #0000003c;
transform: translate3d(-2px, -2px, 10px);
}
.square-btn01:active {
box-shadow: none;
transform: translate3d(0, 0, 0);
}
#hd-rem-time {
position: fixed;
z-index: 998;
top: 8px;
left: 8px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
box-sizing: border-box;
width: 44px;
height: 44px;
transition: all .3s linear;
}
#remTimeMMwrap {
position: absolute;
box-sizing: border-box;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: center;
line-height: 1;
padding-bottom: .5rem;
}
#remTimeMM {
color: #fff;
font-size: .75rem;
font-weight: 600;
text-shadow: 0 0 2px #00000096;
}
#remTimeMMwrap .min {
font-size: .5rem;
}
#go2top {
position: fixed;
z-index: 998;
bottom: 8px;
right: 24px;
}
#hd-menu-bar-btn {
position: fixed;
z-index: 2000;
top: 8px;
right: 24px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
}
#hd-menu-bar-btn .bar {
display: block;
width: 100%;
height: 2px;
background-color: #ccc;
transition: all .3s linear;
}
#hd-menu-bar-btn.active .bar {}
#hd-menu-bar-btn.active .bar:nth-child(1) {
transform: rotate(45deg);
transform-origin: 25% 50%;
}
#hd-menu-bar-btn.active .bar:nth-child(2) {
display: none;
}
#hd-menu-bar-btn.active .bar:nth-child(3) {
transform: rotate(135deg);
transform-origin: 50% -50%;
}
#hd-menu-wrap {
overflow-y: auto;
position: fixed;
z-index: 1000;
top: 0;
left: 100%;
background: white;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
width: 70%;
height: 100dvh;
padding: 64px 16px 16px;
transition: all .3s linear;
}
#hd-menu-wrap.active {
left: 30%;
box-shadow: 4px 4px 14px #0000004f;
}
#hd-menu-list {
list-style: none;
}
#hd-menu-list li {
padding: .25rem 0;
}
#hd-menu-list li a {}
.ul-side-bnr {
list-style: none;
}
.ul-side-bnr li {
margin-top: 1rem;
}
.ul-side-bnr li a {
display: block;
width: 100%;
min-height: 3rem;
background-color: #d1d1d1;
}
.ul-side-bnr li a img {
width: 100%;
}
#mask {
position: fixed;
top: 0;
left: 100%;
z-index: 999;
width: 100%;
height: 100dvh;
background-color: #00000050;
transition: all .3s linear;
}
#mask.active {
left: 0;
}
#main-visual {
position: relative;
display: flex;
justify-content: center;
align-items: flex-end;
height: 360px;
padding-top: var(--header-height);
background-color: lightcyan;
}
.main-img {
/*overflow: hidden;*/
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url(al-soot-yRjLihK35Yw-unsplash.jpg);/**/
background-repeat: no-repeat;
background-size: cover;
background-position: center top;
/*background-attachment: fixed;*/
}
.main-info-box {
overflow: hidden;
--main-box-width: 200px;
position: absolute;
top: calc(50% + var(--header-height)/2);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: var(--main-box-width);
height: var(--main-box-width);
background: #faf473;
/* border: 4px solid #fee289; */
border-radius: calc(var(--main-box-width) / 2);
margin-top: calc(var(--main-box-width) / -2);
color: #f5f114;
line-height: 1;
transition: all .3s linear;
}
.main-info-box.misregistration {
background: #000;
box-shadow: 2px 2px 0px #00ffffe3, -2px -2px 0px #ff06ebcf;
}
.main-info-box.misregistration.glitter::after {
content: "";
position: absolute;
top: 0;
left: 0;
z-index: 1;
width: 100%;
height: 100%;
background-color: #ffffff3b;
transform-origin: left top;
transform: rotate(45deg) translate(-100%, -50%);
/*animation: glitter 2s infinite ease-in-out;*/
animation: glitter 2s 1 ease-in-out;
}
@keyframes glitter {
20%, 100% {
opacity: 0;
transform: rotate(45deg) translate(200%, -50%);
}
0% {
opacity: 0;
}
10% {
opacity: 1;
}
}
.main-info-box dt,
.main-info-box dd {
font-weight: 600;
width: 100%;
text-align: center;
}
.main-info-box .fzL {
font-size: 1.5rem;
}
.main-info-box .fzLL {
font-size: 2rem;
}
.main-info-box .fzLLL {
font-size: 3rem;
}
.main-info-box .fzLLLL {
font-size: 4rem;
}
.main-info-box .fzLLLLL {
font-size: 5rem;
}
.main-info-box.left {
left: 50%;
margin-left: calc(var(--main-box-width) * -2.25);
}
.main-info-box.right {
right: 50%;
margin-right: calc(var(--main-box-width) * -2.25);
}
.main-info-logo {
position: absolute;
z-index: 1;
top: 37%;
width: 100%;
height: 35%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
/* background: aquamarine; */
transition: all .3s linear;
}
body.pointup .main-info-logo {
top: 25%;
}
.main-info-logo dt {
position: relative;
font-size: 2.4rem;
font-weight: 600;
color: #fff;
text-shadow: 2px 2px 0px #00000045;
}
.main-info-logo dt .shop-nm {
position: absolute;
bottom: 100%;
width: 100%;
font-size: 1.6rem;
text-shadow: 0 0 BLACK;
text-align: center;
color: #000;
line-height: 1;
opacity: .35;
}
.main-info-logo dd {}
.main-info-logo dd span {
}
.main-info-logo dd span i {
font-style: normal;
}
.main-info-logo dd.cam-period {
position: absolute;
top: -50%;
}
.main-info-logo dd.cam-period .fmt-ss {
display: none;
}
.main-info-logo dd.cam-period,
.main-info-logo dd.cam-desc {
font-size: 1.1rem;
background: #ffffffd1;
padding: .1rem .5rem;
border-radius: 2px;
}
.sd-limit .fmt-YY,
.sd-limit .fmt-mm,
.sd-limit .fmt-ss {
display: none;
}
[class^="fmt-"] i {
font-style: normal;
}
.main-info-logo dd.cam-desc .fmt-hh,
.sd-limit-time {
color: red;
}
.main-info-logo dd.cam-desc .fmt-hh .num,
.sd-limit-time .num {
font-size: 120%;
font-style: normal;
}
.sd-txt {
font-weight: 600;
}
.cam-period.main-info {
/*
position: absolute;
top: 100%;
left: 0;
*/
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 1.3rem;
text-align: center;
background-color: #ffffff;
transition: all .3s linear;
}
.cam-period.main-info.fixed {
position: fixed;
z-index: 10;
top: var(--header-height);
background: #f1f1f1;
box-shadow: 0px 2px 4px #00000045;
}
.cam-period.main-info .period {
display: inline-block;
}
.cam-period.main-info .period.start {
}
.cam-period.main-info .period.end {
}
article {}
.article-title {
text-align: center;
padding-top: 4rem;
padding-bottom: 2rem;
}
.article-title::first-letter {
font-size: 2rem;
color: var(--main-key-color);
/*border-bottom: 1px solid;*/
}
article section {
counter-increment: number;
}
article section h1:after {
content: counter(number);
}
article section .bg-number {
overflow: hidden;
position: relative;
}
article section .bg-number .card-title,
article section .bg-number .card-contents {
position: relative;
z-index: 1;
display: flex;
justify-content: center;
align-items: center;
}
article section .bg-number .card-title {
height: 2rem;
}
article section .bg-number .card-contents {}
article section .bg-number:after {
content: counter(number);
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
font-size: 30rem;
color: #f1f1f1;
}
.inner-wrap {
width: 1024px;
margin: auto;
text-align: left;
}
.box-2col {
text-align: center;
}
.box-2col .inner-wrap {
display: flex;
flex-wrap: wrap;
}
.box-2col .inner-wrap section {
box-sizing: border-box;
width: 50%;
}
.nav-tag-list {}
.nav-tag-list-ul {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
list-style: none;
padding: 0;
}
.nav-tag-list-ul li {
position: relative;
box-sizing: border-box;
width: calc(12.5% - var(--global-margin)*2);
min-width: 8rem;
margin: var(--global-margin);
display: flex;
justify-content: center;
align-items: center;
padding: var(--global-padding);
border: 1px solid #ccc;
border-radius: 16px;
transition: all .3s linear;
cursor: pointer;
white-space: nowrap;
}
.nav-tag-list-ul li:hover {
background-color: #f1f1f1;
}
.nav-tag-list-ul li.active,
.nav-tag-list-ul li.active:hover {
color: #fff;
background-color: #09f;
}
.disp-list-style {
display: flex;
justify-content: center;
align-items: center;
list-style: none;
}
.disp-list-style li {
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
width: 4rem !important;
/* border: 1px solid #ccc; */
background: #02446f;
line-height: 1;
font-size: .9rem;
padding: .25rem;
color: #ffffff75;
}
.disp-list-style li.active {
color: #fff;
background-color: #40d3f0;
}
.disp-list-style li:nth-child(1) {
border-radius: 4px 0 0 4px;
}
.disp-list-style li:nth-child(2) {
border-radius: 0 4px 4px 0;
}
.card-basic01 {
box-sizing: border-box;
min-height: 16rem;
margin: var(--global-margin);
padding: var(--global-padding);
border: 1px solid var(--global-border-color);
border-radius: 16px;
}
.card-title {
padding-bottom: 8px;
}
.card-contents {
}
[class^="box-list-"] .inner-wrap ul {
display: flex;
flex-wrap: wrap;
list-style: none;
}
[class^="box-list-"] .inner-wrap ul li a {
display: flex;
box-sizing: border-box;
min-height: 16em;
margin: var(--global-margin);
padding: var(--global-padding);
border: 1px solid var(--global-border-color);
border-radius: 16px;
}
ul.coupons {
padding: 0 8px;
}
.coupon {
overflow: hidden;
position: relative;
z-index: 1;
display: flex;
justify-content: center;
align-items: center;
text-decoration: none;
min-height: 6rem !important;
margin: 0 !important;
color: #fff;
font-size: 2rem;
text-align: center;
line-height: 1;
transition: all .1s linear;
border: 2px dotted #ffffff75 !important;
border-radius: 2px !important;
}
a.coupon:hover {
/*opacity: .7;*/
box-shadow: 2px 2px 4px #0000003c;
transform: translate3d(-4px, -4px, 10px);
}
a.coupon:active {
/*transform: scaleY(1.2);*/
box-shadow: none;
transform: translate3d(0, 0, 0);
}
.coupon::before {
content: "COUPON";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff40;
font-size: 4rem;
font-weight: 600;
}
.box-list-3col .inner-wrap ul li {
width: 33.333333%;
}
.box-list-4col .inner-wrap ul li {
width: 25%;
}
.box-list-4col .inner-wrap ul.item li a {
min-height: 24rem;
}
[class^="box-list-"] .inner-wrap ul.list-style {}
[class^="box-list-"] .inner-wrap ul.list-style li {
width: 100%;
}
[class^="box-list-"] .inner-wrap ul.list-style li a {
min-height: 12rem;
}
.box-item01 {
display: flex;
flex-direction: column;
text-decoration: none;
}
.item-img-box {}
.item-img {
padding-top: 100%;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
.item-detail-box {}
.item-detail-nm {}
.item-detail-cd {}
.item-detail-pr {}
.price sales {}
.price normal {}
.item-detail-sh {}
.item-detail-op {}
[class^="ul-tile"] {
display: flex;
flex-wrap: wrap;
list-style: none;
padding: 8px;
}
[class^="ul-tile"] li {
width: 12.5%;
}
[class^="ul-tile"] li a {
display: flex;
padding: 8px;
border: 1px solid #f1f1f1;
}
.tile-img {
width: 100%;
padding-top: 100%;
background-repeat: no-repeat;
background-size: cover;
background-position: center;
}
[class^="ul-tile"].half {
margin: auto;
}
[class^="ul-tile"].half {
justify-content: space-between;
}
[class^="ul-tile"].half li {
width: calc(50% - 4px);
margin: 4px 0;
}
aside {
margin-top: 4rem;
}
aside section {
margin-top: 2rem;
}
aside section:first-child {
margin-top: 0;
}
#footer {
position: relative;
margin-top: 4rem;
padding-top: 2rem;
padding-bottom: 2rem;
text-align: center;
background-color: #f1f1f1;
}
#ft-copy {
margin-top: 1rem;
font-size: .75rem;
}
/* timer */
.timer {
display: inline-block;
font-size: 2rem;
font-family: arial;
background: #f1f1f1;
box-sizing: border-box;
padding: .15rem;
border-radius: 2px;
line-height: 1;
}
.timer span {}
.timer i {
font-style: normal;
}
.timer span i {
position: relative;
display: inline-block;
font-style: normal;
border: 1px solid var(--global-border-color);
line-height: 1;
margin: 0 0.035rem;
padding: 0.05rem 0.15rem;
border-radius: 2px;
background: linear-gradient(0deg, rgba(255,255,255,1) 15%, rgba(236,236,236,1) 50%, rgba(255,255,255,1) 60%);
box-shadow: inset 0px 0px 2px #90909075;
}
.timer span i::after {
position: absolute;
top: 50%;
left: 0;
content: "";
box-sizing: border-box;
width: 100%;
height: 1px;
border-bottom: 1px solid #9999997c;
border-left: 1px solid #000;
border-right: 1px solid #000;
}
.timer [class^="date"] {
}
.timer [class^="date"] .days {
font-size: .5rem;
}
.timer .date0 {
/*display: none;*/
}
#currentTime {
font-size: 1rem;
}
#countDownTimer {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
/*margin-bottom: -1rem;*/
transition: all .3s linear;
}
#countDownTimer > div {
display: none;
width: 100%;
text-align: center;
}
#countDownTimer .txt {
margin-top: .5rem;
margin-bottom: .5rem;
}
#countDownTimer .txt span {
display: inline-flex;
padding: .25rem .5rem;
background-color: #feffa7;
border: 3px solid #ffe289;
border-radius: 44px;
line-height: 1;
box-sizing: border-box;
min-width: 18rem;
/* text-align: center; */
justify-content: center;
align-items: center;
}
#countDownTimer > [class^="sub"] {
/*display: none;*/
}
#countDownTimer > [class^="sub"] {
}
#countDownTimer .timer {
box-shadow: 2px 2px 9px #00000080;
}
#countDownTimer .main .timer {
font-size: 3rem;
}
#countDownTimer.pointup {
flex-direction: column-reverse;
/*margin-bottom: -1.25rem;*/
}
#countDownTimer.pointup > [class^="sub"] {
display: block;
}
#countDownTimer > [class^="sub"] .timer {
color: #f3f3f3;
background-color: #1f1f1f !important;
}
#countDownTimer > [class^="sub"] .timer span {
background-color: #1f1f1f !important;
}
#countDownTimer > [class^="sub"] .timer span i {
color: #fff;
background: #1f1f1f;
border-color: #000;
}
#countDownTimer.pointup > [class^="sub"] .timer {
display: block;
font-size: 3rem;
}
#countDownTimer.pointup > [class^="sub"] .timer span i {
color: red;
}
#countDownTimer > [class^="sub"] .txt span {
}
#countDownTimer.pointup > [class^="sub"] .txt span {
color: #fff;
background-color: #ff6969;
border: 3px solid #f84d4d;
}
#countDownTimer.pointup .main .timer {
font-size: 2rem;
}
.pie {
/*display: none;*/
position: relative;
width: 30px;
height: 30px;
/*background-image: conic-gradient(#ccc 0% 0%, #f00 0% 100%);*/
background-image: conic-gradient(#ccc 0% 0%, #ccc 0% 100%);
border-radius: 50%;
transition: all .1s linear;
}
.pie::before {
content: "P5倍!";
position: absolute;
bottom: 100%;
left: 0;
font-size: .5rem;
width: 100%;
text-align: center;
line-height: 1;
font-weight: 600;
}
.pie::after {
content: "残時間";
position: absolute;
top: 100%;
left: 0;
font-size: .5rem;
width: 100%;
text-align: center;
line-height: 1;
}
#cam-schedule {
overflow: hidden;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 1rem;
font-size: .7rem;
background-color: #a0a0a0;
}
.during-event #cam-schedule {
background-color: #00a852;
}
#cam-schedule > * {
transition: all .3s linear;
}
#time-bar {
position: absolute;
top: 0;
right: 0;
box-sizing: border-box;
height: 100%;
/*padding: 0 .5rem;*/
background-color: #028641;
/*border-radius: 1rem 0 0 1rem;*/
}
#current-time-bar {
overflow: hidden;
position: absolute;
right: 100%;
box-sizing: border-box;
display: flex;
justify-content: flex-end;
align-items: center;
padding-right: .25rem;
}
#current-time-bar span {}
#current-time-bar span i {
font-style: normal;
}
#remain-day-date-bar {
overflow: hidden;
position: absolute;
z-index: 1;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
}
#current-time-bar span {
color: #dcdcdc !important;
}
#remain-day-date-bar span {}
#current-time-bar span,
#remain-day-date-bar span {
white-space: nowrap;
color: #fff;
font-weight: 600;
text-shadow: 0 0 2px #000;
}
#remain-day-date {
transition: all .3s linear;
}
#remain-day-date span {
}
#remain-day-date span i {
font-style: normal;
}
.during-event #time-bar,
.progress {
--bg-color-st01: #008641;
--bg-color-st02: #00a852;
background: linear-gradient(-45deg, var(--bg-color-st01) 25%, var(--bg-color-st02) 25%, var(--bg-color-st02) 50%, var(--bg-color-st01) 50%, var(--bg-color-st01) 75%, var(--bg-color-st02) 75%, var(--bg-color-st02));
background-size: 12px 12px;
animation: progress-bar 2.4s infinite linear;
border-top: 2px solid #07a752;
border-bottom: 2px solid #07a752;
}
@keyframes progress-bar {
0% { background-position-x: 0;}
100% { background-position-x: 12px;}
}
.txt-vertical {}
.txt-vertical i {}
.debug {
/**/display: none;
color: red;
}
/*
** media query DESKTOP > SP
*/
@media screen and (max-width: 1024px) {
/* 1024pxまでの幅の場合に適応される */
.inner-wrap {
width: 100%;
}
.main-info-box.left {
margin-left: unset;
left: 16px;
}
.main-info-box.right {
margin-right: unset;
right: 16px;
}
}
@media screen and (max-width: 768px) {
/* 768pxまでの幅の場合に適応される */
.nav-tag-list-ul {
flex-wrap: nowrap;
justify-content: flex-start;
overflow-x: scroll;
}
.box-list-4col .inner-wrap ul li {
width: 50%;
}
.box-list-4col .inner-wrap ul.item li a {
min-height: 12rem;
}
[class^="ul-tile"] li {
width: 25%;
}
.square-btn01 {
right: 8px !important;
}
#footer {
margin-top: 2rem;
}
}
@media screen and (max-width: 480px) {
/* 480pxまでの幅の場合に適応される */
#header {
justify-content: center;
text-align: center;
}
.cam-desc.header {
display: none;
}
#main-visual {
height: 396px;
}
.main-info-logo {
top: var(--header-height) !important;
justify-content: flex-start;
}
.main-info-logo dt {
display: none;
}
.main-info-logo dd.cam-period {
position: fixed;
top: unset;
font-size: 0.75rem;
}
.main-info-logo dd.cam-desc {
font-size: 1rem;
}
.main-info-logo dd.cam-period,
.main-info-logo dd.cam-desc {
border-radius: 0;
box-sizing: border-box;
width: 100%;
text-align: center;
padding: 0;
}
.main-info-box {
--main-box-width: calc(50vw - 20px);
top: calc(45% + var(--header-height)/2);
}
.pointup .main-info-box {
--main-box-width: calc(50vw - 20px);
top: calc(26% + var(--header-height)/1);
}
.main-info-box.left {
left: 16px;
}
.main-info-box.right {
right: 16px;
}
.cam-period.main-info {
font-size: .8rem;
}
.article-title {
padding-top: 2rem;
padding-bottom: 1rem;
}
.coupon {
font-size: 1rem;
}
[class^="ul-tile"].half li {
width: 100%;
}
.box-list-4col .inner-wrap ul.item {
flex-wrap: nowrap;
overflow-x: scroll;
}
.box-list-4col .inner-wrap ul.item li {
width: 70vw;
}
.box-list-4col .inner-wrap ul.item li a {
width: calc(70vw - var(--global-margin)*2);
}
}
@media screen and (max-width: 320px) {
/* 320pxまでの幅の場合に適応される */
}
</style>
</head>
<html lang="ja">
<body>
<header id="header">
<div class="hd-title">
<h1 class="hd-shop-nm">SHOP x MALL</h1>
<h2 class="hd-cam-nm cam-title"></h2>
</div>
<div class="cam-desc header"></div>
<div id="cam-schedule">
<div id="remain-day-date-bar"><span id="remain-day-date"></span></div>
<div id="time-bar"></div>
</div>
</header>
<div id="main-visual">
<div class="main-img">
<dl id="mainInfo" class="main-info-logo">
<dt><span class="shop-nm">SHOP x MALL</span><span class="cam-title"></span></dt>
<dd class="cam-desc main-info"></dd>
</dl>
<dl class="main-info-box misregistration left">
<dt class="fzLL">ポイント</dt>
<dd><span class="txt-vertical"><i>M</i><i>A</i><i>X</i></span><span class="fzLLLL">39</span><span>倍!</span></dd>
</dl>
<dl class="main-info-box misregistration right">
<dt>クーポン利用で</dt>
<dd>最大<span class="fzLL">10,000</span>円<span class="fzLLL">OFF!</span></dd>
</dl>
</div>
<div id="countDownTimer">
<div class="main">
<div class="txt"><span></span></div>
<div class="timer"></div>
</div>
<div class="sub">
<div class="txt"><span></span></div>
<div class="timer"></div>
</div>
</div>
</div>
<div id="camPeriodInfo" class="cam-period main-info"></div>
<div id="output" class="debug">debug</div>
<main id="main">
<article id="box-point" class="box-2col">
<h1 class="article-title">POINT</h1>
<div class="inner-wrap">
<section><div class="card-basic01 bg-number"><h1 class="card-title">POINT </h1><div class="card-contents">contents</div></div></section>
<section><div class="card-basic01 bg-number"><h1 class="card-title">POINT </h1><div class="card-contents">contents</div></div></section>
<section><div class="card-basic01 bg-number"><h1 class="card-title">POINT </h1><div class="card-contents">contents</div></div></section>
<section><div class="card-basic01 bg-number"><h1 class="card-title">POINT </h1><div class="card-contents">contents</div></div></section>
</div>
</article>
<article id="box-coupon" class="box-list-3col">
<h1 class="article-title">COUPON</h1>
<div class="inner-wrap">
<ul class="coupons">
<li><a href="#" class="coupon" style="background-color: #f29ca5;" target="_blank">300円OFF<br>クーポン</a></li>
<li><a href="#" class="coupon" style="background-color: #ef7b4e;" target="_blank">600円OFF<br>クーポン</a></li>
<li><a href="#" class="coupon" style="background-color: #f7bc63;" target="_blank">1000円OFF<br>クーポン</a></li>
<li><a href="#" class="coupon" style="background-color: #fdeb60;" target="_blank">1400円OFF<br>クーポン</a></li>
<li><a href="#" class="coupon" style="background-color: #9acd71;" target="_blank">2000円OFF<br>クーポン</a></li>
<li><a href="#" class="coupon" style="background-color: #6fbbd1;" target="_blank">4000円OFF<br>クーポン</a></li>
<li><a href="#" class="coupon" style="background-color: #5b83c0;" target="_blank">6000円OFF<br>クーポン</a></li>
<li><a href="#" class="coupon" style="background-color: #b885b6;" target="_blank">8000円OFF<br>クーポン</a></li>
<li><a href="#" class="coupon" style="background-color: #000000;" target="_blank">10000円OFF<br>クーポン</a></li>
</ul>
</div>
</article>
<article id="box-items" class="box-list-4col">
<h1 class="article-title">ITEMS</h1>
<nav class="nav-tag-list">
<ul id="navTagList" class="nav-tag-list-ul">
</ul>
</nav>
<div id="dispItem" class="inner-wrap"></div>
</article>
</main>
<aside id="aside">
<section>
<ul class="ul-tile">
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
<li><a href="#"><div class="tile-img" style="background-image: url(nirzar-pangarkar-CswKfD546Z8-unsplash.jpg);"></div></a></li>
</ul>
</section>
</aside>
<footer id="footer">
<div>footer here!</div>
<div id="ft-copy">© CAMPAIGN PAGE TEMPLATE 2023</div>
</footer>
<button id="go2top" class="square-btn01" type="button">TOP</button>
<button id="hd-menu-bar-btn" class="square-btn01 ico-new" type="button"><span class="bar"></span><span class="bar"></span><span class="bar"></span></button>
<div id="hd-rem-time">
<div id="remTime" class="pie"></div>
<div id="remTimeMMwrap"><span id="remTimeMM">0</span><span class="min">分</span></div>
</div>
<div id="hd-menu-wrap">
<ul id="hd-menu-list">
<li><a href="#box-point">POINT</a></li>
<li><a href="#box-coupon">COUPON</a></li>
<li><a href="#box-items">ITEMS</a></li>
</ul>
<ul id="side-bnr" class="ul-side-bnr">
<li><a href="#">BANNER</a></li>
<li><a href="#">BANNER</a></li>
<li><a href="#">BANNER</a></li>
<li><a href="#">BANNER</a></li>
<li><a href="#">BANNER</a></li>
</ul>
</div>
<div id="mask"></div>
<script>
const CAMP_END_TXT = 'キャンペーンは終了いたしました。';
const mainConf = {
'name':'スーパーセール',
'desc':'セールの簡単な説明文',
'type':'main',
'img':'',
'start' : new Date('2023/04/01 00:00:00'),
'end' : new Date('2023/04/20 23:59:00')
};
const sub1Conf = {
'name':'ポイント5倍!',
'desc':'ポイント5倍!',
'type':'sub',
'img':'',
'start' : new Date('2023/04/10 20:00:00'),
'end' : new Date('2023/04/10 23:59:00')
};
const sub2Conf = {
'name':'ポイント5倍!',
'desc':'ポイント5倍!',
'type':'sub',
'img':'',
'start' : new Date('2023/04/12 05:00:00'),
'end' : new Date('2023/04/12 09:00:00')
};
const n = 1;//サブタイマーをn日前に表示開始
$(function(){
let _strat = new dateFormat(mainConf.start);
let _end = new dateFormat(mainConf.end);
let camPeriod = '<span class="period start">' + _strat.formatDate + 'から' + '</span><span class="period end">' + _end.formatDate + 'まで</span>';
$('.cam-title').html(mainConf.name);
$('.cam-period').html(camPeriod);
$('.cam-desc').html(mainConf.desc);
});
//カウントダウンタイマー
let cnt = 0;
setInterval(function(){
let now = new Date();
let pre = new Date(now.getTime()+86400000*n);
let present = new dateFormat(now);
//$('#current-time').html('今日は、' + present.formatSimpleDate + 'です。');
//メインタイマー
if(mainConf.start && mainConf.end && now < mainConf.end){
let mainTimer = new countDown(mainConf);
mainTimer.countTime;
}
if(cnt == 0) $('body').removeClass('[class$="-event"]');
if(now <= mainConf.start){
//イベント前
if(cnt == 0) $('body').addClass('before-event');
}else if((now > mainConf.start)&&(now < mainConf.end)){
//イベント中
let mainTimerS = new countDown(mainConf);
mainTimerS.setTimeBar;
let remainDayDate = Math.ceil(mainTimerS.remainMM / 60 / 24);
$('#remain-day-date').html('キャンペーン終了まで、あと' + remainDayDate + '日間!');
let endTime = new dateFormat(mainConf.end);
if(now.getDate() == mainConf.end.getDate()) $('#remain-day-date').html('本日' + present.formatSimpleDate + 'は、イベント最終日です。' + endTime.formatJPT + 'まで');
if(cnt == 0) $('body').addClass('during-event');
}else if(now >= mainConf.end){
//イベント終了
if(cnt == 0){
$('body').addClass('after-event');
$('.cam-desc.header').html(CAMP_END_TXT);
$('.cam-desc.main-info').html(CAMP_END_TXT);
$('#hd-menu-bar-btn').removeClass('ico-new');
$('.cam-period.main-info').hide();
$('.main-info-box').hide();
}
return;
}
//サブタイマー
if(cnt == 0) $('body').removeClass('pointup');
if(sub1Conf.start && sub1Conf.end){
if((pre > sub1Conf.start)&&(now < sub1Conf.end)){
//サブタイマー 1
let subTimer01 = new countDown(sub1Conf);
subTimer01.countTime;
if(now > sub1Conf.start) subTimer01.setRemainPie;
$('.cam-desc').html(careateSubDesc(sub1Conf));
if(cnt == 0) $('body').addClass('pointup');
}else if(now >= sub1Conf.end){
//
if(sub2Conf.start && sub2Conf.end){
if((pre > sub2Conf.start)&&(now < sub2Conf.end)){
//サブタイマー 2
let subTimer02 = new countDown(sub2Conf);
subTimer02.countTime;
if(now > sub2Conf.start) subTimer02.setRemainPie;
$('.cam-desc').html(careateSubDesc(sub2Conf));
if(cnt == 0) $('body').addClass('pointup');
}
}else if(now >= sub2Conf.end){
//
}
}
}
cnt++;
}, 1000);
class countDown {
constructor(obj){
this.now = new Date();
this.name= obj.name;
this.type= obj.type;
this.start = obj.start;
this.end = obj.end;
}
get countTime(){
return this.calcTime();
}
calcTime(){
let time = null;
let now = this.now;
let start = this.start;
let end = this.end;
let name = this.name;
let type = this.type;
let diff;
let event;
let tgt = '.' + type;
let el = $('#countDownTimer');
el.children(tgt).show();
if(now <= start){
event = name + '開始まで、';
diff = start.getTime() - now.getTime();
}else if((now > start)&&(now < end)){
event = name + '開催中!終了まで、';
diff = end.getTime() - now.getTime();
if(/sub/.test(type)) el.addClass('pointup');
if(diff <= 1000){
event = name + 'は終了しました。';
if(/sub/.test(type)){
el.removeClass('pointup');
el.children(tgt).hide();
}
}
}else if(now >= end){
//TODO 不要
event = name + 'は終了しました。';
el.children(tgt).children('.timer').hide();
diff = null;
}
el.children(tgt).children('.txt').children('span').html(event);
if(diff != null){
let d = Math.floor(diff / 1000 / 60 / 60 / 24);
let h = Math.floor(diff / 1000 / 60 / 60) % 24;
let m = Math.floor(diff / 1000 / 60) % 60;
let s = Math.floor(diff / 1000) % 60;
time = '<span class="date' + d + '">' + zeroPadding(d) + '<span class="days">days</span>' + '</span>' + zeroPadding(h) + '<i class="colon">:</i>' + zeroPadding(m) + '<i class="colon">:</i>' + zeroPadding(s);
el.children(tgt).children('.timer').html(time);
}
}
get remainTimePer(){
return this.calcRemainPer();
}
calcRemainPer(){
let now = this.now;
let start = this.start.getTime();
let end = this.end.getTime();
let elapsed = now.getTime() - start;
let diff = end - start;
let percent = elapsed / diff * 100;
return percent;
}
get remainMM(){
return this.calcRemainMM();
}
calcRemainMM(){
let now = this.now.getTime();
let end = this.end.getTime();
let diff = end - now;
let result = Math.ceil(diff / 1000 / 60);
result = (result > 0)? result: 0;
return result;
}
get setRemainPie(){
return this.createRemainMM();
}
createRemainMM(){
let per = this.calcRemainPer();
$('#remTime').css({'background-image':`conic-gradient(#ccc 0% ${per}%, #f00 ${per}% 100%)`});
let mm = this.calcRemainMM();
$('#remTimeMM').html(mm);
}
get remainDD(){
return this.calcRemainDD();
}
calcRemainDD(){
let now = this.now.getTime();
let end = this.end.getTime();
let diff = end - now;
let result = Math.floor(diff / 1000 / 60 / 60 / 24);
result = (result > 0)? result: 0;
return result;
}
calcRemainDaysPer(){
let now = this.now;
let start = this.start.getTime();
let end = this.end.getTime();
let elapsed = now.getTime() - start;
let diff = end - start;
elapsed = Math.ceil(elapsed / 1000 / 60 / 60 / 24);
//console.log(elapsed)
diff = Math.ceil(diff / 1000 / 60 / 60 / 24) + 1;
//console.log(diff)
let percent = (diff - elapsed) / diff * 100;
return percent;
}
get setTimeBar(){
return this.createTimeBar();
}
createTimeBar(){
let per = this.calcRemainDaysPer();
$('#time-bar').css({'width': per + '%'});
}
}
class dateFormat {
constructor(now){
this.now = now;
this.year = this.now.getFullYear();
this.month = this.now.getMonth() + 1;
this.date = this.now.getDate();
this.day = this.now.getDay();
this.week = this.now.getDay();
this.hour = this.now.getHours();
this.minute = this.now.getMinutes();
this.second = this.now.getSeconds();
this.week = ['日', '月', '火', '水', '木', '金', '土'];
}
get formatDate(){
return this.formatTime();
}
formatTime(){
let result;
let weeks = this.week;
let day = weeks[this.day];
//result = `<span class="fmt-YY"><i class="num">${this.year}</i>年</span><span class="fmt-MM"><i class="num">${this.month}</i>月</span><span class="fmt-DD"><i class="num">${this.date}</i>日</span><span class="fmt-d">(${day})</span><span class="fmt-hh"><i class="num">${zeroPadding(this.hour)}</i>時</span><span class="fmt-mm"><i class="num">${zeroPadding(this.minute)}</i>分</span><span class="fmt-ss"><i class="num">${zeroPadding(this.second)}</i>秒</span>`;
result = `<span class="fmt-YY"><i class="num">${this.year}</i>年</span><span class="fmt-MM"><i class="num">${this.month}</i>月</span><span class="fmt-DD"><i class="num">${this.date}</i>日</span><span class="fmt-d">(${day})</span><span class="fmt-hh"><i class="num">${zeroPadding(this.hour)}</i>:</span><span class="fmt-mm"><i class="num">${zeroPadding(this.minute)}</i></span>`;
return result;
}
get formatSimpleDate(){
return this.formatSimpleTime();
}
formatSimpleTime(){
let result;
let weeks = this.week;
let day = weeks[this.day];
result = `${this.month}/${this.date}(${day})`;
return result;
}
get formatJPT(){
return this.formatTimeJP();
}
formatTimeJP(){
return `${zeroPadding(this.hour)}時${zeroPadding(this.minute)}分`;
}
}
function zeroPadding(num){
let n;
n = num.toString().padStart(2, '0');
let arr = [...n];
let nt = '<span>';
for(let i in arr) nt += '<i>' + arr[i] + '</i>';
nt += '</span>';
return nt;
}
function limitHour(s, e){
if(s > e) return;
let start = s;
let end = e;
let diff = end.getTime() - start.getTime();
diff = diff / (60*60*1000);
return diff;
}
function careateSubDesc(obj){
let time = new dateFormat(obj.start);
let limit = limitHour(obj.start, obj.end);
let html = '<span class="sd-limit">' + time.formatDate.replace(':','時') + '</span>から、';
html += '<span class="sd-limit-time">' + '<i class="num">' + Math.ceil(limit) + '</i>' + '時間限定!' + '</span> ';
html += '<span class="sd-txt">' + obj.desc + '</span>';
return html;
}
$('#hd-menu-bar-btn').on('click', function(){
let tgt = $('#hd-menu-wrap');
if(tgt.hasClass('active')){
$(this).removeClass('active');
tgt.removeClass('active');
$('#mask').removeClass('active');
$('html').css({'overflow':'visible'});
}else{
$(this).addClass('active');
tgt.addClass('active');
$('html').css({'overflow':'hidden'});
$('#mask').addClass('active');
$('#mask.active').on('click',function(){
$(this).removeClass('active');
tgt.removeClass('active');
$('#hd-menu-bar-btn').removeClass('active');
$('html').css({'overflow':'visible'});
});
}
});
$('#go2top').on('click', function(){
$('html, body').animate({scrollTop: 0}, 300);
});
let tgtElm = $('#camPeriodInfo');
let tgtPos = tgtElm.offset().top - $('#header').outerHeight();
$(window).scroll(function(){
let sc = $(this).scrollTop();
if(sc >= tgtPos){
tgtElm.addClass('fixed');
}else if(sc < tgtPos){
tgtElm.removeClass('fixed');
}
});
//ITEM
class getItem {
constructor(obj){
this.name = (obj.name)? obj.name: 'アイテム名';
this.code = (obj.code)? obj.code: '商品コード';
this.page = (obj.page)? obj.page: '#';
this.image = (obj.image)? obj.image: 'domenico-loia-hGV2TfOh0ns-unsplash.jpg';//ダミー
this.nPrice = (obj.nPrice)? obj.nPrice: '通常価格';
this.sPrice = (obj.sPrice)? obj.sPrice: 'セール価格';
this.shipping = (obj.shipping)? obj.shipping: '送料';
this.coShipping = (obj.coShipping)? obj.coShipping: '法人送料';
this.coupon = (obj.coupon)? obj.coupon: 'クーポン利用額';
this.category = (obj.category)? obj.category: 'カテゴリー';
this.type = (obj.type)? obj.type: '種別';
this.rank = (obj.rank)? obj.rank: 'ランキング';
this.newFlag = (obj.newFlag)? obj.newFlag: 'NEW';
}
rendering(){
let html = `
<a class="box-item01" href="${this.page}">
<div class="item-img-box"><div class="item-img" style="background-image: url(${this.image});"></div></div>
<div class="item-detail-box">
<dl>
<dt class="item-detail-nm">${this.name}</dt>
<dd class="item-detail-cd">${this.code}</dd>
<dd class="item-detail-pr">
<div><span class="price sales">${this.sPrice}</span></div>
<div><span class="price normal">${this.nPrice}</span></div>
</dd>
<dd class="item-detail-sh">
${this.shipping}<br>
${this.coShippin}
</dd>
<dd class="item-detail-op">
debug/TODO:<br>
${this.coupon}<br>
${this.category}<br>
${this.type}<br>
${this.rank}<br>
${this.newFlag}<br>
</dd>
</dl>
</div>
</a>
`;
return html;
}
getCategory(){
return this.category;
}
}
//ダミーjsonデータ
let items = [
{"name":"しょうひんめいてすと01","category":"CAT-A"},
{"name":"しょうひんめいてすと02","category":"CAT-B"},
{"name":"しょうひんめいてすと03","category":"CAT-C"},
{"name":"しょうひんめいてすと04","category":"CAT-A"},
{"name":"しょうひんめいてすと05","category":"CAT-B"},
{"name":"しょうひんめいてすと06","category":"CAT-C"},
{"name":"しょうひんめいてすと07","category":"CAT-A"},
{"name":"しょうひんめいてすと08","category":"CAT-B"}
]
//カテゴリでデータ抽出
class extByCate {
constructor(data, keyword){
this.data = data;
this.keyword = keyword;
}
get result(){
return this.extract();
}
extract(){
let d = this.data;
let kw = this.keyword;
let result = d.filter(function(v, i){
return v.category.indexOf(kw) !== -1;
});
return result;
}
}
let categories = ['ALL'];
//アイテムリストレンダリング
let html = '';
for(let i in items){
let item = new getItem(items[i]);
html += `<li>${item.rendering()}</li>`;
categories.push(item.getCategory());//カテゴリリスト作成
}
const cNames = [...new Set(categories)];
document.getElementById('dispItem')
.appendChild(document.createElement('ul'))
.setAttribute('id', 'itemList');
let classArr = ['item','disp-list','card-style'];
document.getElementById('itemList').classList.add(...classArr);
document.getElementById('itemList').innerHTML = html;
//アイテムナビ
let navChild = '';
for(let i=0; i<cNames.length; i++){
let initClass = (cNames[i] == 'ALL')? 'active': '';
navChild += `<li class="${initClass}" data-cat="${cNames[i]}">${cNames[i]}</li>`;
}
document.getElementById('navTagList').innerHTML = navChild;
let elements = document.getElementById('navTagList').children;
let e;
if (window.ontouchstart === null) {
e = 'touchstart';
} else{
e = 'click';
}
for(let i=0; i<elements.length; i++){
elements[i].addEventListener(e, function(){
let el = this.innerHTML;
let cat = this.dataset.cat;
//let cl = this.className;
for(let j=0; j<elements.length; j++){
elements[j].classList.remove('active');
}
this.classList.add('active');
let nData = new extByCate(items, cat);
nData = (cat == 'ALL')? items: nData.result;
//console.log(nData)
let html = '';
for(let i in nData){
let item = new getItem(nData[i]);
html += `<li>${item.rendering()}</li>`;
}
document.getElementById('itemList').innerHTML = html;
}, false);
}
</script>
</body>
</html>