javascript Issue319:20171101 - バナーとモーダルとAMP
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript Issue319:20171101 - バナーとモーダルとAMP相关的知识,希望对你有一定的参考价值。
import forEach from 'lodash/forEach'
import { hasClass } from '../utils/DOM'
import { setLocalStLimit } from './yearEndBanner'
const pageDOM = document.getElementById('page')
const modalImgAbsolutePath = '/r/bnr/point/year-end-cpn201710_sp.png'
const buildElement = (elmDataObj) => {
const elm = document.createElement(elmDataObj.tagName)
forEach(elmDataObj, (value, key) => {
if (key === 'tagName') return
if (key === 'text') {
elm.appendChild(document.createTextNode(elmDataObj[key]))
} else {
elm[key] = elmDataObj[key]
}
})
return elm
}
// 忘年会CPモーダルを作り出し、最親DOMを返す関数.
// 引数で現在ページを判定し、予約ページで発火する場合、リンク要素無しのモーダルが生成される。
const modalBuild = (isReserve) => {
const divYearEndModal = buildElement({ tagName: 'div', id: 'js-year-end_modal', className: 'year-end_modal js-modal-close' })
const divContentWrap = buildElement({ tagName: 'div', className: 'year-end_modal__content-wrap' })
const divModalContent = buildElement({ tagName: 'div', className: 'year-end_modal__content' })
const divImgWrap = buildElement({ tagName: 'div', className: 'img-wrap' })
const imgItem = buildElement({ tagName: 'img', className: 'img-item', src: modalImgAbsolutePath, alt: '2017年度忘年会予約キャンペーン' })
const divLinkArea = buildElement({ tagName: 'div', className: 'link-area' })
const aLink = buildElement({ tagName: 'a', className: 'link', text: '利用規約・詳細はこちら', href: '/sp/campaign/enkai_10/s/?sc_lid=enkaicp_tnp_12' })
const divCloseBtnArea = buildElement({ tagName: 'div', className: 'close-btn-area' })
const spnaCloseBtn = buildElement({ tagName: 'span', className: 'close-btn js-modal-close', text: '閉じる' })
const divNodeArr = [divYearEndModal, divContentWrap, divModalContent, divImgWrap, imgItem]
const linkNodeArr = [divImgWrap, divLinkArea, aLink]
const closeAreaArr = [divModalContent, divCloseBtnArea, spnaCloseBtn]
// ""Element配列の配列"""を渡すと渡された順番通りにDOMを整形する関数.
const shapingDOM = elmArr => elmArr.forEach(nodeArr => nodeArr.reduce((parent, child) => parent.appendChild(child)))
// 予約ページ内でこの関数が発火していたら、(離脱率防止のために)リンクのないモーダルを作り出す.
if (isReserve) {
shapingDOM([divNodeArr, closeAreaArr])
} else {
shapingDOM([divNodeArr, linkNodeArr, closeAreaArr])
}
// 整形されたDOMの最も親となるElementを返す.
return divYearEndModal
}
export function yearEndModal() {
const bannerDOM = document.getElementById('js-year-end-banner')
const modalTrigger = document.getElementsByClassName('js-year-end-modal-trigger')
const isReservePage = document.getElementsByClassName('js-reserve-page-flag')[0] !== undefined
// 表示したhtmlにモーダルのトリガーがなければこの関数は役目終了.
if (!modalTrigger) return
forEach(modalTrigger, (mTrigger) => {
mTrigger.addEventListener('click', (ev) => {
// aタグにラップされてたとき用のpreventDefault()
ev.preventDefault()
// バナーからこのモーダルが発火しているか判定.
if (hasClass(mTrigger, 'year-end-sticky__item')) {
bannerDOM.parentNode.removeChild(bannerDOM)
setLocalStLimit('bannerHide')
}
// 予約ページなら他ページへのリンクのないモーダルをビルドしてappend.
pageDOM.appendChild(modalBuild(isReservePage))
// appendしたDOM情報を取得.
const modalDOM = document.getElementById('js-year-end_modal')
const closeModalTrigger = document.getElementsByClassName('js-modal-close')
// モーダル出現後に黒枠を押下したか、閉じるボタンを押下したか判定する.
forEach(closeModalTrigger, (closeTrigger) => {
closeTrigger.addEventListener('click', (e) => {
if (hasClass(e.target, 'js-modal-close')) {
modalDOM.parentNode.removeChild(modalDOM)
// 貫通して背景までクリックさせるのを防止する.
e.stopPropagation()
}
})
})
})
})
}
// AMPページからの遷移時
// yearEndModal()から必要な部分のみコピペでモーダルの流用
function yearEndModalAMP() {
pageDOM.appendChild(modalBuild())
const modalDOM = document.getElementById('js-year-end_modal')
const closeModalTrigger = document.getElementsByClassName('js-modal-close')
forEach(closeModalTrigger, (closeTrigger) => {
closeTrigger.addEventListener('click', (e) => {
if (hasClass(e.target, 'js-modal-close')) {
modalDOM.parentNode.removeChild(modalDOM)
e.stopPropagation()
}
})
})
}
// ページ内のelmのY座標
const getTargetPositionY = (elm) => {
const rect = elm.getBoundingClientRect()
return rect.top + pageYOffset
}
// ハッシュでAMPからの遷移を判別してモーダルを開く
export const judgeAMPModal = () => {
const ampHash = location.hash
if (ampHash.match('#amp-campaign')) {
const campaignBanner = document.querySelector('.js-year-end-modal-trigger.-block')
const campaignBannerSection = campaignBanner.parentNode.parentNode
const positionX = 0
const positionY = getTargetPositionY(campaignBannerSection)
window.scrollTo(positionX, positionY)
location.hash = '_'
yearEndModalAMP()
}
}
import { yearEndBanner } from './yearEndBanner'
import { yearEndModal, judgeAMPModal } from './yearEndModal'
export default function yearendPartyCp() {
yearEndBanner()
yearEndModal()
judgeAMPModal()
}
以上是关于javascript Issue319:20171101 - バナーとモーダルとAMP的主要内容,如果未能解决你的问题,请参考以下文章
javascript Issue84 - 20190620电话导线改善
javascript Issue302:20171018 - 动画商品トライアル
javascript Issue15:20180705 - no79.CVエリア改善