Drugie zdjęcie na hover
This commit is contained in:
18
README.md
18
README.md
@@ -58,6 +58,7 @@ Warto gdzieś później zapisać nową nazwę klasy np w opisie komponentu, albo
|
|||||||
- Nie znaleziono kontenera
|
- Nie znaleziono kontenera
|
||||||
- Nie znaleziono metody graphql
|
- Nie znaleziono metody graphql
|
||||||
- Najniższa cena
|
- Najniższa cena
|
||||||
|
- Drugie Zdjęcie
|
||||||
|
|
||||||
### Przykłady UŻYCIA ###
|
### Przykłady UŻYCIA ###
|
||||||
##### Jedna ramka - obiekt ######
|
##### Jedna ramka - obiekt ######
|
||||||
@@ -84,33 +85,44 @@ new IdmHotspot({
|
|||||||
* @property {string} title - Tytuł ramki.
|
* @property {string} title - Tytuł ramki.
|
||||||
* @property {string} classes - Dodatkowe klasy CSS.
|
* @property {string} classes - Dodatkowe klasy CSS.
|
||||||
* @property {object[]} [products] - tablica produktów z układem danych takich jak w graphql. Opcjonalne, pod specjalne funkcjonalności.
|
* @property {object[]} [products] - tablica produktów z układem danych takich jak w graphql. Opcjonalne, pod specjalne funkcjonalności.
|
||||||
|
|
||||||
|
|
||||||
* @property {object} placement - Określa, gdzie wstawić ramkę (required).
|
* @property {object} placement - Określa, gdzie wstawić ramkę (required).
|
||||||
* @property {string} placement.selector - Selektor miejsca osadzenia.
|
* @property {string} placement.selector - Selektor miejsca osadzenia.
|
||||||
* @property {string} placement.insert - Pozycja wstawienia względem selektora (np. "afterbegin", "beforeend").
|
* @property {string} placement.insert - Pozycja wstawienia względem selektora (np. "afterbegin", "beforeend").
|
||||||
* @property {object} source - Dane źródłowe dla hotspotu (required).
|
|
||||||
|
|
||||||
|
* @property {object} source - Dane źródłowe dla hotspotu.
|
||||||
* @property {string} [source.hotspotType] - Typ hotspotu (np. "promotion").
|
* @property {string} [source.hotspotType] - Typ hotspotu (np. "promotion").
|
||||||
* @property {number[]} [source.productsId] - Tablica ID produktów.
|
* @property {number[]} [source.productsId] - Tablica ID produktów.
|
||||||
* @property {number} [source.productsMenu] - Identyfikator menu produktów.
|
* @property {number} [source.productsMenu] - Identyfikator menu produktów.
|
||||||
|
|
||||||
|
|
||||||
* @property {object} query - Dane zapytania, nadpisują source (DEV).
|
* @property {object} query - Dane zapytania, nadpisują source (DEV).
|
||||||
* @property {string} query.string - Zapytanie w formacie GraphQL.
|
* @property {string} query.string - Zapytanie w formacie GraphQL.
|
||||||
* @property {Function} query.graphFn - Funkcja do pobierania danych.
|
* @property {Function} query.graphFn - Funkcja do pobierania danych.
|
||||||
|
|
||||||
|
|
||||||
* @property {object} options - Ustawienia dla hotspotu (required).
|
* @property {object} options - Ustawienia dla hotspotu (required).
|
||||||
* @property {boolean} [options.lazy] - Czy wczytywać w trybie lazy.
|
* @property {boolean} [options.lazy] - Czy wczytywać w trybie lazy.
|
||||||
* @property {boolean} [options.devMode] - Czy wczytywać ramki tylko dla stron z dev=true.
|
* @property {boolean} [options.devMode] - Czy wczytywać ramki tylko dla stron z dev=true.
|
||||||
|
* @property {boolean} [options.omnibusTooltip] - Czy wyświetlać omnibusa w formie tooltip
|
||||||
|
* @property {Function} [options.callbackFn] - Funkcja callback która dzieje się po wywołaniu wszystkiego włącznie ze swiperem
|
||||||
|
|
||||||
* @property {boolean} [options.addToFavorites] - Czy włączać dodawanie do ulubionych(DZIAŁA TYLKO PO ZMIANACH SZABLONOWYCH)
|
* @property {boolean} [options.addToFavorites] - Czy włączać dodawanie do ulubionych(DZIAŁA TYLKO PO ZMIANACH SZABLONOWYCH)
|
||||||
* @property {boolean} [options.addToCompare] - Czy włączać dodawanie do porównywania
|
* @property {boolean} [options.addToCompare] - Czy włączać dodawanie do porównywania
|
||||||
* @property {boolean|string} [options.addToBasket] - Obsługa koszyka:
|
* @property {boolean|string} [options.addToBasket] - Obsługa koszyka:
|
||||||
* - true = włącz
|
* - true = włącz
|
||||||
* - false = wyłącz
|
* - false = wyłącz
|
||||||
* - "range" = dodaj z zakresem
|
* - "range" = dodaj z zakresem
|
||||||
|
|
||||||
* @property {boolean|object} options.swiper - Slider:
|
* @property {boolean|object} options.swiper - Slider:
|
||||||
* - true = aktywny
|
* - true = aktywny
|
||||||
* - false = nieaktywny
|
* - false = nieaktywny
|
||||||
* - object = konfiguracja Swiper
|
* - object = konfiguracja Swiper
|
||||||
* @property {boolean} [options.swiperScrollbar] - Czy włączać scrollbar w swiperze - DO DZIAŁANIA WYMAGA WŁĄCZONEGO SWIPERA
|
* @property {boolean} [options.swiperScrollbar] - Czy włączać scrollbar w swiperze - DO DZIAŁANIA WYMAGA WŁĄCZONEGO SWIPERA
|
||||||
* @property {Function} [options.callbackFn] - Funkcja callback która dzieje się po wywołaniu wszystkiego włącznie ze swiperem
|
|
||||||
* @property {boolean} [options.omnibusTooltip] - Czy wyświetlać omnibusa w formie tooltip
|
|
||||||
* @property {boolean} [options.showOpinions] - Czy wyświetlać opinie o produkcie w formie gwiazdek nad nazwą
|
* @property {boolean} [options.showOpinions] - Czy wyświetlać opinie o produkcie w formie gwiazdek nad nazwą
|
||||||
|
* @property {boolean} [options.showSecondImage] - Czy wyświetlać drugie zdjęcie na hover
|
||||||
*
|
*
|
||||||
* @type {Hotspot[]}
|
* @type {Hotspot[]}
|
||||||
*/
|
*/
|
||||||
|
|||||||
67
klasa.js
67
klasa.js
@@ -31,6 +31,7 @@ const idmHotspotTextObject = {
|
|||||||
[<iai:variable vid="Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"/>]: <iai:variable vid="Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"/>,
|
[<iai:variable vid="Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"/>]: <iai:variable vid="Wystąpił błąd z inicjalizacją. Proszę odśwież stronę"/>,
|
||||||
[<iai:variable vid="Nie znaleziono kontenera"/>]: <iai:variable vid="Nie znaleziono kontenera"/>,
|
[<iai:variable vid="Nie znaleziono kontenera"/>]: <iai:variable vid="Nie znaleziono kontenera"/>,
|
||||||
[<iai:variable vid="Nie znaleziono metody graphql"/>]: <iai:variable vid="Nie znaleziono metody graphql"/>,
|
[<iai:variable vid="Nie znaleziono metody graphql"/>]: <iai:variable vid="Nie znaleziono metody graphql"/>,
|
||||||
|
[<iai:variable vid="Drugie Zdjęcie"/>]: <iai:variable vid="Drugie Zdjęcie"/>,
|
||||||
};
|
};
|
||||||
// STRING
|
// STRING
|
||||||
// const idmHotspotTextObject = {
|
// const idmHotspotTextObject = {
|
||||||
@@ -240,7 +241,18 @@ const IDM_PRODUCT_GQL = (args) => JSON.stringify({
|
|||||||
});
|
});
|
||||||
// ADD TO BASKET
|
// ADD TO BASKET
|
||||||
const IDM_HOTSPOT_ADD_TO_BASKET = (t, e, a) => JSON.stringify({
|
const IDM_HOTSPOT_ADD_TO_BASKET = (t, e, a) => JSON.stringify({
|
||||||
query: `mutation {\n addProductsToBasket(ProductInput: {id: ${t}, size: "${e}", quantity: ${a}}) {\n status\n results {\n status\n error {\n code\n message\n }\n productCode\n productId\n sizeId\n quantity\n quantityAvailable\n }\n clientDetailsInBasket {\n id\n login\n firstname\n lastname\n participationPartnerProgram\n usesVat\n email\n isWholesaler\n isWholesalerOrder\n clientIdUpc\n }\n }\n }`
|
query: `mutation {
|
||||||
|
addProductsToBasket(ProductInput: {id: ${t}, size: "${e}", quantity: ${a}}) {
|
||||||
|
status
|
||||||
|
results {
|
||||||
|
status
|
||||||
|
error {
|
||||||
|
code
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`
|
||||||
});
|
});
|
||||||
/////////////////////////////////////////
|
/////////////////////////////////////////
|
||||||
// JS
|
// JS
|
||||||
@@ -420,6 +432,7 @@ class IdmHotspot{
|
|||||||
|
|
||||||
// POKAZANIE
|
// POKAZANIE
|
||||||
showOpinions: false,
|
showOpinions: false,
|
||||||
|
showSecondImage: false,
|
||||||
|
|
||||||
// DODAWANIE
|
// DODAWANIE
|
||||||
addToBasket: true, // true, false, "range"
|
addToBasket: true, // true, false, "range"
|
||||||
@@ -468,6 +481,8 @@ class IdmHotspot{
|
|||||||
this.handleQuantityInputChange = this.handleQuantityInputChange.bind(this);
|
this.handleQuantityInputChange = this.handleQuantityInputChange.bind(this);
|
||||||
this.handleAddToCompare = this.handleAddToCompare.bind(this);
|
this.handleAddToCompare = this.handleAddToCompare.bind(this);
|
||||||
this.handleAddToFav = this.handleAddToFav.bind(this);
|
this.handleAddToFav = this.handleAddToFav.bind(this);
|
||||||
|
this.handleShowSecondImage = this.handleShowSecondImage.bind(this);
|
||||||
|
this.handleHideSecondImage = this.handleHideSecondImage.bind(this);
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
@@ -619,14 +634,17 @@ class IdmHotspot{
|
|||||||
<source media="(min-width: 421px)" type="image/jpeg" srcset="${prod.iconSecond}"/>
|
<source media="(min-width: 421px)" type="image/jpeg" srcset="${prod.iconSecond}"/>
|
||||||
<source media="(max-width: 420px)" type="image/webp" srcset="${prod.iconSmall}"/>
|
<source media="(max-width: 420px)" type="image/webp" srcset="${prod.iconSmall}"/>
|
||||||
<source media="(max-width: 420px)" type="image/jpeg" srcset="${prod.iconSmallSecond}"/>
|
<source media="(max-width: 420px)" type="image/jpeg" srcset="${prod.iconSmallSecond}"/>
|
||||||
<img src="${prod.iconSecond}" loading="lazy" alt="${prod.name}">
|
<img src="${prod.iconSecond}" loading="lazy" alt="${prod.name}" class="product__image --first">
|
||||||
</picture>`;
|
</picture>`;
|
||||||
else if(prod?.iconSmall) markup += `<picture>
|
else if(prod?.iconSmall) markup += `<picture>
|
||||||
<source media="(min-width: 421px)" srcset="${prod.icon}"/>
|
<source media="(min-width: 421px)" srcset="${prod.icon}"/>
|
||||||
<source media="(max-width: 420px)" srcset="${prod.iconSmall}"/>
|
<source media="(max-width: 420px)" srcset="${prod.iconSmall}"/>
|
||||||
<img src="${prod.iconSecond}" loading="lazy" alt="${prod.name}">
|
<img src="${prod.iconSecond}" loading="lazy" alt="${prod.name}" class="product__image --first">
|
||||||
</picture>`;
|
</picture>`;
|
||||||
else markup += `<img src="${prod.icon}" loading="lazy" alt="${prod.name}">`
|
else markup += `<img src="${prod.icon}" loading="lazy" alt="${prod.name}" class="product__image --first">`;
|
||||||
|
|
||||||
|
if(this.options?.showSecondImage && prod.enclosuresImages?.[1]?.url) markup += `<img loading="lazy" src="${prod.enclosuresImages[1].url}" alt="${prod.name} - ${idmHotspotTextObject["Drugie Zdjęcie"]}" class="product__image --second"/>`;
|
||||||
|
|
||||||
return markup;
|
return markup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,6 +959,22 @@ class IdmHotspot{
|
|||||||
input.value = current.toFixed(precision);
|
input.value = current.toFixed(precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obsługuje Pokazywanie zdjęcia na hover
|
||||||
|
*/
|
||||||
|
handleShowSecondImage(e){
|
||||||
|
const prodIconEl = e.target.closest(".product__icon");
|
||||||
|
if(!prodIconEl) return;
|
||||||
|
|
||||||
|
prodIconEl.classList.add("--toggle-icon");
|
||||||
|
}
|
||||||
|
|
||||||
|
handleHideSecondImage(e){
|
||||||
|
const prodIconEl = e.target.closest(".product__icon");
|
||||||
|
if(!prodIconEl) return;
|
||||||
|
|
||||||
|
prodIconEl.classList.remove("--toggle-icon");
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Walidacja zmian ilości w polu input.
|
* Walidacja zmian ilości w polu input.
|
||||||
*/
|
*/
|
||||||
@@ -1129,28 +1163,27 @@ class IdmHotspot{
|
|||||||
// DODAWANIE DO KOSZYKA
|
// DODAWANIE DO KOSZYKA
|
||||||
if(this.options?.addToBasket){
|
if(this.options?.addToBasket){
|
||||||
const addToBasketEl = prodEl.querySelector("form.add_to_basket");
|
const addToBasketEl = prodEl.querySelector("form.add_to_basket");
|
||||||
if(!addToBasketEl) return;
|
|
||||||
addToBasketEl.addEventListener("submit", this.handleAddToBasket);
|
|
||||||
|
|
||||||
|
addToBasketEl?.addEventListener("submit", this.handleAddToBasket);
|
||||||
// + -
|
// + -
|
||||||
if(this?.options?.addToBasket === "range"){
|
if(this?.options?.addToBasket === "range"){
|
||||||
addToBasketEl.querySelector(".idm-products-banner__qty")?.addEventListener("click",this.handleQuantityButtonClick);
|
addToBasketEl?.querySelector(".idm-products-banner__qty")?.addEventListener("click",this.handleQuantityButtonClick);
|
||||||
addToBasketEl.querySelector(".idm-products-banner__qty-input")?.addEventListener("input",this.handleQuantityInputChange);
|
addToBasketEl?.querySelector(".idm-products-banner__qty-input")?.addEventListener("input",this.handleQuantityInputChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Tooltip
|
|
||||||
// if(this.options?.omnibusTooltip){
|
|
||||||
// const tooltipEl = prodEl.querySelector(".idm_tooltip");
|
|
||||||
|
|
||||||
// tooltipEl.addEventListener("click", ()=>{
|
|
||||||
// this.showTooltip(tooltipEl);
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Add to Favorites
|
// Add to Favorites
|
||||||
if(this.options?.addToFavorites && typeof this.addToFavFn === "function") prodEl.querySelector(".product__favorite")?.addEventListener("click", this.handleAddToFav);
|
if(this.options?.addToFavorites && typeof this.addToFavFn === "function") prodEl.querySelector(".product__favorite")?.addEventListener("click", this.handleAddToFav);
|
||||||
// Compare
|
// Compare
|
||||||
if(this.options?.addToCompare) prodEl.querySelector(".idm-products-banner__compare-btn")?.addEventListener("click", this.handleAddToCompare);
|
if(this.options?.addToCompare) prodEl.querySelector(".idm-products-banner__compare-btn")?.addEventListener("click", this.handleAddToCompare);
|
||||||
|
|
||||||
|
// Second image on hover
|
||||||
|
if(this.options?.showSecondImage){
|
||||||
|
const prodIconEl = prodEl.querySelector(".product__icon");
|
||||||
|
if(prodIconEl.querySelector(".product__image.--second")){
|
||||||
|
prodIconEl?.addEventListener("mouseover", this.handleShowSecondImage);
|
||||||
|
prodIconEl?.addEventListener("mouseleave", this.handleHideSecondImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
10
ramka.txt
10
ramka.txt
@@ -9,12 +9,20 @@
|
|||||||
- stary szablon
|
- stary szablon
|
||||||
- cena za kg
|
- cena za kg
|
||||||
- blokowanie dodawania do koszyka jeśli ilość jest maksymalna
|
- blokowanie dodawania do koszyka jeśli ilość jest maksymalna
|
||||||
|
- informacje o producencie albo serri gdzieś nad produktem
|
||||||
|
- czy zapisywać wszystkie hotspoty do jakiegoś app_shop.fn.idmHotspots = {"#idmMainHotspot1": {}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- własne klasy
|
- własne klasy
|
||||||
- aplikacja do zarządania dodatkiem od obiektów hotspot
|
|
||||||
|
|
||||||
Stara ramka
|
Stara ramka
|
||||||
- getProductXML=t
|
- getProductXML=t
|
||||||
- slick
|
- slick
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cos: any[] = []
|
||||||
|
|
||||||
|
cos ?? ''
|
||||||
|
cos?? false
|
||||||
37
style.less
37
style.less
@@ -1,3 +1,7 @@
|
|||||||
|
.idm__hotspot .btn.add_to_basket__link{
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.idm__hotspot .add_to_basket{
|
.idm__hotspot .add_to_basket{
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
@@ -151,7 +155,7 @@
|
|||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* COMPARE */
|
||||||
.idm-products-banner__compare-btn{
|
.idm-products-banner__compare-btn{
|
||||||
.idm-products-banner__compare-icon{
|
.idm-products-banner__compare-icon{
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -173,7 +177,10 @@
|
|||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.idm-products-banner__compare-btn.--success {
|
||||||
|
display: flex;
|
||||||
|
align-items: end;
|
||||||
|
}
|
||||||
|
|
||||||
/* opinions */
|
/* opinions */
|
||||||
.product__opinions{
|
.product__opinions{
|
||||||
@@ -188,3 +195,29 @@
|
|||||||
.product__opinions .icon-star:not(.--active)::before{
|
.product__opinions .icon-star:not(.--active)::before{
|
||||||
content: "\f006";
|
content: "\f006";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* second image */
|
||||||
|
.product__image.--second{
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.product__icon{
|
||||||
|
.product__image{
|
||||||
|
transition: opacity .25s;
|
||||||
|
}
|
||||||
|
.product__image.--second{
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.--toggle-icon:has(.product__image.--second){
|
||||||
|
.product__image.--first{
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.product__image.--second{
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user