Costruire un monitor di prezzo e disponibilita con MutationObserver
Vuoi quell'articolo, ma solo al prezzo giusto — o vuoi sapere nel momento in cui un prodotto esaurito torna disponibile. Aggiornare la scheda tutto il giorno non e un modo di vivere. Questo articolo costruisce un monitor di prezzo e disponibilita con una regola JS di JustZix: un MutationObserver osserva l'elemento rilevante, confronta il valore e ti avvisa quando la tua condizione e soddisfatta.
Come funziona il monitor
Il piano ha quattro parti, e ognuna corrisponde a una sezione qui sotto:
- Scegli un selettore stabile per l'elemento di prezzo o disponibilita.
- Collega un
MutationObservercosi reagisci ai cambiamenti senza polling. - Analizza il testo trasformandolo in un numero o booleano confrontabile.
- Avvisa te stesso — un banner sulla pagina o una notifica di sistema — e ricorda l'ultimo valore.
Tutto gira lato client nella scheda. Tieni aperta la pagina del prodotto (una scheda fissata e ideale) e la regola fa il monitoraggio.
Scegliere un selettore stabile
Il monitor e affidabile solo quanto il suo selettore. Apri i DevTools, pannello Elements, e trova l'elemento che contiene il prezzo. Preferisci, in quest'ordine:
- Un aggancio semantico:
[itemprop="price"],[data-price],[data-testid="product-price"]. Cambiano raramente. - Un ID stabile:
#priceblock_ourprice,#product-price. - Una classe significativa:
.price-now,.product__price.
Evita le classi con hash (.css-1a2b3c) e le lunghe catene di discendenti — si rompono al prossimo deploy. Molti negozi incorporano anche dati strutturati in un blocco <script type="application/ld+json">; se il DOM visibile e disordinato, analizzare quel JSON e spesso la via piu stabile.
Impostare il MutationObserver
Un MutationObserver esegue una callback ogni volta che il sottoalbero osservato cambia — niente polling, niente CPU sprecata. Osserva il nodo del prezzo per cambiamenti di testo e di figli:
const SELECTOR = '[itemprop="price"]'; // your stable selector
const priceEl = document.querySelector(SELECTOR);
if (!priceEl) {
console.warn('[watcher] price element not found - check the selector');
} else {
const observer = new MutationObserver(() => checkPrice(priceEl));
observer.observe(priceEl, {
childList: true,
subtree: true,
characterData: true
});
// Also check once on load - the price may already be a deal
checkPrice(priceEl);
}
I negozi single-page-app a volte sostituiscono l'intero nodo del prezzo all'aggiornamento. Se il tuo observer ammutolisce, osserva un contenitore genitore stabile con subtree: true e ri-interroga il prezzo dentro la callback.
Analizzare il prezzo in un numero
Il testo del prezzo e disordinato: simboli di valuta, separatori delle migliaia, virgole decimali. Riducilo a un numero pulito prima di confrontare:
// Turn "$1,299.00" or "1 299,00 zl" into 1299
function parsePrice(text) {
if (!text) return NaN;
// Keep digits, dot and comma; drop everything else
let s = text.replace(/[^0-9.,]/g, '');
// If comma is the decimal separator, normalise it
if (/,\d{2}$/.test(s)) s = s.replace(/\./g, '').replace(',', '.');
else s = s.replace(/,/g, '');
return parseFloat(s);
}
Confrontare con una soglia
Ora la logica di decisione. Confronta il prezzo analizzato con il tuo obiettivo e avvisa solo quando lo attraversa davvero — e solo una volta per discesa, cosi non vieni sommerso a ogni minima mutazione del DOM:
const TARGET = 999; // alert when price drops to/below this
const STORAGE_KEY = 'jz-watch-' + location.pathname;
function checkPrice(el) {
const price = parsePrice(el.textContent);
if (Number.isNaN(price)) return;
const last = parseFloat(localStorage.getItem(STORAGE_KEY)) || Infinity;
localStorage.setItem(STORAGE_KEY, String(price));
console.log('[watcher] price now', price, '- last', last);
// Fire only when we newly cross the threshold
if (price <= TARGET && last > TARGET) {
notify('Price drop! Now ' + price + ' (target ' + TARGET + ')');
}
}
Monitorare il ritorno della disponibilita
Stesso schema, segnale diverso. Invece di un numero osservi un booleano — il pulsante di acquisto e abilitato, l'etichetta "esaurito" e sparita:
function checkStock() {
const soldOut = document.querySelector('[class*="out-of-stock" i], .sold-out');
const buyBtn = document.querySelector('button[name="add-to-cart"], .add-to-cart');
const inStock = !soldOut && buyBtn && !buyBtn.disabled;
const wasInStock = localStorage.getItem('jz-stock') === 'yes';
localStorage.setItem('jz-stock', inStock ? 'yes' : 'no');
if (inStock && !wasInStock) {
notify('Back in stock! Grab it now.');
}
}
Avvisare te stesso
Un avviso e inutile se non lo vedi. Usa due canali: un banner sulla pagina impossibile da mancare, piu una notifica di sistema per quando la scheda e in secondo piano.
function notify(message) {
// 1. On-page banner - always visible in the tab
let bar = document.getElementById('jz-watch-bar');
if (!bar) {
bar = document.createElement('div');
bar.id = 'jz-watch-bar';
bar.style.cssText =
'position:fixed;top:0;left:0;right:0;z-index:2147483647;' +
'background:#16a34a;color:#fff;font:600 15px/1.4 sans-serif;' +
'padding:12px 16px;text-align:center;';
document.body.appendChild(bar);
}
bar.textContent = 'JZ watcher: ' + message;
// 2. System notification - works when the tab is hidden
if (Notification.permission === 'granted') {
new Notification('JustZix watcher', { body: message });
} else if (Notification.permission !== 'denied') {
Notification.requestPermission();
}
}
Lo z-index di 2147483647 e il massimo intero a 32 bit — garantisce che il banner stia sopra qualsiasi cosa il sito renderizzi. Le notifiche di sistema richiedono un permesso, che il browser concede solo da un gesto dell'utente o da un'origine gia approvata, quindi la prima esecuzione potrebbe limitarsi a richiederlo; il banner ti copre nel frattempo.
Conservare l'ultimo valore visto
Hai visto usare localStorage sopra, e fa un lavoro reale. Sopravvive alle ricariche, cosi il monitor sa se un cambiamento e davvero nuovo. Deduplica anche gli avvisi — confronti con il valore memorizzato e avvisi solo a un attraversamento reale. Indicizzalo per pagina (location.pathname) cosi piu monitor di prodotti possono coesistere senza sovrascriversi a vicenda.
Collegarlo in JustZix
- Crea una regola con il pattern di URL del prodotto esatto, per esempio
https://shop.example.com/product/12345*. - Incolla lo script combinato nella scheda JS — imposta
SELECTOReTARGETper quel prodotto. - Fissa la scheda e lasciala aperta; l'observer reagisce ogni volta che il negozio aggiorna il DOM.
- Vuoi un ricontrollo periodico anche senza cambiamenti del DOM? Aggiungi un
setIntervalche ricarica la pagina ogni pochi minuti.
Vedi anche
- Disattiva i dark pattern — togli la falsa urgenza cosi vedi il prezzo reale.
- Simula le risposte API — testa il tuo monitor contro un finto feed di prezzi.
- Casi d'uso di JustZix per altre idee di automazione.
Smetti di aggiornare quella scheda. Installa JustZix, inserisci lo script del monitor in una regola per prodotto e lascia che sia il browser a dirti il momento in cui il prezzo e giusto.
Valuta questo articolo
Nessuna valutazione — sii il primo.