ZXing non è progettato per funzionare con AJAX. Invece, funziona aprendo un URL analizzato nel browser predefinito. Il comportamento del browser è principalmente ciò che è responsabile dell'esperienza utente da quel momento in avanti.
Esistono diversi metodi per quanto riguarda questo; sfortunatamente, non esiste un metodo che funzioni per ogni browser.
Alcuni browser, quando li si apre dalla riga di comando, verificheranno se l'URL è già aperto in un'altra scheda e, in caso affermativo, utilizzerà tale scheda anziché una nuova. Ciò causerà un evento "onhashchange" se il collegamento zxing contiene "zxing: // scan /? Ret = mytab.html # {CODE}".
Altri browser non eseguono tale controllo, quindi finiamo con più schede, tutte con lo stesso URL (ad eccezione dell'hash), e nessuna di esse genera l'evento "hashchanged". Per quei browser, è necessario riutilizzare la pagina dalla cache, se possibile (per evitare il traffico di rete su ogni scansione) e modificare il valore localStorage con l'hash. Se il browser è in grado di ascoltare l'evento "storage", possiamo usarlo per attivare il codice.
Il codice seguente funziona con Chrome, l'intrinseco browser Android e Firefox. Potrebbe funzionare con gli altri, ma non ho provato. Un avvertimento di Firefox, tuttavia, è che la finestra dello scanner si chiuderà solo se l'impostazione about: config "dom.allow_scripts_to_close_windows" è impostata su "true".
** Questo è stato modificato per funzionare meglio con più pagine che consentono scansioni e ora è possibile utilizzare hash diversi senza interferire con il codice. **
NUOVA VERSIONE 12/19/16
<!DOCTYPE html>
<HTML>
<HEAD>
<script type="text/javascript">
if(window.location.hash.substr(1,2) == "zx"){
var bc = window.location.hash.substr(3);
localStorage["barcode"] = decodeURI(window.location.hash.substr(3))
window.close();
self.close();
window.location.href = "about:blank";//In case self.close isn't allowed
}
</script>
<SCRIPT type="text/javascript" >
var changingHash = false;
function onbarcode(event){
switch(event.type){
case "hashchange":{
if(changingHash == true){
return;
}
var hash = window.location.hash;
if(hash.substr(0,3) == "#zx"){
hash = window.location.hash.substr(3);
changingHash = true;
window.location.hash = event.oldURL.split("\#")[1] || ""
changingHash = false;
processBarcode(hash);
}
break;
}
case "storage":{
window.focus();
if(event.key == "barcode"){
window.removeEventListener("storage", onbarcode, false);
processBarcode(event.newValue);
}
break;
}
default:{
console.log(event)
break;
}
}
}
window.addEventListener("hashchange", onbarcode, false);
function getScan(){
var href = window.location.href;
var ptr = href.lastIndexOf("#");
if(ptr>0){
href = href.substr(0,ptr);
}
window.addEventListener("storage", onbarcode, false);
setTimeout('window.removeEventListener("storage", onbarcode, false)', 15000);
localStorage.removeItem("barcode");
//window.open (href + "#zx" + new Date().toString());
if(navigator.userAgent.match(/Firefox/i)){
//Used for Firefox. If Chrome uses this, it raises the "hashchanged" event only.
window.location.href = ("zxing://scan/?ret=" + encodeURIComponent(href + "#zx{CODE}"));
}else{
//Used for Chrome. If Firefox uses this, it leaves the scan window open.
window.open ("zxing://scan/?ret=" + encodeURIComponent(href + "#zx{CODE}"));
}
}
function processBarcode(bc){
document.getElementById("scans").innerHTML += "<div>" + bc + "</div>";
//put your code in place of the line above.
}
</SCRIPT>
<META name="viewport" content="width=device-width, initial-scale=1" />
</HEAD>
<BODY>
<INPUT id=barcode type=text >
<INPUT style="width:100px;height:100px" type=button value="Scan" onclick="getScan();">
<div id="scans"></div>
</BODY>
</HTML>
È possibile effettuare una JS file include per il blocco superiore di script e includerlo in tutte le pagine in cui è necessario funzionalità di scansione.
Quindi nel corpo del documento, è possibile impostare un evento da qualche parte per chiamare getZxing(), che chiamerà processBarcode (codice a barre) che si scrive nella pagina. Incluso è un semplice per esempio.
Nota a margine: la prima volta che si esegue zxing dalla pagina, verrà chiesto di scegliere un'app predefinita.Assicurati di aver scelto lo stesso browser da cui stai eseguendo la pagina. Inoltre, se in precedenza hai selezionato un broswer predefinito per zxing e desideri modificare il browser che utilizzi per zxing, dovrai eliminare i valori predefiniti dagli altri browser.
Mille grazie a @sean-owen per il suo duro lavoro e il fantastico prodotto.
UPDATE 12/19/16
Ok, ho fatto una versione leggermente più robusto che funziona bene con Firefox e Chrome. Un paio di cose che ho scoperto:
Chrome utilizzerà l'evento Storage
se lo scanner non è impostato per l'apertura automatica di Chrome e utilizzerà l'evento Hash
dopo che diventa predefinito.
Firefox non potrà mai utilizzare l'evento Hash
, ma apre una finestra in più a meno che non si chiama lo scanner con window.location.href
(Grazie, @Roland)
Ci sono un paio di altre anomalie, ma nessun interruttori affare.
Ho lasciato il prefisso "zx" nell'hash, in modo che il codice potesse delineare tra gli hash dello scanner e gli hash regolari. Se lo lasci lì, non lo noterai nella funzione processBarcode
e gli hash non zx funzioneranno come previsto.
Puoi condividere un campione funzionante? Sarebbe fantastico –
@ Mo-Prog, ho FINALMENTE incluso un esempio funzionante. Ci scusiamo per il ritardo di 10 settimane! Ho anche ottimizzato il codice per prevenire più ascoltatori. – alfadog67
L'utilizzo dell'evento di archiviazione è un'idea geniale, grazie per aver condiviso questo trucco! :) –