View all
  • ※First Order 5% Off※

    ※First Order 5% Off※

    Shop now
  • ※ Free Shipping on orders £49

    ※ Free Shipping on orders £49

    Shop now

※First Order 5% Off※

Shop now

※ Free Shipping on orders £49

※First Order 5% Off※

Shop now

※ Free Shipping on orders £49

Colinenshop

  • Home
  • New Arrivals
  • Best Sellers
  • Dresses
    • Wedding Guest Dresses
    • Floral Dresses
    • Mini Dresses
    • Midi Dresses
    • Maxi Dresses
  • Swimwears
  • Sweatshirt
  • Accessories
  • More links
const marketSlot = document.querySelector(".plugin_c_market"); if(marketSlot) { marketSlot.remove(); } const SITE = (window.C_SETTINGS || window[atob('U0hPUExBWlpB')])?.routes?.root || ''; const MARKET_THEME_SETTINGS = `${SITE}/api/markets/theme_setting`; const MARKET_COUNTRIES = `${SITE}/api/markets/countries`; const IP_MATCHING_MARKET = `${SITE}/api/front/station`; const MARKET_LANGUAGES = `${SITE}/api/markets/:id/active_languages`; const URL_REDIRECT = '_market_redirected'; const COOKIE_TIPS_NAME = 'market_no_tips'; const COOKIE_TIPS_EXPIRES = 1000 * 60 * 60 * 24 * 14; const MARKET_COUNTRY_COOKIE = '_shoplazza_market_country'; const MARKET_MODAL_LOADED = '__market_modal_loaded__'; const PROPERTY_SELECTED = 'selected'; const MARKET_PC_HEADER_TRIGGER = 'market-pc-header-trigger'; const MARKET_PC_HEADER_COUNTRY_SELECT_TITLE = 'market-pc-header-country-select-title'; const MARKET_PC_HEADER_LANGUAGE_SELECT_TITLE = 'market-pc-header-language-select-title'; const MARKET_PC_HEADER_LANGUAGE_SELECT_SUB_TITLE = 'market-pc-header-language-select-sub-title'; const MARKET_PC_HEADER_COUNTRY_SELECT_SUB_TITLE = 'market-pc-header-country-select-sub-title'; const MARKET_FLAG = 'market-flag'; const MARKET_SELECT_VALUE = 'market-select-value'; const MARKET_CURRENCY = 'market-currency'; const MARKET_CURRENCY_SYMBOL = 'market-currency-symbol'; const MARKET_SELECT_ITEM = 'market-select-item'; const MARKET_SELECT_ITEM_ID = 'market-select-item-id'; const MARKET_SELECT_LIST = 'market-select-list'; const MARKET_LANGUAGE_SELECT = 'market-language-select'; const MARKET_COUNTRY_SELECT = 'market-country-select'; const MARKET_MODAL = 'market-modal'; const MARKET_GATEWAY_REDIRECT_MODAL = 'market-gateway-redirect-modal'; const MARKET_RESELECT_MODAL = 'market-reselect-modal'; const MARKET_MODAL_FLAG = 'market-modal-flag'; const MARKET_MODAL_COUNTRY_CODE = 'market-modal-country-code'; const MARKET_MODAL_CURRENCY_SYMBOL = 'market-modal-currency-symbol'; const MARKET_MODAL_CLOSE = 'market-modal-close'; const MARKET_MODAL_CONFIRM = 'market-modal-confirm'; const MARKET_MODAL_RESELECT = 'market-modal-reselect'; const MARKET_MODAL_RESELECT_COUNTRY_SELECT = 'market-modal-reselect-country-select'; const DATA_SECTION_TYPE = 'data-section-type'; const SECTION_TYPE_HEADER = 'header'; const SECTION_TYPE_FOOTER = 'footer'; class SpzCustomMarket extends SPZ.BaseElement { constructor(element) { super(element); this.global = null; this.useCountrySelect_ = false; this.useLanguageSelect_ = false; this.useModal_ = false; this.isSingleSelectMode_ = false; this.blockSectionPosition_ = ''; this.isEditMode = false; this.ipMatchingMarket = null; this.marketCountryList = []; this.marketLanguages = []; this.toast = null; } static deferredMount() { return false; } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } buildCallback() { console.debug('Geolocation'); this.xhr_ = SPZServices.xhrFor(this.win); const platform = SPZServices.platformFor(this.win); this.isIOS_ = platform.isIos(); this.action_ = SPZServices.actionServiceForDoc(this.element); this.global = this.win.C_SETTINGS || this.win[atob('U0hPUExBWlpB')]; this.isEditMode = new URLSearchParams(this.win.location.search).get('preview_theme_id') && new URLSearchParams(this.win.location.search).get('oseid'); this.init_(); } showToast_(content) { if (!this.toast) { this.toast = self.document.createElement('ljs-toast'); this.toast.setAttribute('layout', 'nodisplay'); this.toast.setAttribute('hidden', ''); this.toast.setAttribute('duration', '2000'); this.element.appendChild(this.toast); } SPZ.whenApiDefined(this.toast).then((apis) => { apis.showToast(content); }); } triggerEvent_(name, data) { const event = SPZUtils.Event.create(this.win, `${TAG}.${name}`, data); this.action_.trigger(this.element, name, event); } findBlockSectionPosition() { let current = this.element; while (current) { const dataSectionType = current.getAttribute(DATA_SECTION_TYPE); if ( dataSectionType === SECTION_TYPE_HEADER || dataSectionType === SECTION_TYPE_FOOTER ) { return dataSectionType; } current = current.parentElement; } return ''; } async initSettings_() { await this.getMarketThemeSettings_(); if (this.useCountrySelect_) { this.element.setAttribute('use-country-select', true); } if (this.useLanguageSelect_) { this.element.setAttribute('use-language-select', true); } if (this.useModal_) { this.element.setAttribute('use-modal', true); } if ( (this.useCountrySelect_ && !this.useLanguageSelect_) || (!this.useCountrySelect_ && this.useLanguageSelect_) ) { this.isSingleSelectMode_ = true; } this.blockSectionPosition_ = this.findBlockSectionPosition(); this.isPCLayout_ = this.win.matchMedia('(min-width: 960px)').matches; } renderMarketSelectTemplateNode_(clonedTemplate, data) { this.renderTemplateImg_(clonedTemplate, MARKET_FLAG, { src: data?.flag, width: '24', height: '24', }); this.renderTemplateElement_( clonedTemplate, MARKET_SELECT_VALUE, data.value ); this.renderTemplateElement_( clonedTemplate, MARKET_CURRENCY, data?.currency ); this.renderTemplateElement_( clonedTemplate, MARKET_CURRENCY_SYMBOL, data?.currencySymbol ); } bindDropdownOpenClickEvent_(triggerElement, dropdown) { if (!triggerElement) return; const triggerOpen = () => { SPZ.whenApiDefined(dropdown).then((apis) => { if (!dropdown.hasAttribute('open')) { apis.open(triggerElement); } }); }; if (this.isIOS_) { triggerElement.addEventListener('touchstart', triggerOpen); } else { triggerElement.addEventListener('click', triggerOpen); } } createDropdown_() { const dropdown = self.document.createElement('ljs-dropdown'); dropdown.setAttribute('layout', 'nodisplay'); if (this.blockSectionPosition_ === 'header') { dropdown.setAttribute('overlay-style', 'top: 4px;'); dropdown.setAttribute('placement', 'bottomRight'); } else if (this.blockSectionPosition_ === 'footer') { dropdown.setAttribute('overlay-style', 'top: -4px;'); dropdown.setAttribute('placement', 'top'); } return dropdown; } createDropdownIcon_() { const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svgElement.setAttribute("class", "market-rotate-180"); svgElement.setAttribute("width", "16"); svgElement.setAttribute("height", "16"); const path1 = document.createElementNS("http://www.w3.org/2000/svg", "path"); path1.setAttribute("d", "M7.47 5.172a.75.75 0 0 1 1.06 0l4.596 4.596a.75.75 0 1 1-1.06 1.06L7.468 6.232a.75.75 0 0 1 0-1.06Z"); path1.setAttribute("fill", "currentColor"); const path2 = document.createElementNS("http://www.w3.org/2000/svg", "path"); path2.setAttribute("d", "M8.533 5.172a.75.75 0 0 1 0 1.06l-4.596 4.596a.75.75 0 1 1-1.061-1.06l4.596-4.596a.75.75 0 0 1 1.06 0Z"); path2.setAttribute("fill", "currentColor"); svgElement.appendChild(path1); svgElement.appendChild(path2); return svgElement; } renderDropdownListWithClickEvent_({ triggerElement, dataList, subTitleRole, listElementWithTemplate, defaultValue, itemHandler, shouldUpdateSelectedItem = false, }) { const dropdown = this.createDropdown_(); const itemTemplate = SPZCore.Dom.scopedQuerySelector( listElementWithTemplate, 'template' ); const clonedItemTemplate = itemTemplate.cloneNode(true); const fragment = self.document.createDocumentFragment(); dataList.forEach((data) => { const tempParentNode = self.document.createElement('div'); const clonedTemplate = self.document.importNode( clonedItemTemplate.content, true ); tempParentNode.appendChild(clonedTemplate); tempParentNode.firstElementChild.classList.add( 'market-select-item' ); this.renderMarketSelectTemplateNode_(tempParentNode, data); const selectItemElement = SPZCore.Dom.scopedQuerySelector( tempParentNode, `[role="${MARKET_SELECT_ITEM}"]` ); if (!selectItemElement) { return; } if (defaultValue === data.value) { if (shouldUpdateSelectedItem) { const clonedSelectItemElement = selectItemElement.cloneNode(true); triggerElement.replaceChild( clonedSelectItemElement, triggerElement.firstElementChild ); } selectItemElement.setAttribute(PROPERTY_SELECTED, ''); } selectItemElement.setAttribute(MARKET_SELECT_ITEM_ID, data.value); fragment.appendChild(tempParentNode.firstElementChild); }); let value = defaultValue; listElementWithTemplate.addEventListener( 'click', (e) => { if (this.isEditMode) { this.showToast_('编辑器下不支持切换国家'); SPZ.whenApiDefined(dropdown).then((apis) => { apis.close(); }); return; } let targetElement = e.target; while (targetElement) { if ( !targetElement || targetElement.getAttribute(MARKET_SELECT_ITEM_ID) ) { break; } targetElement = targetElement.parentNode; } if ( !targetElement || !targetElement.hasAttribute(MARKET_SELECT_ITEM_ID) ) { return; } const selectValue = targetElement.getAttribute(MARKET_SELECT_ITEM_ID); if (value === selectValue) { SPZ.whenApiDefined(dropdown).then((apis) => { apis.close(); }); return; } const selectedData = dataList.find((c) => c.value === selectValue); if (shouldUpdateSelectedItem) { const tempParentNode = self.document.createElement('div'); const clonedTemplate = self.document.importNode( clonedItemTemplate.content, true ); tempParentNode.appendChild(clonedTemplate); this.renderMarketSelectTemplateNode_(tempParentNode, selectedData); tempParentNode.firstElementChild.classList.add( 'market-select-item' ); triggerElement.replaceChild( tempParentNode.firstElementChild, triggerElement.firstElementChild ); } value = selectValue; itemHandler?.(selectedData); SPZ.whenApiDefined(dropdown).then((apis) => { apis.close(); }); }, false ); listElementWithTemplate.removeChild(itemTemplate); listElementWithTemplate.appendChild(fragment); listElementWithTemplate.classList.add('market-select-list'); dropdown.appendChild(listElementWithTemplate); if (subTitleRole) { this.renderSelectTitle_(dropdown, subTitleRole); } return dropdown; } createSelect_({ parent, defaultValue, dataList, listElementWithTemplate, itemHandler, titleRole, }) { const triggerElement = self.document.createElement('div'); triggerElement.classList.add('market-select'); const displayElement = self.document.createElement('div'); triggerElement.appendChild(displayElement); triggerElement.appendChild(this.createDropdownIcon_()); const dropdown = this.renderDropdownListWithClickEvent_({ triggerElement, dataList, listElementWithTemplate, defaultValue, itemHandler, shouldUpdateSelectedItem: true, }); this.bindDropdownOpenClickEvent_(triggerElement, dropdown); const dropdownContainer = self.document.createElement('div'); dropdownContainer.appendChild(triggerElement); dropdownContainer.appendChild(dropdown); dropdownContainer.classList.add('market-select-container'); this.renderSelectTitle_(dropdownContainer, titleRole); parent.appendChild(dropdownContainer); } getListElementWithTemplate_(role) { const template = SPZCore.Dom.scopedQuerySelector( this.element, `[role="${role}"]` ); if (template) { const clonedTemplate = template.cloneNode(true); const tempParent = self.document.createElement("div"); tempParent.appendChild(clonedTemplate.content); const listElementWithTemplate = SPZCore.Dom.scopedQuerySelector( tempParent, `[role="${MARKET_SELECT_LIST}"]` ); return listElementWithTemplate; } return null; } renderSelectTitle_(parent, role) { if (!parent || !role) { return; } const template = SPZCore.Dom.scopedQuerySelector( this.element, `[role="${role}"]` ); const content = self.document.importNode(template.content, true); parent.insertBefore(content, parent.firstElementChild); parent.firstElementChild.classList.add( role.includes('sub') ? 'market-pc-header-select-sub-title' : 'market-pc-header-select-title' ); } initSelect_(rootNode, options) { const parent = rootNode || this.element; if (this.useCountrySelect_) { this.createSelect_({ parent, titleRole: options?.shouldRenderSelectTitle ? MARKET_PC_HEADER_COUNTRY_SELECT_TITLE : undefined, defaultValue: this.getDefaultCountryValue_(), dataList: this.marketCountryList.map(this.mapCountryRenderData_), listElementWithTemplate: this.getListElementWithTemplate_( MARKET_COUNTRY_SELECT ), itemHandler: this.handleCountrySelectChange_.bind(this), }); } if (this.useLanguageSelect_) { this.createSelect_({ parent, titleRole: options?.shouldRenderSelectTitle ? MARKET_PC_HEADER_LANGUAGE_SELECT_TITLE : undefined, defaultValue: this.getDefaultLanguageValue_(), dataList: this.marketLanguages.map(this.mapLanguageRenderData_), listElementWithTemplate: this.getListElementWithTemplate_( MARKET_LANGUAGE_SELECT ), itemHandler: this.handleLanguageSelectChange_.bind(this), }); } } initPcHeaderTriggerElement() { const headerTriggerElementTemplate = SPZCore.Dom.scopedQuerySelector( this.element, `[role="${MARKET_PC_HEADER_TRIGGER}"]` ); const headerTriggerElement = self.document.importNode( headerTriggerElementTemplate.content, true ); const parentDivElement = self.document.createElement('div'); parentDivElement.setAttribute('role', MARKET_PC_HEADER_TRIGGER); parentDivElement.appendChild(headerTriggerElement); this.element.removeChild(headerTriggerElementTemplate); return parentDivElement; } initPanelWithSelect_() { const triggerElement = this.initPcHeaderTriggerElement(); const dropdown = this.createDropdown_(); const panelElement = self.document.createElement('div'); panelElement.classList.add('market-panel'); this.initSelect_(panelElement, {shouldRenderSelectTitle: true}); dropdown.appendChild(panelElement); this.bindDropdownOpenClickEvent_(triggerElement, dropdown); this.element.appendChild(triggerElement); this.element.insertBefore(dropdown, triggerElement); } initSingleSelectDropdown_() { const triggerElement = this.initPcHeaderTriggerElement(); let dropdown; if (this.useCountrySelect_) { dropdown = this.renderDropdownListWithClickEvent_({ triggerElement, subTitleRole: MARKET_PC_HEADER_COUNTRY_SELECT_SUB_TITLE, dataList: this.marketCountryList.map(this.mapCountryRenderData_), listElementWithTemplate: this.getListElementWithTemplate_( MARKET_COUNTRY_SELECT ), defaultValue: this.getDefaultCountryValue_(), itemHandler: this.handleCountrySelectChange_.bind(this), }); } else if (this.useLanguageSelect_) { dropdown = this.renderDropdownListWithClickEvent_({ triggerElement, subTitleRole: MARKET_PC_HEADER_LANGUAGE_SELECT_SUB_TITLE, dataList: this.marketLanguages.map(this.mapLanguageRenderData_), listElementWithTemplate: this.getListElementWithTemplate_( MARKET_LANGUAGE_SELECT ), defaultValue: this.getDefaultLanguageValue_(), itemHandler: this.handleLanguageSelectChange_.bind(this), }); } if (dropdown) { this.bindDropdownOpenClickEvent_(triggerElement, dropdown); this.element.appendChild(triggerElement); this.element.appendChild(dropdown); } } initEntry_() { if (this.blockSectionPosition_ === SECTION_TYPE_HEADER) { if (this.isSingleSelectMode_) { this.initSingleSelectDropdown_(); } else if (this.useCountrySelect_ && this.useLanguageSelect_) { this.initPanelWithSelect_(); } } this.initSelect_(this.element); } async initData_() { const promises = []; if (this.useCountrySelect_ || this.useModal_) { promises.push(this.getCountryList_(), this.getIpMatchingMarket_()); } if (this.useLanguageSelect_) { promises.push(this.getMarketLanguages_(this.global.market.market_id)); } return Promise.all(promises).then((results) => { const ipMatchingMarket = results.find((result) => result.hasOwnProperty('matching_station') ); const marketCountryList = results.find((result) => result.hasOwnProperty('data') ); if (ipMatchingMarket && marketCountryList) { this.ipMatchingMarket = ipMatchingMarket?.matching_station?.find?.( (item) => item.type === 'multiple_market' ) || { img: marketCountryList.length ? marketCountryList?.[0]?.detail && marketCountryList[0].detail?.flag : '', }; } }); } initModal_() { if ( this.isEditMode || !this.ipMatchingMarket?.market_id || !this.useModal_ || this.hasCookie_(COOKIE_TIPS_NAME) || this.win[MARKET_MODAL_LOADED] ) { return; } this.win[MARKET_MODAL_LOADED] = true; const redirectParam = new URLSearchParams(this.win.location.search).get( URL_REDIRECT ); if (redirectParam) { this.initModalEntry_(MARKET_GATEWAY_REDIRECT_MODAL); } else if ( this.ipMatchingMarket.market_id !== this.global?.market?.market_id ) { this.initModalEntry_(MARKET_MODAL); } } async init_() { await this.initSettings_(); await this.initData_(); this.initEntry_(); this.initModal_(); } getDefaultCountryValue_() { return this.getCookie_(MARKET_COUNTRY_COOKIE) || this.marketCountryList[0]?.country_code; } mapCountryRenderData_(country) { return { flag: country?.detail?.flag || '', value: country?.country_code, currency: country?.currency, currencySymbol: country?.symbol?.val || '', url: country?.url, }; } handleCountrySelectChange_(selectedData) { this.setCookie_(MARKET_COUNTRY_COOKIE, selectedData.value); this.handleChangeURL_(selectedData.url); } getDefaultLanguageValue_() { return this.marketLanguages?.find?.( (lang) => lang.code === this.global?.market?.market_lang )?.name; } mapLanguageRenderData_(language) { return { value: language.name, url: language.url, }; } handleLanguageSelectChange_(selectedData) { this.handleChangeURL_(selectedData.url); } renderTemplateElement_(parent, role, value) { const elements = SPZCore.Dom.scopedQuerySelectorAll( parent, `[role="${role}"]` ); elements.forEach((element) => { if (element && value) { element.innerHTML = value; } }); } renderTemplateImg_(parent, role, options) { const flagElement = SPZCore.Dom.scopedQuerySelector( parent, `[role="${role}"]` ); if (flagElement && options?.src && options?.height && options?.width) { const spzImg = self.document.createElement('ljs-img'); spzImg.setAttribute('src', options.src); spzImg.setAttribute('layout', 'responsive'); spzImg.setAttribute('width', options.width); spzImg.setAttribute('height', options.height); flagElement.appendChild(spzImg); } } handleChangeURL_(url) { if (!!url) { let {origin, pathname, search} = this.win.location; pathname = pathname.replace(SITE, url != '/' ? url : ''); this.win.location.href = `${origin}${pathname}${search}`; } else { this.win.location.reload(true); } } initModalEntry_(role) { const marketModalTemplate = SPZCore.Dom.scopedQuerySelector( this.element, `[role="${role}"]` ); if (marketModalTemplate) { const tempParentNode = self.document.createElement('div'); const clonedTemplate = self.document.importNode( marketModalTemplate.content, true ); tempParentNode.appendChild(clonedTemplate); this.renderTemplateImg_(tempParentNode, MARKET_MODAL_FLAG, { src: this.ipMatchingMarket?.img, width: '80', height: '80', }); this.renderTemplateElement_( tempParentNode, MARKET_MODAL_COUNTRY_CODE, this.ipMatchingMarket?.name ); this.renderTemplateElement_( tempParentNode, MARKET_MODAL_CURRENCY_SYMBOL, this.ipMatchingMarket?.currency_with_symbol ); const lightbox = self.document.createElement('ljs-lightbox'); lightbox.setAttribute('layout', 'nodisplay'); lightbox.appendChild(tempParentNode.firstElementChild); self.document.body.appendChild(lightbox); SPZ.whenApiDefined(lightbox).then((apis) => { SPZCore.Dom.scopedQuerySelectorAll( lightbox, `[role="${MARKET_MODAL_CLOSE}"]` ).forEach((ele) => { ele.addEventListener('click', () => { this.setCookie_(COOKIE_TIPS_NAME, 1, COOKIE_TIPS_EXPIRES); apis.close(); }); }); const marketModalConfirmElement = SPZCore.Dom.scopedQuerySelector( lightbox, `[role="${MARKET_MODAL_CONFIRM}"]` ); if (marketModalConfirmElement && this.ipMatchingMarket?.url) { marketModalConfirmElement.addEventListener('click', () => { this.setCookie_(COOKIE_TIPS_NAME, 1, COOKIE_TIPS_EXPIRES); this.setCookie_(MARKET_COUNTRY_COOKIE, this.ipMatchingMarket?.name); this.handleChangeURL_(this.ipMatchingMarket?.url); }); } const marketModalReselectElement = SPZCore.Dom.scopedQuerySelector( lightbox, `[role="${MARKET_MODAL_RESELECT}"]` ); if (marketModalReselectElement) { marketModalReselectElement.addEventListener('click', () => { this.setCookie_(COOKIE_TIPS_NAME, 1, COOKIE_TIPS_EXPIRES); const marketReselectTemplate = SPZCore.Dom.scopedQuerySelector( this.element, `[role="${MARKET_RESELECT_MODAL}"]` ); if (marketReselectTemplate && lightbox.firstElementChild) { const clonedTemplate = self.document.importNode( marketReselectTemplate.content, true ); const selectParent = SPZCore.Dom.scopedQuerySelector( clonedTemplate, `[role="${MARKET_MODAL_RESELECT_COUNTRY_SELECT}"]` ); if (selectParent) { this.createSelect_({ parent: selectParent, defaultValue: this.getDefaultCountryValue_(), dataList: this.marketCountryList.map( this.mapCountryRenderData_ ), listElementWithTemplate: this.getListElementWithTemplate_( MARKET_COUNTRY_SELECT ), itemHandler: this.handleCountrySelectChange_.bind(this), }); } lightbox.replaceChild(clonedTemplate, lightbox.firstElementChild); SPZCore.Dom.scopedQuerySelectorAll( lightbox, `[role="${MARKET_MODAL_CLOSE}"]` ).forEach((ele) => { ele.addEventListener('click', () => { this.setCookie_(COOKIE_TIPS_NAME, 1, COOKIE_TIPS_EXPIRES); apis.close(); }); }); } }); } apis.open(); }); } } async getMarketThemeSettings_() { return this.xhr_.fetchJson(MARKET_THEME_SETTINGS).then((res) => { this.useCountrySelect_ = !!res.country_selector_enabled; this.useLanguageSelect_ = !!res.language_selector_enabled && this.global?.market?.market_id; this.useModal_ = !!res.redirect_pop_enabled; return res; }); } async getCountryList_() { return this.xhr_.fetchJson(MARKET_COUNTRIES).then((res) => { this.marketCountryList = res.data.length ? res.data : []; return res; }); } async getIpMatchingMarket_() { return this.xhr_.fetchJson(IP_MATCHING_MARKET, { method: 'POST', body: { stations: [], }, }); } async getMarketLanguages_(marketId) { return this.xhr_ .fetchJson(MARKET_LANGUAGES.replace(/:id/gim, marketId)) .then((res) => { this.marketLanguages = res?.languages?.length ? res.languages : []; return res; }); } hasCookie_(name) { const m = self.document.cookie .split(';') .filter((pair) => pair.trim().startsWith(name + '=')); return !!(m && m[0]); } getCookie_(name) { const m = self.document.cookie .split(';') .filter((pair) => pair.trim().startsWith(name + '=')); return m && m[0] ? m[0].split('=')[1] : null; } setCookie_(name, value, expires) { const expiresDate = new Date(Date.now() + expires).toGMTString(); self.document.cookie = `${name}=${encodeURIComponent( value )};expires=${expiresDate};path=/`; } } SPZ.defineElement('spz-custom-market', SpzCustomMarket);
function setSearchUrl(searchValue) { return Promise.resolve({ url: '/search?q=' + searchValue }); } exportFunction('setSearchUrl', setSearchUrl); Search function setSearchUrl(searchValue) { return Promise.resolve({ url: '/search?q=' + searchValue }); } exportFunction('setSearchUrl', setSearchUrl); Search
Log in Create an account
Your cart is reserved for !
Your cart is currently empty.
Close
  • Home
  • New Arrivals
  • Best Sellers
  • Dresses
    Dresses
    • Wedding Guest Dresses
    • Floral Dresses
    • Mini Dresses
    • Midi Dresses
    • Maxi Dresses
  • Swimwears
  • Sweatshirt
  • Accessories
  • Log in Create an account
    const marketSlot = document.querySelector(".plugin_c_market"); if(marketSlot) { marketSlot.remove(); } const SITE = (window.C_SETTINGS || window[atob('U0hPUExBWlpB')])?.routes?.root || ''; const MARKET_THEME_SETTINGS = `${SITE}/api/markets/theme_setting`; const MARKET_COUNTRIES = `${SITE}/api/markets/countries`; const IP_MATCHING_MARKET = `${SITE}/api/front/station`; const MARKET_LANGUAGES = `${SITE}/api/markets/:id/active_languages`; const URL_REDIRECT = '_market_redirected'; const COOKIE_TIPS_NAME = 'market_no_tips'; const COOKIE_TIPS_EXPIRES = 1000 * 60 * 60 * 24 * 14; const MARKET_COUNTRY_COOKIE = '_shoplazza_market_country'; const MARKET_MODAL_LOADED = '__market_modal_loaded__'; const PROPERTY_SELECTED = 'selected'; const MARKET_PC_HEADER_TRIGGER = 'market-pc-header-trigger'; const MARKET_PC_HEADER_COUNTRY_SELECT_TITLE = 'market-pc-header-country-select-title'; const MARKET_PC_HEADER_LANGUAGE_SELECT_TITLE = 'market-pc-header-language-select-title'; const MARKET_PC_HEADER_LANGUAGE_SELECT_SUB_TITLE = 'market-pc-header-language-select-sub-title'; const MARKET_PC_HEADER_COUNTRY_SELECT_SUB_TITLE = 'market-pc-header-country-select-sub-title'; const MARKET_FLAG = 'market-flag'; const MARKET_SELECT_VALUE = 'market-select-value'; const MARKET_CURRENCY = 'market-currency'; const MARKET_CURRENCY_SYMBOL = 'market-currency-symbol'; const MARKET_SELECT_ITEM = 'market-select-item'; const MARKET_SELECT_ITEM_ID = 'market-select-item-id'; const MARKET_SELECT_LIST = 'market-select-list'; const MARKET_LANGUAGE_SELECT = 'market-language-select'; const MARKET_COUNTRY_SELECT = 'market-country-select'; const MARKET_MODAL = 'market-modal'; const MARKET_GATEWAY_REDIRECT_MODAL = 'market-gateway-redirect-modal'; const MARKET_RESELECT_MODAL = 'market-reselect-modal'; const MARKET_MODAL_FLAG = 'market-modal-flag'; const MARKET_MODAL_COUNTRY_CODE = 'market-modal-country-code'; const MARKET_MODAL_CURRENCY_SYMBOL = 'market-modal-currency-symbol'; const MARKET_MODAL_CLOSE = 'market-modal-close'; const MARKET_MODAL_CONFIRM = 'market-modal-confirm'; const MARKET_MODAL_RESELECT = 'market-modal-reselect'; const MARKET_MODAL_RESELECT_COUNTRY_SELECT = 'market-modal-reselect-country-select'; const DATA_SECTION_TYPE = 'data-section-type'; const SECTION_TYPE_HEADER = 'header'; const SECTION_TYPE_FOOTER = 'footer'; class SpzCustomMarket extends SPZ.BaseElement { constructor(element) { super(element); this.global = null; this.useCountrySelect_ = false; this.useLanguageSelect_ = false; this.useModal_ = false; this.isSingleSelectMode_ = false; this.blockSectionPosition_ = ''; this.isEditMode = false; this.ipMatchingMarket = null; this.marketCountryList = []; this.marketLanguages = []; this.toast = null; } static deferredMount() { return false; } isLayoutSupported(layout) { return layout == SPZCore.Layout.LOGIC; } buildCallback() { console.debug('Geolocation'); this.xhr_ = SPZServices.xhrFor(this.win); const platform = SPZServices.platformFor(this.win); this.isIOS_ = platform.isIos(); this.action_ = SPZServices.actionServiceForDoc(this.element); this.global = this.win.C_SETTINGS || this.win[atob('U0hPUExBWlpB')]; this.isEditMode = new URLSearchParams(this.win.location.search).get('preview_theme_id') && new URLSearchParams(this.win.location.search).get('oseid'); this.init_(); } showToast_(content) { if (!this.toast) { this.toast = self.document.createElement('ljs-toast'); this.toast.setAttribute('layout', 'nodisplay'); this.toast.setAttribute('hidden', ''); this.toast.setAttribute('duration', '2000'); this.element.appendChild(this.toast); } SPZ.whenApiDefined(this.toast).then((apis) => { apis.showToast(content); }); } triggerEvent_(name, data) { const event = SPZUtils.Event.create(this.win, `${TAG}.${name}`, data); this.action_.trigger(this.element, name, event); } findBlockSectionPosition() { let current = this.element; while (current) { const dataSectionType = current.getAttribute(DATA_SECTION_TYPE); if ( dataSectionType === SECTION_TYPE_HEADER || dataSectionType === SECTION_TYPE_FOOTER ) { return dataSectionType; } current = current.parentElement; } return ''; } async initSettings_() { await this.getMarketThemeSettings_(); if (this.useCountrySelect_) { this.element.setAttribute('use-country-select', true); } if (this.useLanguageSelect_) { this.element.setAttribute('use-language-select', true); } if (this.useModal_) { this.element.setAttribute('use-modal', true); } if ( (this.useCountrySelect_ && !this.useLanguageSelect_) || (!this.useCountrySelect_ && this.useLanguageSelect_) ) { this.isSingleSelectMode_ = true; } this.blockSectionPosition_ = this.findBlockSectionPosition(); this.isPCLayout_ = this.win.matchMedia('(min-width: 960px)').matches; } renderMarketSelectTemplateNode_(clonedTemplate, data) { this.renderTemplateImg_(clonedTemplate, MARKET_FLAG, { src: data?.flag, width: '24', height: '24', }); this.renderTemplateElement_( clonedTemplate, MARKET_SELECT_VALUE, data.value ); this.renderTemplateElement_( clonedTemplate, MARKET_CURRENCY, data?.currency ); this.renderTemplateElement_( clonedTemplate, MARKET_CURRENCY_SYMBOL, data?.currencySymbol ); } bindDropdownOpenClickEvent_(triggerElement, dropdown) { if (!triggerElement) return; const triggerOpen = () => { SPZ.whenApiDefined(dropdown).then((apis) => { if (!dropdown.hasAttribute('open')) { apis.open(triggerElement); } }); }; if (this.isIOS_) { triggerElement.addEventListener('touchstart', triggerOpen); } else { triggerElement.addEventListener('click', triggerOpen); } } createDropdown_() { const dropdown = self.document.createElement('ljs-dropdown'); dropdown.setAttribute('layout', 'nodisplay'); if (this.blockSectionPosition_ === 'header') { dropdown.setAttribute('overlay-style', 'top: 4px;'); dropdown.setAttribute('placement', 'bottomRight'); } else if (this.blockSectionPosition_ === 'footer') { dropdown.setAttribute('overlay-style', 'top: -4px;'); dropdown.setAttribute('placement', 'top'); } return dropdown; } createDropdownIcon_() { const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svgElement.setAttribute("class", "market-rotate-180"); svgElement.setAttribute("width", "16"); svgElement.setAttribute("height", "16"); const path1 = document.createElementNS("http://www.w3.org/2000/svg", "path"); path1.setAttribute("d", "M7.47 5.172a.75.75 0 0 1 1.06 0l4.596 4.596a.75.75 0 1 1-1.06 1.06L7.468 6.232a.75.75 0 0 1 0-1.06Z"); path1.setAttribute("fill", "currentColor"); const path2 = document.createElementNS("http://www.w3.org/2000/svg", "path"); path2.setAttribute("d", "M8.533 5.172a.75.75 0 0 1 0 1.06l-4.596 4.596a.75.75 0 1 1-1.061-1.06l4.596-4.596a.75.75 0 0 1 1.06 0Z"); path2.setAttribute("fill", "currentColor"); svgElement.appendChild(path1); svgElement.appendChild(path2); return svgElement; } renderDropdownListWithClickEvent_({ triggerElement, dataList, subTitleRole, listElementWithTemplate, defaultValue, itemHandler, shouldUpdateSelectedItem = false, }) { const dropdown = this.createDropdown_(); const itemTemplate = SPZCore.Dom.scopedQuerySelector( listElementWithTemplate, 'template' ); const clonedItemTemplate = itemTemplate.cloneNode(true); const fragment = self.document.createDocumentFragment(); dataList.forEach((data) => { const tempParentNode = self.document.createElement('div'); const clonedTemplate = self.document.importNode( clonedItemTemplate.content, true ); tempParentNode.appendChild(clonedTemplate); tempParentNode.firstElementChild.classList.add( 'market-select-item' ); this.renderMarketSelectTemplateNode_(tempParentNode, data); const selectItemElement = SPZCore.Dom.scopedQuerySelector( tempParentNode, `[role="${MARKET_SELECT_ITEM}"]` ); if (!selectItemElement) { return; } if (defaultValue === data.value) { if (shouldUpdateSelectedItem) { const clonedSelectItemElement = selectItemElement.cloneNode(true); triggerElement.replaceChild( clonedSelectItemElement, triggerElement.firstElementChild ); } selectItemElement.setAttribute(PROPERTY_SELECTED, ''); } selectItemElement.setAttribute(MARKET_SELECT_ITEM_ID, data.value); fragment.appendChild(tempParentNode.firstElementChild); }); let value = defaultValue; listElementWithTemplate.addEventListener( 'click', (e) => { if (this.isEditMode) { this.showToast_('编辑器下不支持切换国家'); SPZ.whenApiDefined(dropdown).then((apis) => { apis.close(); }); return; } let targetElement = e.target; while (targetElement) { if ( !targetElement || targetElement.getAttribute(MARKET_SELECT_ITEM_ID) ) { break; } targetElement = targetElement.parentNode; } if ( !targetElement || !targetElement.hasAttribute(MARKET_SELECT_ITEM_ID) ) { return; } const selectValue = targetElement.getAttribute(MARKET_SELECT_ITEM_ID); if (value === selectValue) { SPZ.whenApiDefined(dropdown).then((apis) => { apis.close(); }); return; } const selectedData = dataList.find((c) => c.value === selectValue); if (shouldUpdateSelectedItem) { const tempParentNode = self.document.createElement('div'); const clonedTemplate = self.document.importNode( clonedItemTemplate.content, true ); tempParentNode.appendChild(clonedTemplate); this.renderMarketSelectTemplateNode_(tempParentNode, selectedData); tempParentNode.firstElementChild.classList.add( 'market-select-item' ); triggerElement.replaceChild( tempParentNode.firstElementChild, triggerElement.firstElementChild ); } value = selectValue; itemHandler?.(selectedData); SPZ.whenApiDefined(dropdown).then((apis) => { apis.close(); }); }, false ); listElementWithTemplate.removeChild(itemTemplate); listElementWithTemplate.appendChild(fragment); listElementWithTemplate.classList.add('market-select-list'); dropdown.appendChild(listElementWithTemplate); if (subTitleRole) { this.renderSelectTitle_(dropdown, subTitleRole); } return dropdown; } createSelect_({ parent, defaultValue, dataList, listElementWithTemplate, itemHandler, titleRole, }) { const triggerElement = self.document.createElement('div'); triggerElement.classList.add('market-select'); const displayElement = self.document.createElement('div'); triggerElement.appendChild(displayElement); triggerElement.appendChild(this.createDropdownIcon_()); const dropdown = this.renderDropdownListWithClickEvent_({ triggerElement, dataList, listElementWithTemplate, defaultValue, itemHandler, shouldUpdateSelectedItem: true, }); this.bindDropdownOpenClickEvent_(triggerElement, dropdown); const dropdownContainer = self.document.createElement('div'); dropdownContainer.appendChild(triggerElement); dropdownContainer.appendChild(dropdown); dropdownContainer.classList.add('market-select-container'); this.renderSelectTitle_(dropdownContainer, titleRole); parent.appendChild(dropdownContainer); } getListElementWithTemplate_(role) { const template = SPZCore.Dom.scopedQuerySelector( this.element, `[role="${role}"]` ); if (template) { const clonedTemplate = template.cloneNode(true); const tempParent = self.document.createElement("div"); tempParent.appendChild(clonedTemplate.content); const listElementWithTemplate = SPZCore.Dom.scopedQuerySelector( tempParent, `[role="${MARKET_SELECT_LIST}"]` ); return listElementWithTemplate; } return null; } renderSelectTitle_(parent, role) { if (!parent || !role) { return; } const template = SPZCore.Dom.scopedQuerySelector( this.element, `[role="${role}"]` ); const content = self.document.importNode(template.content, true); parent.insertBefore(content, parent.firstElementChild); parent.firstElementChild.classList.add( role.includes('sub') ? 'market-pc-header-select-sub-title' : 'market-pc-header-select-title' ); } initSelect_(rootNode, options) { const parent = rootNode || this.element; if (this.useCountrySelect_) { this.createSelect_({ parent, titleRole: options?.shouldRenderSelectTitle ? MARKET_PC_HEADER_COUNTRY_SELECT_TITLE : undefined, defaultValue: this.getDefaultCountryValue_(), dataList: this.marketCountryList.map(this.mapCountryRenderData_), listElementWithTemplate: this.getListElementWithTemplate_( MARKET_COUNTRY_SELECT ), itemHandler: this.handleCountrySelectChange_.bind(this), }); } if (this.useLanguageSelect_) { this.createSelect_({ parent, titleRole: options?.shouldRenderSelectTitle ? MARKET_PC_HEADER_LANGUAGE_SELECT_TITLE : undefined, defaultValue: this.getDefaultLanguageValue_(), dataList: this.marketLanguages.map(this.mapLanguageRenderData_), listElementWithTemplate: this.getListElementWithTemplate_( MARKET_LANGUAGE_SELECT ), itemHandler: this.handleLanguageSelectChange_.bind(this), }); } } initPcHeaderTriggerElement() { const headerTriggerElementTemplate = SPZCore.Dom.scopedQuerySelector( this.element, `[role="${MARKET_PC_HEADER_TRIGGER}"]` ); const headerTriggerElement = self.document.importNode( headerTriggerElementTemplate.content, true ); const parentDivElement = self.document.createElement('div'); parentDivElement.setAttribute('role', MARKET_PC_HEADER_TRIGGER); parentDivElement.appendChild(headerTriggerElement); this.element.removeChild(headerTriggerElementTemplate); return parentDivElement; } initPanelWithSelect_() { const triggerElement = this.initPcHeaderTriggerElement(); const dropdown = this.createDropdown_(); const panelElement = self.document.createElement('div'); panelElement.classList.add('market-panel'); this.initSelect_(panelElement, {shouldRenderSelectTitle: true}); dropdown.appendChild(panelElement); this.bindDropdownOpenClickEvent_(triggerElement, dropdown); this.element.appendChild(triggerElement); this.element.insertBefore(dropdown, triggerElement); } initSingleSelectDropdown_() { const triggerElement = this.initPcHeaderTriggerElement(); let dropdown; if (this.useCountrySelect_) { dropdown = this.renderDropdownListWithClickEvent_({ triggerElement, subTitleRole: MARKET_PC_HEADER_COUNTRY_SELECT_SUB_TITLE, dataList: this.marketCountryList.map(this.mapCountryRenderData_), listElementWithTemplate: this.getListElementWithTemplate_( MARKET_COUNTRY_SELECT ), defaultValue: this.getDefaultCountryValue_(), itemHandler: this.handleCountrySelectChange_.bind(this), }); } else if (this.useLanguageSelect_) { dropdown = this.renderDropdownListWithClickEvent_({ triggerElement, subTitleRole: MARKET_PC_HEADER_LANGUAGE_SELECT_SUB_TITLE, dataList: this.marketLanguages.map(this.mapLanguageRenderData_), listElementWithTemplate: this.getListElementWithTemplate_( MARKET_LANGUAGE_SELECT ), defaultValue: this.getDefaultLanguageValue_(), itemHandler: this.handleLanguageSelectChange_.bind(this), }); } if (dropdown) { this.bindDropdownOpenClickEvent_(triggerElement, dropdown); this.element.appendChild(triggerElement); this.element.appendChild(dropdown); } } initEntry_() { if (this.blockSectionPosition_ === SECTION_TYPE_HEADER) { if (this.isSingleSelectMode_) { this.initSingleSelectDropdown_(); } else if (this.useCountrySelect_ && this.useLanguageSelect_) { this.initPanelWithSelect_(); } } this.initSelect_(this.element); } async initData_() { const promises = []; if (this.useCountrySelect_ || this.useModal_) { promises.push(this.getCountryList_(), this.getIpMatchingMarket_()); } if (this.useLanguageSelect_) { promises.push(this.getMarketLanguages_(this.global.market.market_id)); } return Promise.all(promises).then((results) => { const ipMatchingMarket = results.find((result) => result.hasOwnProperty('matching_station') ); const marketCountryList = results.find((result) => result.hasOwnProperty('data') ); if (ipMatchingMarket && marketCountryList) { this.ipMatchingMarket = ipMatchingMarket?.matching_station?.find?.( (item) => item.type === 'multiple_market' ) || { img: marketCountryList.length ? marketCountryList?.[0]?.detail && marketCountryList[0].detail?.flag : '', }; } }); } initModal_() { if ( this.isEditMode || !this.ipMatchingMarket?.market_id || !this.useModal_ || this.hasCookie_(COOKIE_TIPS_NAME) || this.win[MARKET_MODAL_LOADED] ) { return; } this.win[MARKET_MODAL_LOADED] = true; const redirectParam = new URLSearchParams(this.win.location.search).get( URL_REDIRECT ); if (redirectParam) { this.initModalEntry_(MARKET_GATEWAY_REDIRECT_MODAL); } else if ( this.ipMatchingMarket.market_id !== this.global?.market?.market_id ) { this.initModalEntry_(MARKET_MODAL); } } async init_() { await this.initSettings_(); await this.initData_(); this.initEntry_(); this.initModal_(); } getDefaultCountryValue_() { return this.getCookie_(MARKET_COUNTRY_COOKIE) || this.marketCountryList[0]?.country_code; } mapCountryRenderData_(country) { return { flag: country?.detail?.flag || '', value: country?.country_code, currency: country?.currency, currencySymbol: country?.symbol?.val || '', url: country?.url, }; } handleCountrySelectChange_(selectedData) { this.setCookie_(MARKET_COUNTRY_COOKIE, selectedData.value); this.handleChangeURL_(selectedData.url); } getDefaultLanguageValue_() { return this.marketLanguages?.find?.( (lang) => lang.code === this.global?.market?.market_lang )?.name; } mapLanguageRenderData_(language) { return { value: language.name, url: language.url, }; } handleLanguageSelectChange_(selectedData) { this.handleChangeURL_(selectedData.url); } renderTemplateElement_(parent, role, value) { const elements = SPZCore.Dom.scopedQuerySelectorAll( parent, `[role="${role}"]` ); elements.forEach((element) => { if (element && value) { element.innerHTML = value; } }); } renderTemplateImg_(parent, role, options) { const flagElement = SPZCore.Dom.scopedQuerySelector( parent, `[role="${role}"]` ); if (flagElement && options?.src && options?.height && options?.width) { const spzImg = self.document.createElement('ljs-img'); spzImg.setAttribute('src', options.src); spzImg.setAttribute('layout', 'responsive'); spzImg.setAttribute('width', options.width); spzImg.setAttribute('height', options.height); flagElement.appendChild(spzImg); } } handleChangeURL_(url) { if (!!url) { let {origin, pathname, search} = this.win.location; pathname = pathname.replace(SITE, url != '/' ? url : ''); this.win.location.href = `${origin}${pathname}${search}`; } else { this.win.location.reload(true); } } initModalEntry_(role) { const marketModalTemplate = SPZCore.Dom.scopedQuerySelector( this.element, `[role="${role}"]` ); if (marketModalTemplate) { const tempParentNode = self.document.createElement('div'); const clonedTemplate = self.document.importNode( marketModalTemplate.content, true ); tempParentNode.appendChild(clonedTemplate); this.renderTemplateImg_(tempParentNode, MARKET_MODAL_FLAG, { src: this.ipMatchingMarket?.img, width: '80', height: '80', }); this.renderTemplateElement_( tempParentNode, MARKET_MODAL_COUNTRY_CODE, this.ipMatchingMarket?.name ); this.renderTemplateElement_( tempParentNode, MARKET_MODAL_CURRENCY_SYMBOL, this.ipMatchingMarket?.currency_with_symbol ); const lightbox = self.document.createElement('ljs-lightbox'); lightbox.setAttribute('layout', 'nodisplay'); lightbox.appendChild(tempParentNode.firstElementChild); self.document.body.appendChild(lightbox); SPZ.whenApiDefined(lightbox).then((apis) => { SPZCore.Dom.scopedQuerySelectorAll( lightbox, `[role="${MARKET_MODAL_CLOSE}"]` ).forEach((ele) => { ele.addEventListener('click', () => { this.setCookie_(COOKIE_TIPS_NAME, 1, COOKIE_TIPS_EXPIRES); apis.close(); }); }); const marketModalConfirmElement = SPZCore.Dom.scopedQuerySelector( lightbox, `[role="${MARKET_MODAL_CONFIRM}"]` ); if (marketModalConfirmElement && this.ipMatchingMarket?.url) { marketModalConfirmElement.addEventListener('click', () => { this.setCookie_(COOKIE_TIPS_NAME, 1, COOKIE_TIPS_EXPIRES); this.setCookie_(MARKET_COUNTRY_COOKIE, this.ipMatchingMarket?.name); this.handleChangeURL_(this.ipMatchingMarket?.url); }); } const marketModalReselectElement = SPZCore.Dom.scopedQuerySelector( lightbox, `[role="${MARKET_MODAL_RESELECT}"]` ); if (marketModalReselectElement) { marketModalReselectElement.addEventListener('click', () => { this.setCookie_(COOKIE_TIPS_NAME, 1, COOKIE_TIPS_EXPIRES); const marketReselectTemplate = SPZCore.Dom.scopedQuerySelector( this.element, `[role="${MARKET_RESELECT_MODAL}"]` ); if (marketReselectTemplate && lightbox.firstElementChild) { const clonedTemplate = self.document.importNode( marketReselectTemplate.content, true ); const selectParent = SPZCore.Dom.scopedQuerySelector( clonedTemplate, `[role="${MARKET_MODAL_RESELECT_COUNTRY_SELECT}"]` ); if (selectParent) { this.createSelect_({ parent: selectParent, defaultValue: this.getDefaultCountryValue_(), dataList: this.marketCountryList.map( this.mapCountryRenderData_ ), listElementWithTemplate: this.getListElementWithTemplate_( MARKET_COUNTRY_SELECT ), itemHandler: this.handleCountrySelectChange_.bind(this), }); } lightbox.replaceChild(clonedTemplate, lightbox.firstElementChild); SPZCore.Dom.scopedQuerySelectorAll( lightbox, `[role="${MARKET_MODAL_CLOSE}"]` ).forEach((ele) => { ele.addEventListener('click', () => { this.setCookie_(COOKIE_TIPS_NAME, 1, COOKIE_TIPS_EXPIRES); apis.close(); }); }); } }); } apis.open(); }); } } async getMarketThemeSettings_() { return this.xhr_.fetchJson(MARKET_THEME_SETTINGS).then((res) => { this.useCountrySelect_ = !!res.country_selector_enabled; this.useLanguageSelect_ = !!res.language_selector_enabled && this.global?.market?.market_id; this.useModal_ = !!res.redirect_pop_enabled; return res; }); } async getCountryList_() { return this.xhr_.fetchJson(MARKET_COUNTRIES).then((res) => { this.marketCountryList = res.data.length ? res.data : []; return res; }); } async getIpMatchingMarket_() { return this.xhr_.fetchJson(IP_MATCHING_MARKET, { method: 'POST', body: { stations: [], }, }); } async getMarketLanguages_(marketId) { return this.xhr_ .fetchJson(MARKET_LANGUAGES.replace(/:id/gim, marketId)) .then((res) => { this.marketLanguages = res?.languages?.length ? res.languages : []; return res; }); } hasCookie_(name) { const m = self.document.cookie .split(';') .filter((pair) => pair.trim().startsWith(name + '=')); return !!(m && m[0]); } getCookie_(name) { const m = self.document.cookie .split(';') .filter((pair) => pair.trim().startsWith(name + '=')); return m && m[0] ? m[0].split('=')[1] : null; } setCookie_(name, value, expires) { const expiresDate = new Date(Date.now() + expires).toGMTString(); self.document.cookie = `${name}=${encodeURIComponent( value )};expires=${expiresDate};path=/`; } } SPZ.defineElement('spz-custom-market', SpzCustomMarket);
