MaggiQall, so che hai una risposta, ma ho una soluzione flessibile che potrebbe interessarti o forse a qualcun altro.
La soluzione dipende da jQuery (1.7+) e dall'interfaccia utente jQuery dialog
, ma viene implementata come metodo personalizzato del prototipo Array, non come un plug-in jQuery.
Ecco il metodo Array:
Array.prototype.runDialogSequence = function(dialogCallback, startIndex, endIndex){
startIndex = Math.max(0, startIndex || 0);
endIndex = Math.min(this.length - 1, endIndex || this.length - 1);
var sequenceIndex = 0,
arr = this,
dfrd = $.Deferred().resolve(startIndex);
function makeCloseFn(seqData){
return function(event, ui){
if(seqData.continue_) { seqData.dfrd.resolve(seqData.arrayIndex+1, seqData); } //continue dialog sequence
else { seqData.dfrd.reject(seqData.arrayIndex, seqData); } //break dialog sequence
}
}
$.each(this, function(i){
if(i < startIndex || i > endIndex) { return true; }//continue
dfrd = dfrd.then(function(arrayIndex){
var seqData = {
dfrd: $.Deferred(),
arrayIndex: arrayIndex,
sequenceIndex: ++sequenceIndex,
length: 1 + endIndex - startIndex,
item: arr[arrayIndex],
continue_: false
};
dialogCallback(seqData).on("dialogclose", makeCloseFn(seqData));
return seqData.dfrd.promise();
});
});
return dfrd.promise();
}
Array.runDialogSequence()
si basa su:
- Un modello di dialogo nel corpo del documento, in forma per essere popolato con testo/valori.
- un array di elementi simili (in genere oggetti javascript) contenenti i dati necessari per compilare la finestra di dialogo, in sequenza.
- passando, come primo argomento, una funzione "openDialog" correttamente costruita.
Ecco un esempio funzione "OpenDialog" con commenti esplicativi:
function openDialog(seqData){
/*
seqData is an object with the following properties:
dfrd: A Deferred object associated with the current dialog. Normally resolved by Array.runDialogSequence() to run through the sequence or rejected to break it, but can be resolved/rejected here to force the dialog sequence to continue/break. If resolved, then pass (seqData.arrayIndex+1, seqData), or custom values. If rejected, typically pass (seqData.arrayIndex, seqData).
arrayIndex: The current array index.
sequenceIndex: The current index within the sequence. Normally the same as arrayIndex but Differs when a non-zero startIndex is specified.
length: The full length of the dialog sequence.
item: The current item from the array.
continue_: (false) Set to true to allow the sequence to continue.
*/
var item = seqData.item;
var $d = $("#d");
$d.dialog({
title: 'Dialog (' + seqData.sequenceIndex + ' of ' + seqData.length + ')',
modal: true,
buttons: {
"Continue": function(){
seqData.continue_ = true;//set to true before closing to go to next dialog.
$(this).dialog("close");
},
"Cancel": function(){
$(this).dialog('close');//closing with seqData.continue_ set to its default value false will break the dialog sequence.
}
}
}).find("#message").text(item);//Typically you will do a lot more here to populate the dialog with item data.
return $d;//openDialog() must return a dialog container, jQuery-wrapped.
}
Array.runDialogSequence()
restituisce un jQuery promise
, permettendo azioni personalizzate da eseguire quando la sequenza di dialogo completa (funzione fatto) o è rotto a metà -sequence (fail function).
Qui ci sono un paio di chiamate di esempio:
//Simplest possible
$("#myButton1").click(function(){
myArray.runDialogSequence(openDialog);
});
//Call with custom startIndex and endIndex, and chanined `.then()` to provide custom actions on break/completion.
$("#myButton2").click(function(){
myArray.runDialogSequence(openDialog, 1, 3).then(function(i, seqData){
alert('All dialogs complete - last item = "' + seqData.item + '"');
}, function(i, seqData){
alert('Dialog sequence was broken at item ' + i + ' "' + seqData.item + '"');
});
});
DEMO
Questo è il più vicino ad una soluzione generalizzata come la mia immaginazione consente.
Stai dicendo che non puoi effettivamente usare l'avviso perché non supporta abbastanza opzioni? –
Non è possibile semplicemente sostituire 'alert()' con una modal personalizzata e farlo funzionare allo stesso modo in cui l'avviso è –
'alert's è BTW sincrono. Non sarai in grado di fermare un'esecuzione di una funzione del genere - a meno che non usi le coroutine/['yield'] di JS1.7 (https://developer.mozilla.org/en-US/docs/JavaScript/New_in_JavaScript/1.7#Generators) ma non è molto cross-browser e richiede la definizione di una 'versione' sul tuo tipo di script. Probabilmente dovresti archiviare il 'i' all'interno di un contesto di esecuzione e passarlo a una funzione che esegue un'ulteriore iterazione che richiama il tuo avviso di stile che ancora una volta passa indietro di un' i alla tua funzione iteratore. –