← Tutti gli articoli

API e helper

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:

  1. Scegli un selettore stabile per l'elemento di prezzo o disponibilita.
  2. Collega un MutationObserver cosi reagisci ai cambiamenti senza polling.
  3. Analizza il testo trasformandolo in un numero o booleano confrontabile.
  4. 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:

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

  1. Crea una regola con il pattern di URL del prodotto esatto, per esempio https://shop.example.com/product/12345*.
  2. Incolla lo script combinato nella scheda JS — imposta SELECTOR e TARGET per quel prodotto.
  3. Fissa la scheda e lasciala aperta; l'observer reagisce ogni volta che il negozio aggiorna il DOM.
  4. Vuoi un ricontrollo periodico anche senza cambiamenti del DOM? Aggiungi un setInterval che ricarica la pagina ogni pochi minuti.

Vedi anche

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.

Provalo tu stesso

Installa JustZix e incolla qualsiasi snippet di questo articolo. Due minuti da zero a una regola funzionante su tutti i tuoi dispositivi.

Ottieni JustZix

Funzionalità · Come funziona · Esempi · Casi d'uso