
Накратко за проекта
Онлайн магазинът Vicious Intent искаше всички цени в лева да показват приблизителна цена в евро точно под тях. Валутният курс трябваше да бъде фиксиран на 1.95583 (BGN към EUR), а скриптът да работи на всички типове страници — продуктови, количка, бърз преглед.
Ключови подобрения
- Фиксиран курс: Не се използва външен API при зареждане, за бързина и стабилност.
- Мощен MutationObserver: Засича динамично добавяне на елементи и инжектира евро цена в реално време.
- Мулти-селекторно покритие: Скриптът обхваща над 9 различни класа за цена, характерни за темата Kalles.
- Автоматично позициониране: Евро цената се добавя точно до лева, без да се нарушава дизайна.
- Минимална визуална намеса: Евро цената е с по-сив шрифт и с 5% по-малък размер, без да доминира визуално.
Използвани технологии
- Vanilla JavaScript – за динамично откриване и вграждане на евро стойностите.
- MutationObserver – за следене на DOM промени и автоматично вграждане в динамично заредени елементи.
- Shopify Liquid + Kalles v2.7.0 – интеграция със съществуващата тема.
Предизвикателства
Темата Kalles използва JavaScript рендериране за части от съдържанието — включително някои ценови елементи, които се появяват само при действие от потребителя (напр. добавяне в количката, quick view). Това прави невъзможно еднократно вграждане на евро цената само при DOMContentLoaded
.
Допълнително предизвикателство беше, че част от елементите се рендерират в сянка (Shadow DOM) или задействат повторно рендериране при mouseover или scroll. Някои елементи, като span.price.dib.mb__5
, визуализираха промяната едва след отваряне на инспектора. Затова внедрихме MutationObserver
с повторно валидиране.
Използван JavaScript код
<script>
document.addEventListener("DOMContentLoaded", function () {
const selectors = [
'span.price.dib.mb__5',
'p#price_ppr.price_range',
'div.cart_price',
'strong._19gi7yt0._19gi7yt12._19gi7yt1a._19gi7yt1l',
'strong._19gi7yt0._19gi7ytk._19gi7ytj._1fragemp5._19gi7yt12._19gi7yt1a._19gi7yt1l.notranslate',
'span._19gi7yt0._19gi7yt12._19gi7yt1a._19gi7yt1g.notranslate',
'.cart_tot_price',
'.totals__subtotal-value',
'.cart__subtotal .money'
];
const rate = 1.95583;
function applyConversions() {
const elements = document.querySelectorAll(selectors.join(','));
elements.forEach((el) => {
if (el.querySelector('.euro-price')) return;
let prices = el.textContent.match(/[\d.,]+/g);
let priceBGN = parseFloat((prices ? prices[prices.length - 1] : '0').replace(',', '.'));
if (!isNaN(priceBGN)) {
let priceEUR = (Math.round((priceBGN / rate) * 100) / 100).toFixed(2);
el.insertAdjacentHTML('beforeend', ` <span class="euro-price" style="display:inline; font-size:0.85em; color:gray;">(${priceEUR} €)</span>`);
}
});
}
applyConversions();
const observer = new MutationObserver(applyConversions);
observer.observe(document.body, { childList: true, subtree: true });
});
</script>
Резултат
Всички визуализирани цени вече показват евро стойност в реално време – включително в количката, quick view и продуктовите страници. Дизайнът остана непроменен, а добавянето не влияе на скоростта на сайта.
Ограничения
Въпреки прецизната имплементация, трябва да се отбележи, че поради естеството на динамичното зареждане на съдържание в Shopify, не всички ценови елементи могат да бъдат обработени на 100%. Например, съдържание, заредено през iframe или в Shadow DOM, не подлежи на стандартна обработка. В такива случаи е възможно евро цената да не се покаже, ако елементът не бъде открит в DOM.
На финала
Благодарение на внимателно изградения JavaScript и адаптацията към темата Kalles, проектът на ViciousIntent постигна желаната функционалност: динамична, точна и визуално ненатрапчива евро цена до всяка стойност в лева. Решението може лесно да се прехвърли в други Shopify магазини с минимални корекции.