function setSearchUrl(searchValue) { return Promise.resolve({ url: '/search?q=' + searchValue }); } exportFunction('setSearchUrl', setSearchUrl);
Home /  My Account
Login
Please enter your e-mail and password:
Email is required
Please enter a valid email.
Password is required.
Password must be between 6-16 characters long.
Forgot password?
Don't have an account? Create one
Login for more discounts
⭐️Subscribe today to hear first about our sales⭐️
Please fill in this field
Please enter a valid email address
Thanks for subscribing
Company Info
  • About Us
  • Privacy Policy
  • Terms & Conditions
Get in touch
Email us Live chat
Support Info
  • Shipping Policy
  • Returns and Refunds
  • Payment Method
  • Track Order
We accept
American Express Apple Pay Mastercard PayPal Visa
Company Info
  • About Us
  • Privacy Policy
  • Terms & Conditions
Get in touch
Email us Live chat
Support Info
  • Shipping Policy
  • Returns and Refunds
  • Payment Method
  • Track Order
We accept
American Express Apple Pay Mastercard PayPal Visa
© 2025 Colinenshop Copyright © 2025 Colinenshop all rights reserved.

Cart

Your cart is reserved for !
cart
cart
Your cart is currently empty.
Continue shopping
const TAG = "spz-custom-announcement"; const DISPLAY_TYPE = { ANNOUNCEMENT: "PTT_BANNER" // 公告栏 }; const API = { LIST: `/api/storefront/promotion/placement/list`, // 获取公告栏列表 REPORT: `/api/storefront/promotion/placement/data/report` // 上报数据 }; const DISPLAY_DEVICE = { PC_AND_MOBILE: "PD_PC_MOBILE", // PC和移动端 PC: "PD_PC", // PC MOBILE: "PD_MOBILE" // 移动端 }; const REPORT_EVENT = { CLICK: "PE_CLICK", // 点击事件 IMPRESSION: "PE_IMPRESSION" // 曝光事件 }; const POSITION = { TOP: "PP_TOP", // 顶部 BOTTOM: "PP_BOTTOM" // 底部 } const MODE = { FIXED: "PM_FIXED", // 固定 NORMAL: "PM_SCROLLING" // 滚动 } const THEME_NAME = window.SHOPLAZZA.theme.merchant_theme_name; class SpzCustomAnnouncement extends SPZ.BaseElement { constructor(element) { super(element); this.announcementList_ = []; // 公告栏数据 } static deferredMount() { return false; } buildCallback() { this.action_ = SPZServices.actionServiceForDoc(this.element); this.templates_ = SPZServices.templatesForDoc(this.element); this.xhr_ = SPZServices.xhrFor(this.win); this.setupAction_(); this.viewport_ = this.getViewport(); } mountCallback() { this.fetchData_(); this.createAnnouncementDom_(); this.listenCartChange_(); } fetchData_(type = '') { const id = window.SHOPLAZZA.meta.page.template_type === 51 ? window.SHOPLAZZA.meta.page.resource_id : 0; return this.xhr_.fetchJson(API.LIST, { method: 'POST', body: { page_id: window.SHOPLAZZA.meta.page.template_type, placement_type: DISPLAY_TYPE.ANNOUNCEMENT, discount_id: id } }).then((res) => { this.announcementList_ = res.list || []; if (this.announcementList_.length > 0) { this.announcementList_.forEach((item) => { item.config = JSON.parse(item.config); }); } if(type === 'cartChange') { this.announcementList_.forEach((item) => { this.updateText_(item); }); } else { this.doRender_(this.announcementList_); } }).catch((error) => { console.error(error); }) } doRender_(data) { return this.templates_ .findAndRenderTemplate(this.element, { list: this.announcementList_ }) .then((el) => { const children = this.element.querySelector('*:not(template)'); children && SPZCore.Dom.removeElement(children); this.element.appendChild(el); }) .then(() => { this.announcementList_.forEach((item) => { this.showAnnouncement_(item); }); }).then(() => { this.handleThemeCompatibility_(); }); } // 更新文案 updateText_(item) { const announcement = document.querySelector(`#announcement-${item.id}`); const announcementText = announcement.querySelectorAll('.announcement_text'); const textArr = item.config.text_discount.replace_texts; const textDom = textArr.map((text) => { return `${text}`; }).join(','); announcementText.forEach((text) => { text.innerHTML = textDom; }); } // 创建公告栏dom createAnnouncementDom_() { const isHero = /Hero/.test(THEME_NAME); const isEva = /Eva/.test(THEME_NAME); const headerEl = document.querySelector('[data-section-type="header"]'); const headerSticky = headerEl && SPZCore.Dom.computedStyle(this.win, headerEl).position === 'sticky'; // 创建滚动的底部公告栏 const announcementBottomContainer = document.createElement('div'); announcementBottomContainer.className = 'announcement__container_bottom bootstrap'; document.body.appendChild(announcementBottomContainer); // 创建固定的底部公告栏 const announcementBottomSticky = document.createElement('ljs-sticky'); announcementBottomSticky.className = 'announcement__container_bottom-sticky'; announcementBottomSticky.setAttribute('layout', 'container'); announcementBottomSticky.setAttribute('position', 'bottom'); announcementBottomSticky.style.position = 'fixed'; announcementBottomSticky.style.bottom = '0'; announcementBottomSticky.style.left = '0'; announcementBottomSticky.style.right = '0'; announcementBottomSticky.style.zIndex = '1030'; document.body.appendChild(announcementBottomSticky); const announcementTopContainer = document.createElement('div'); announcementTopContainer.classList.add('announcement__container_top'); if (isHero) { announcementTopContainer.classList.add('announcement__container_top_zIndex_1030'); } announcementTopContainer.classList.add('bootstrap'); document.body.insertBefore(announcementTopContainer, document.body.children[0]); const announcementTopFixedContainer = document.createElement('div'); announcementTopFixedContainer.classList.add('announcement__container_top-fixed'); if (isHero) { announcementTopFixedContainer.classList.add('announcement__container_top_zIndex_1030'); } announcementTopFixedContainer.classList.add('bootstrap'); const insertBeforeElement = headerSticky ? headerEl : document.body; insertBeforeElement.insertBefore(announcementTopFixedContainer, insertBeforeElement.children[0]); if (isEva) { const evaHeader = document.querySelector('header.header'); const isEvaMaskHeader = evaHeader && SPZCore.Dom.computedStyle(this.win, evaHeader).position === 'absolute'; let fixedBannerTopContainer = document.querySelector('.announcement__container_top-fixed'); if (isEvaMaskHeader) { if (fixedBannerTopContainer) { fixedBannerTopContainer.remove(); } const newBanner = document.createElement('div'); newBanner.className = 'announcement__container_top-fixed bootstrap'; document.body.insertBefore(newBanner, document.body.firstChild); fixedBannerTopContainer = newBanner; } else { if (!headerEl) return; const observer = new MutationObserver(() => { const isSticky = SPZCore.Dom.computedStyle(this.win, headerEl).position === 'sticky'; if (!isSticky) return; const isTopFixedAnnouncementInHeader = headerEl.querySelector('.announcement__container_top-fixed'); if (isTopFixedAnnouncementInHeader) return; const announcementTopFixedContainer = document.querySelector('.announcement__container_top-fixed'); if (announcementTopFixedContainer) { announcementTopFixedContainer.remove(); headerEl.insertBefore(announcementTopFixedContainer, headerEl.children[0]); observer.disconnect(); } }); observer.observe(headerEl, { attributes: true, attributeFilter: ['style', 'class'] }); } if (headerSticky && !isEvaMaskHeader && fixedBannerTopContainer) { fixedBannerTopContainer.style.position = 'relative'; fixedBannerTopContainer.style.zIndex = '29'; } } } // 展示公告栏 showAnnouncement_(item) { const announcement = document.querySelector(`#announcement-${item.id}`); const announcementBottomContainer = document.querySelector('.announcement__container_bottom'); const announcementBottomSticky = document.querySelector('.announcement__container_bottom-sticky'); const announcementTopContainer = document.querySelector('.announcement__container_top'); const announcementTopFixedContainer = document.querySelector('.announcement__container_top-fixed'); const isPC = this.viewport_.getWidth() >= 960; const isMobile = this.viewport_.getWidth() < 960; const isMatchPCDevice = item.device === DISPLAY_DEVICE.PC_AND_MOBILE || item.device === DISPLAY_DEVICE.PC; const isMatchMobileDevice = item.device == DISPLAY_DEVICE.PC_AND_MOBILE || item.device === DISPLAY_DEVICE.MOBILE; if((isPC && isMatchPCDevice) || (isMobile && isMatchMobileDevice)) { if (item.position === POSITION.BOTTOM) { if(item.mode === MODE.FIXED) { announcementBottomSticky && announcementBottomSticky.appendChild(announcement); } else { announcementBottomContainer && announcementBottomContainer.appendChild(announcement); } } else { if (item.mode === MODE.FIXED) { announcementTopFixedContainer && announcementTopFixedContainer.appendChild(announcement); } else { announcementTopContainer && announcementTopContainer.appendChild(announcement); } } this.reportData({ placement_id: item.id, event: REPORT_EVENT.IMPRESSION }); } } // 处理主题兼容 handleThemeCompatibility_() { try { const isBoost = /Boost/.test(THEME_NAME); const isHyde = /Hyde/.test(THEME_NAME); const isEva = /Eva/.test(THEME_NAME); const boostHeader = document.querySelector('.boost-header'); const fixedBannerTopContainer = document.querySelector('.announcement__container_top-fixed'); const notFixedBannerTopContainer = document.querySelector('.announcement__container_top'); const headerEl = document.querySelector('[data-section-type="header"]'); const headerSticky = headerEl && SPZCore.Dom.computedStyle(this.win, headerEl).position === 'sticky'; const header = document.querySelector('.header__fixed') || document.querySelector('.header__wrapper'); const headerFixed = header && SPZCore.Dom.computedStyle(this.win, header).position === 'fixed'; const handleScroll = SPZCore.Types.throttle(this.win, () => { if (isHyde) { if (header && headerSticky) { header.style.marginTop = `${fixedBannerTopContainer.offsetHeight}px`; } else { notFixedBannerTopContainer.style.marginTop = `${fixedBannerTopContainer.offsetHeight}px`; } } if (isEva) { const evaHeader = document.querySelector('header.header'); const isEvaMaskHeader = evaHeader && SPZCore.Dom.computedStyle(this.win, evaHeader).position === 'absolute'; if (!isEvaMaskHeader) return; if (evaHeader.classList.contains('header__fixed')) { evaHeader.style.marginTop = `${fixedBannerTopContainer.offsetHeight}px`; } else { notFixedBannerTopContainer.style.marginTop = `${fixedBannerTopContainer.offsetHeight}px`; } if(document.documentElement.scrollTop === 0) { evaHeader.style.marginTop = '0'; } } if (headerSticky) return; if (headerFixed) { header.style.marginTop = `${fixedBannerTopContainer.offsetHeight}px`; } else { const observer = new MutationObserver((mutationsList, observer) => { for (const mutation of mutationsList) { if (mutation.type === 'childList' && fixedBannerTopContainer.childElementCount > 0) { notFixedBannerTopContainer.style.marginTop = `${fixedBannerTopContainer.offsetHeight}px`; observer.disconnect(); // 停止观察 break; } } }); // 开始观察 fixedBannerTopContainer 的子节点变化 observer.observe(fixedBannerTopContainer, { childList: true, subtree: true }); // 初始检查 if (fixedBannerTopContainer.childElementCount > 0) { notFixedBannerTopContainer.style.marginTop = `${fixedBannerTopContainer.offsetHeight}px`; } if(header) { header.style.marginTop = '0'; } } if (isBoost) { fixedBannerTopContainer.style.zIndex = '1031'; if (boostHeader && boostHeader.classList.contains('header__fixed')) { boostHeader.style.marginTop = `${fixedBannerTopContainer.offsetHeight}px`; } else { notFixedBannerTopContainer.style.marginTop = `${fixedBannerTopContainer.offsetHeight}px`; } } }, 16); window.addEventListener('scroll', handleScroll); window.dispatchEvent(new Event('scroll')); } catch (error) { console.error('error', error); } } // 上报数据 async reportData(data) { // 如果是主题编辑器则不用处理 if(window.top !== window.self) { return; } this.xhr_.fetchJson(API.REPORT, { method: "POST", body: { placement_id: data.placement_id, event: data.event } }); } // 监听购物车变化事件dj.cartChange listenCartChange_() { SPZUtils.Event.listen(document, 'dj.cartChange', (event) => { this.fetchData_('cartChange'); }); } setupAction_() { this.registerAction('handleClose', (invocation) => { const data = invocation.args; const id = data.id; const announcement = document.querySelector(`#announcement-${id}`); announcement && SPZCore.Dom.removeElement(announcement); window.dispatchEvent(new Event('scroll')); }); this.registerAction('handleJumpLink', (invocation) => { const data = invocation.args; if(!data.show_url) return; data.url && window.open(data.url, data.open_new_window ? '_blank' : '_self'); this.reportData({ placement_id: data.id, event: REPORT_EVENT.CLICK }); }); } triggerEvent_(name, data) { const event = SPZUtils.Event.create(this.win, `${ TAG }.${ name }`, data || {}); this.action_.trigger(this.element, name, event); } isLayoutSupported(layout) { return layout == SPZCore.Layout.CONTAINER; } } SPZ.defineElement(TAG, SpzCustomAnnouncement);