本帖最后由 louiszoom 于 2012-03-06 10:05:01 编辑

解决方案 »

  1.   

    j以下是Js/sisyphus.js
    ( function( $ ) {
    $.sisyphus = function() {
    return Sisyphus.getInstance();
    }; $.fn.sisyphus = function( options ) {
    var sisyphus = Sisyphus.getInstance();
    sisyphus.setOptions( options )
    sisyphus.protect( this );
    return sisyphus;
    };  var browserStorage = {};   browserStorage.isAvailable = function() {
        if ( typeof $.jStorage === "object" ) {
          return true;
        }
        try {
          return localStorage.getItem;
        } catch ( e ) {
            return false;
        }
      }  browserStorage.set = function( key, value ) {
        if ( typeof $.jStorage === "object" ) {
          $.jStorage.set( key, value + "" )
        } else {
          try {
            localStorage.setItem( key, value + "" );
          } catch (e) {
            //QUOTA_EXCEEDED_ERR
          }
        }
      }   browserStorage.get = function( key ) {
        if ( typeof $.jStorage === "object" ) {
          var result = $.jStorage.get( key );
          return result ? result.toString() : result;
        } else {
          return localStorage.getItem( key )
        }
      }   browserStorage.remove = function( key ) {
        if ( typeof $.jStorage === "object" ) {
          $.jStorage.deleteKey( key );
        } else {
          localStorage.removeItem( key );
        }
      } Sisyphus = ( function() {
    var params = {
    instantiated: null,
    started: null
    }; function init () {

    return {
    /**
     * Set plugin initial options
     *
     * @param [Object] options
     *
     * @return void
     */
    setInitialOptions: function ( options ) {
    var defaults = {
    excludeFields: null,
    customKeyPrefix: "",
    timeout: 0,
    autoRelease: true,
    onSave: function() {},
    onRestore: function() {},
    onRelease: function() {}
    };
    this.options = this.options || $.extend( defaults, options );
    this.browserStorage = browserStorage;
    },

    setOptions: function ( options ) {
    this.options = this.options || this.setInitialOptions( options );
    this.options = $.extend( this.options, options );
    }, 


    protect: function( targets ) {
    targets = targets || {};
    var self = this;
    this.targets = this.targets || [];
    this.href = location.hostname + location.pathname + location.search;

    this.targets = $.merge( this.targets, targets );
    this.targets = $.unique( this.targets );
    this.targets = $( this.targets );
    if ( ! this.browserStorage.isAvailable() ) {
    return false;
    }

    self.restoreAllData();
    if ( this.options.autoRelease ) {
    self.bindReleaseData();
    }
    if ( ! params.started ) {
    self.bindSaveData();
    params.started = true;
    }
    },


    bindSaveData: function() {
    var self = this;

    if ( self.options.timeout ) {
    self.saveDataByTimeout();
    }

    self.targets.each( function() {
    var targetFormId = $( this ).attr( "id" );
    var fieldsToProtect = $( this ).find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" );

    fieldsToProtect.each( function() {
    if ( $.inArray( this, self.options.excludeFields ) !== -1 ) {
    // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
    return true;
    }
    var field = $( this );
    var prefix = self.href + targetFormId + field.attr( "name" ) + self.options.customKeyPrefix;
      

  2.   

    if ( field.is( ":text" ) || field.is( "textarea" ) ) {
    if ( ! self.options.timeout ) {
    self.bindSaveDataImmediately( field, prefix );
    }
    } else {
    self.bindSaveDataOnChange( field, prefix );
    }
    } );
    } )
    },


    saveAllData: function() {
    var self = this;
    self.targets.each( function() {
    var targetFormId = $( this ).attr( "id" );
    var fieldsToProtect = $( this ).find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" );

    fieldsToProtect.each( function() {
    if ( $.inArray( this, self.options.excludeFields ) !== -1 ) {
    // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
    return true;
    }
    var field = $( this );
    var prefix = self.href + targetFormId + field.attr( "name" ) + self.options.customKeyPrefix;
    var value = field.val();

    if ( field.is(":checkbox") ) {
    if ( field.attr( "name" ).indexOf( "[" ) != -1 ) {
    value = [];
    $( "[name='" + field.attr( "name" ) +"']:checked" ).each( function() {
    value.push( $( this ).val() );
    } );
    } else {
    value = field.is( ":checked" );
    }
    self.saveToBrowserStorage( prefix, value, false );
    } else if ( field.is( ":radio" ) ) {
    if ( field.is( ":checked" ) ) {
    value = field.val();
    self.saveToBrowserStorage( prefix, value, false );
    }
    } else {
    self.saveToBrowserStorage( prefix, value, false );
    }
    } );
    } );
    if ( $.isFunction( self.options.onSave ) ) {
    self.options.onSave.call();
    }
    },


    restoreAllData: function() {
    var self = this;
    var restored = false;

    self.targets.each( function() {
    var target = $( this );
    var targetFormId = target.attr( "id" );
    var fieldsToProtect = target.find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" );

    fieldsToProtect.each( function() {
    if ( $.inArray( this, self.options.excludeFields ) !== -1 ) {
    // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
    return true;
    }
    var field = $( this );
    var prefix = self.href + targetFormId + field.attr( "name" ) + self.options.customKeyPrefix;
    var resque = self.browserStorage.get( prefix );
    if ( resque ) {
    self.restoreFieldsData( field, resque );
    restored = true;
    }
    } );
    } );

    if ( restored && $.isFunction( self.options.onRestore ) ) {
    self.options.onRestore.call();
    }
    },


    restoreFieldsData: function( field, resque ) {
    if ( field.is( ":checkbox" ) && resque !== "false" && field.attr( "name" ).indexOf( "[" ) === -1 ) {
    field.attr( "checked", "checked" );
    } else if ( field.is( ":radio" ) ) {
    if ( field.val() === resque ) {
    field.attr( "checked", "checked" );
    }
    } else if ( field.attr( "name" ).indexOf( "[" ) === -1 ) {
    field.val( resque ); 
    } else {
    resque = resque.split( "," );
    field.val( resque );
    }
    },


    bindSaveDataImmediately: function( field, prefix ) {
    var self = this;
    if ( $.browser.msie == null ) {
    field.get(0).oninput = function() {
    self.saveToBrowserStorage( prefix, field.val() );
    }
    } else {
    field.get(0).onpropertychange = function() {
    self.saveToBrowserStorage( prefix, field.val() );
    }
    }
    },


    saveToBrowserStorage: function( key, value, fireCallback ) {
    // if fireCallback is undefined it should be true
    fireCallback = fireCallback == null ? true : fireCallback;
    this.browserStorage.set( key, value );
    if ( fireCallback && value !== "" && $.isFunction( this.options.onSave ) ) {
    this.options.onSave.call();
    }
    },


    bindSaveDataOnChange: function( field, prefix ) {
    var self = this;
    field.change( function() {
    self.saveAllData();
    } );
    },

    saveDataByTimeout: function() {
    var self = this;
    var targetForms = self.targets;
    setTimeout( ( function( targetForms ) {
    function timeout() {
    self.saveAllData();
    setTimeout( timeout, self.options.timeout * 1000 );
    }
    return timeout;
    } )( targetForms ), self.options.timeout * 1000 );
    },


    bindReleaseData: function() {
    var self = this;
    self.targets.each( function( i ) {
    var target = $( this );
    var fieldsToProtect = target.find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" );
    var formId = target.attr( "id" );
    $( this ).bind( "submit reset", function() {
    self.releaseData( formId, fieldsToProtect );
    } )
    } )


    }, manuallyReleaseData: function() {
    var self = this;
    self.targets.each( function( i ) {
    var target = $( this );
    var fieldsToProtect = target.find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" );
    var formId = target.attr( "id" );
    self.releaseData( formId, fieldsToProtect );
    } )
    }, releaseData: function( targetFormId, fieldsToProtect ) {
    var released = false;
    var self = this;
    fieldsToProtect.each( function() {
    if ( $.inArray( this, self.options.excludeFields ) !== -1 ) {
    // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
    return true;
    }
    var field = $( this );
    var prefix = self.href + targetFormId + field.attr( "name" ) + self.options.customKeyPrefix;
    self.browserStorage.remove( prefix )
    released = true;
    } );

    if ( released && $.isFunction( self.options.onRelease ) ) {
    self.options.onRelease.call();
    }
    }

    };
    }

    return {
    getInstance: function() {
    if ( ! params.instantiated ) {
    params.instantiated = init();
    params.instantiated.setInitialOptions();
    }
    return params.instantiated; 
    },

    free: function() {
    params = {};
    return null;
    }
    };
    } )();
    } )( jQuery );