在调用destroy方法后无法重新初始化插件

时间:2014-07-27 23:43:26

标签: javascript methods jquery-plugins coffeescript

在上一个问题(Can't destroy jQuery plugin)之后,我终于让destroy方法运行良好,但问题是我现在无法再次初始化插件。

我可以通过$('#element').fullscreen()调用插件并使用$('#element').fullscreen('destroy')将其销毁,但是当我调用$('#element').fullscreen()时,它只返回元素并且不会初始化。

(($, window) ->

  'use strict'

  # Create the defaults once
  pluginName = 'fullscreen'
  dataKey    = 'plugin_#{pluginName}'
  defaults =
    reference: window
    offset: 0
    debug: false

  class Plugin
    constructor: ( @element, options ) ->
      @options = $.extend { }, defaults, options
      @init()

    init: ->
      @bind()
      @setHeight()

    bind: ->
      # Trigger on resize

      $(window).on 'debouncedresize', =>
        @log 'Resize event fired'
        @setHeight()

      $(window).on 'orientationchange', =>
        @log 'Orientation changed'
        @setHeight()

      # When scrolling on a touchscreen
      # prevent further resizes due to address bar shrinking
      $(window).on 'touchstart', =>
        @log 'Touch start fired'
        @unbind()

    # Getter
    getHeight: ->
      @log 'Get height from: ', @options.reference
      $( @options.reference ).height()

    # Setter
    setHeight: ->
      # Make sure the offset is a number
      if @options.offset == parseInt( @options.offset )
        offset = @options.offset
      else
        offset = 0

      $( @element ).css
        'min-height' : @getHeight() - offset

      @callback()

    unbind: ->
      @log 'Unbind the debouncedresize, touchstart and orientationchange event handlers'
      $(window).off 'debouncedresize touchstart orientationchange'

    destroy: ->
      @unbind()

      @log 'Remove min-height from: ', @element
      $( @element ).removeAttr 'style'

      return

    callback: ->
      @log 'Callback fired'

      # Check if the callback is a function
      if typeof @options.callback == 'function'
        # Execute the callback and return the origin element as `this`
        @options.callback.call( @element )

    log: ( msg, object ) ->
      if @options.debug
        if !object
          object = ''
        console.log( pluginName + ': ' + msg, object )

  # The plugin itself
  $.fn[pluginName] = ( args... ) ->
    @each ->
      plugin = $.data(@, dataKey)

      # Allow .fullscreen('destroy')
      if typeof args[0] == 'string'
        plugin?[args[0]]?()
      else if !plugin
        $.data(@, dataKey, new Plugin(@, args[0]))

  return $.fn[pluginName]

) jQuery, window

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

您需要$.removeData删除dataKey数据,以便$.data(@, dataKey)再次返回undefined。如果您未手动删除dataKey,则$.data(@, dataKey)将继续返回您的插件实例,else if !plugin将失败。

这样的事情就足够了:

destroy: ->
  @unbind()

  @log 'Remove min-height from: ', @element
  $( @element ).removeAttr 'style'

  $.removeData(@element, dataKey) # <------------ Add this

  return

更新了quick'n'dirty演示:http://jsfiddle.net/ambiguous/568SU/2/

对不起,我上次可能应该想到这个。