Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 393|回复: 0

jquery.pjax.js bug问题解决集锦

[复制链接]
  • TA的每日心情
    奋斗
    4 天前
  • 签到天数: 802 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726006
    发表于 2021-5-23 08:05:01 | 显示全部楼层 |阅读模式

    jquery.pjax 是一个很好的局部刷新插件,但实际应用过程是还是会有很多小问题,部分问题解决如下:

    1.pjax 局部加载时候,IE 存在缓存问题,很容易理解,pjax是通过jquery的ajax加载局部内容的,默认cache=true,这会导致ie下get数据从缓存中获取,解决办法是设置pjax options的cache=false,这样请求会自动变成如下方式:

      /XXXX?_pjax=%23pjax-container&_=1455092848927

    2.pjax 与 jquery datatables一起使用,浏览器回退或前进的时候导致双表头,原因是浏览器回退或者前进的时候状态内容获取的是cacheMapping的数据,只需要将这个禁用即可解决datatables双表头问题

    3.pjax 与 highcharts一起使用,到是error 16错误,重复定义Highcharts,原因是多次加载了js文件,原因很好理解,解决方式是初始化highchart时候,先delete (Highcharts);

    4.pjax 加载带有<script type="text/javascript" src="xxx.js"></script> javascript inline的时候,存在无法加载的情况。pjax的机制是自动异步加载html内容,然后会自动将script[src]的内容加入到<head>标签最后,但经常会出现问题,这个机制是为了减少js的请求次数,不必每次都加载js,但产生bug的具体原因不明(有知道的请留言)。解决方案:禁止将script[src]的内容拷贝到<head>中,牺牲js缓存,也就是每次加载container都加载一次js,问题解决。

    5.pjax 与 CodeMirror一起使用,导致CodeMirror无法正常加载的情况,解决方法设置一个延迟refresh()。

    var pcEditor = CodeMirror.fromTextArea(document.getElementById('TplCntPc'), codeOpt);
            //bug,fixed by jackchain 20160604
    setTimeout(function () {
        pcEditor.refresh();
    }, 500);

     

    上述几个问题已解决,下面是修改后的jquery.pjax.js

    if ($.support.pjax) {
            $(document).on('click', 'a[data-pjax]', function (event) {
                $.pjax.click(event, { container: '#pjax-container' });
            });
            $(document).on('pjax:end', function () {
                $(".fixed-left-menu li").removeClass("cur");
                $("a[href='" + window.location.pathname + "']").closest("li").addClass("cur");
            });
        }
    /*!
     * Copyright 2012, Chris Wanstrath
     * Released under the MIT License
     * https://github.com/defunkt/jquery-pjax
     */
    
    (function($){
    
    // When called on a container with a selector, fetches the href with
    // ajax into the container or with the data-pjax attribute on the link
    // itself.
    //
    // Tries to make sure the back button and ctrl+click work the way
    // you'd expect.
    //
    // Exported as $.fn.pjax
    //
    // Accepts a jQuery ajax options object that may include these
    // pjax specific options:
    //
    //
    // container - Where to stick the response body. Usually a String selector.
    //             $(container).html(xhr.responseBody)
    //             (default: current jquery context)
    //      push - Whether to pushState the URL. Defaults to true (of course).
    //   replace - Want to use replaceState instead? That's cool.
    //
    // For convenience the second parameter can be either the container or
    // the options object.
    //
    // Returns the jQuery object
    function fnPjax(selector, container, options) {
      var context = this
      return this.on('click.pjax', selector, function(event) {
        var opts = $.extend({}, optionsFor(container, options))
        if (!opts.container)
          opts.container = $(this).attr('data-pjax') || context
        handleClick(event, opts)
      })
    }
    
    // Public: pjax on click handler
    //
    // Exported as $.pjax.click.
    //
    // event   - "click" jQuery.Event
    // options - pjax options
    //
    // Examples
    //
    //   $(document).on('click', 'a', $.pjax.click)
    //   // is the same as
    //   $(document).pjax('a')
    //
    //  $(document).on('click', 'a', function(event) {
    //    var container = $(this).closest('[data-pjax-container]')
    //    $.pjax.click(event, container)
    //  })
    //
    // Returns nothing.
    function handleClick(event, container, options) {
      options = optionsFor(container, options)
    
      var link = event.currentTarget
    
      if (link.tagName.toUpperCase() !== 'A')
        throw "$.fn.pjax or $.pjax.click requires an anchor element"
    
      // Middle click, cmd click, and ctrl click should open
      // links in a new tab as normal.
      if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
        return
    
      // Ignore cross origin links
      if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
        return
    
      // Ignore case when a hash is being tacked on the current URL
      if ( link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location) )
        return
    
      // Ignore event with default prevented
      if (event.isDefaultPrevented())
        return
    
      var defaults = {
        url: link.href,
        container: $(link).attr('data-pjax'),
        target: link
      }
    
      var opts = $.extend({}, defaults, options)
      var clickEvent = $.Event('pjax:click')
      $(link).trigger(clickEvent, [opts])
    
      if (!clickEvent.isDefaultPrevented()) {
        pjax(opts)
        event.preventDefault()
        $(link).trigger('pjax:clicked', [opts])
      }
    }
    
    // Public: pjax on form submit handler
    //
    // Exported as $.pjax.submit
    //
    // event   - "click" jQuery.Event
    // options - pjax options
    //
    // Examples
    //
    //  $(document).on('submit', 'form', function(event) {
    //    var container = $(this).closest('[data-pjax-container]')
    //    $.pjax.submit(event, container)
    //  })
    //
    // Returns nothing.
    function handleSubmit(event, container, options) {
      options = optionsFor(container, options)
    
      var form = event.currentTarget
      var $form = $(form)
    
      if (form.tagName.toUpperCase() !== 'FORM')
        throw "$.pjax.submit requires a form element"
    
      var defaults = {
        type: ($form.attr('method') || 'GET').toUpperCase(),
        url: $form.attr('action'),
        container: $form.attr('data-pjax'),
        target: form
      }
    
      if (defaults.type !== 'GET' && window.FormData !== undefined) {
        defaults.data = new FormData(form);
        defaults.processData = false;
        defaults.contentType = false;
      } else {
        // Can't handle file uploads, exit
        if ($(form).find(':file').length) {
          return;
        }
    
        // Fallback to manually serializing the fields
        defaults.data = $(form).serializeArray();
      }
    
      pjax($.extend({}, defaults, options))
    
      event.preventDefault()
    }
    
    // Loads a URL with ajax, puts the response body inside a container,
    // then pushState()'s the loaded URL.
    //
    // Works just like $.ajax in that it accepts a jQuery ajax
    // settings object (with keys like url, type, data, etc).
    //
    // Accepts these extra keys:
    //
    // container - Where to stick the response body.
    //             $(container).html(xhr.responseBody)
    //      push - Whether to pushState the URL. Defaults to true (of course).
    //   replace - Want to use replaceState instead? That's cool.
    //
    // Use it just like $.ajax:
    //
    //   var xhr = $.pjax({ url: this.href, container: '#main' })
    //   console.log( xhr.readyState )
    //
    // Returns whatever $.ajax returns.
    function pjax(options) {
      options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)
    
      if ($.isFunction(options.url)) {
        options.url = options.url()
      }
    
      var target = options.target
    
      var hash = parseURL(options.url).hash
    
      var context = options.context = findContainerFor(options.container)
    
      // We want the browser to maintain two separate internal caches: one
      // for pjax'd partial page loads and one for normal page loads.
      // Without adding this secret parameter, some browsers will often
      // confuse the two.
      if (!options.data) options.data = {}
      if ($.isArray(options.data)) {
          options.data.push({ name: '_pjax', value: context.selector })
      } else {
        options.data._pjax = context.selector
      }
      //
      function fire(type, args, props) {
        if (!props) props = {}
        props.relatedTarget = target
        var event = $.Event(type, props)
        context.trigger(event, args)
        return !event.isDefaultPrevented()
      }
    
      var timeoutTimer
    
      options.beforeSend = function(xhr, settings) {
        // No timeout for non-GET requests
        // Its not safe to request the resource again with a fallback method.
        if (settings.type !== 'GET') {
          settings.timeout = 0
        }
    
        xhr.setRequestHeader('X-PJAX', 'true')
        xhr.setRequestHeader('X-PJAX-Container', context.selector)
    
        if (!fire('pjax:beforeSend', [xhr, settings]))
          return false
    
        if (settings.timeout > 0) {
          timeoutTimer = setTimeout(function() {
            if (fire('pjax:timeout', [xhr, options]))
              xhr.abort('timeout')
          }, settings.timeout)
    
          // Clear timeout setting so jquerys internal timeout isn't invoked
          settings.timeout = 0
        }
    
        var url = parseURL(settings.url)
        if (hash) url.hash = hash
        options.requestUrl = stripInternalParams(url)
      }
    
      options.complete = function(xhr, textStatus) {
        if (timeoutTimer)
          clearTimeout(timeoutTimer)
    
        fire('pjax:complete', [xhr, textStatus, options])
    
        fire('pjax:end', [xhr, options])
      }
    
      options.error = function(xhr, textStatus, errorThrown) {
        var container = extractContainer("", xhr, options)
    
        var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])
        if (options.type == 'GET' && textStatus !== 'abort' && allowed) {
          locationReplace(container.url)
        }
      }
    
      options.success = function(data, status, xhr) {
        var previousState = pjax.state;
    
        // If $.pjax.defaults.version is a function, invoke it first.
        // Otherwise it can be a static string.
        var currentVersion = (typeof $.pjax.defaults.version === 'function') ?
          $.pjax.defaults.version() :
          $.pjax.defaults.version
    
        var latestVersion = xhr.getResponseHeader('X-PJAX-Version')
    
        var container = extractContainer(data, xhr, options)
    
        var url = parseURL(container.url)
        if (hash) {
          url.hash = hash
          container.url = url.href
        }
    
        // If there is a layout version mismatch, hard load the new url
        if (currentVersion && latestVersion && currentVersion !== latestVersion) {
          locationReplace(container.url)
          return
        }
    
        // If the new response is missing a body, hard load the page
        if (!container.contents) {
          locationReplace(container.url)
          return
        }
    
        pjax.state = {
          id: options.id || uniqueId(),
          url: container.url,
          title: container.title,
          container: context.selector,
          fragment: options.fragment,
          timeout: options.timeout
        }
    
        if (options.push || options.replace) {
          window.history.replaceState(pjax.state, container.title, container.url)
        }
    
        // Only blur the focus if the focused element is within the container.
        var blurFocus = $.contains(options.container, document.activeElement)
    
        // Clear out any focused controls before inserting new page contents.
        if (blurFocus) {
          try {
            document.activeElement.blur()
          } catch (e) { }
        }
    
        if (container.title) document.title = container.title
    
        fire('pjax:beforeReplace', [container.contents, options], {
          state: pjax.state,
          previousState: previousState
        })
        context.html(container.contents)
    
        // FF bug: Won't autofocus fields that are inserted via JS.
        // This behavior is incorrect. So if theres no current focus, autofocus
        // the last field.
        //
        // http://www.w3.org/html/wg/drafts/html/master/forms.html
        var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]
        if (autofocusEl && document.activeElement !== autofocusEl) {
          autofocusEl.focus();
        }
        
        executeScriptTags(container.scripts)
    
        var scrollTo = options.scrollTo
    
        // Ensure browser scrolls to the element referenced by the URL anchor
        if (hash) {
          var name = decodeURIComponent(hash.slice(1))
          var target = document.getElementById(name) || document.getElementsByName(name)[0]
          if (target) scrollTo = $(target).offset().top
        }
    
        if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo)
    
        fire('pjax:success', [data, status, xhr, options])
      }
    
    
      // Initialize pjax.state for the initial page load. Assume we're
      // using the container and options of the link we're loading for the
      // back button to the initial page. This ensures good back button
      // behavior.
      if (!pjax.state) {
        pjax.state = {
          id: uniqueId(),
          url: window.location.href,
          title: document.title,
          container: context.selector,
          fragment: options.fragment,
          timeout: options.timeout
        }
        window.history.replaceState(pjax.state, document.title)
      }
    
      // Cancel the current request if we're already pjaxing
      abortXHR(pjax.xhr)
    
      pjax.options = options
      var xhr = pjax.xhr = $.ajax(options)
    
      if (xhr.readyState > 0) {
        if (options.push && !options.replace) {
          // Cache current container element before replacing it
          cachePush(pjax.state.id, cloneContents(context))
    
          window.history.pushState(null, "", options.requestUrl)
        }
    
        fire('pjax:start', [xhr, options])
        fire('pjax:send', [xhr, options])
      }
    
      return pjax.xhr
    }
    
    // Public: Reload current page with pjax.
    //
    // Returns whatever $.pjax returns.
    function pjaxReload(container, options) {
      var defaults = {
        url: window.location.href,
        push: false,
        replace: true,
        scrollTo: false
      }
    
      return pjax($.extend(defaults, optionsFor(container, options)))
    }
    
    // Internal: Hard replace current state with url.
    //
    // Work for around WebKit
    //   https://bugs.webkit.org/show_bug.cgi?id=93506
    //
    // Returns nothing.
    function locationReplace(url) {
      window.history.replaceState(null, "", pjax.state.url)
      window.location.replace(url)
    }
    
    
    var initialPop = true
    var initialURL = window.location.href
    var initialState = window.history.state
    
    // Initialize $.pjax.state if possible
    // Happens when reloading a page and coming forward from a different
    // session history.
    if (initialState && initialState.container) {
      pjax.state = initialState
    }
    
    // Non-webkit browsers don't fire an initial popstate event
    if ('state' in window.history) {
      initialPop = false
    }
    
    // popstate handler takes care of the back and forward buttons
    //
    // You probably shouldn't use pjax on pages with other pushState
    // stuff yet.
    function onPjaxPopstate(event) {
        // Hitting back or forward should override any pending PJAX request.
        if (!initialPop) {
        abortXHR(pjax.xhr)
      }
    
      var previousState = pjax.state
      var state = event.state
      var direction
    
      if (state && state.container) {
        // When coming forward from a separate history session, will get an
        // initial pop with a state we are already at. Skip reloading the current
        // page.
        if (initialPop && initialURL == state.url) return
    
        if (previousState) {
          // If popping back to the same state, just skip.
          // Could be clicking back from hashchange rather than a pushState.
          if (previousState.id === state.id) return
    
          // Since state IDs always increase, we can deduce the navigation direction
          direction = previousState.id < state.id ? 'forward' : 'back'
        }
        //changed by jackchain cancel cache;
        var cache = cacheMapping[state.id] || []
        //console.log(cache);
        var container = $(cache[0] || state.container), contents = cache[1]
        //console.log(container);
        if (container.length) {
          if (previousState) {
            // Cache current container before replacement and inform the
            // cache which direction the history shifted.
            cachePop(direction, previousState.id, cloneContents(container))
          }
    
          var popstateEvent = $.Event('pjax:popstate', {
            state: state,
            direction: direction
          })
          container.trigger(popstateEvent)
    
          var options = {
            id: state.id,
            url: state.url,
            container: container,
            push: false,
            fragment: state.fragment,
            timeout: state.timeout,
            scrollTo: false
          }
    
          if (contents) {
            container.trigger('pjax:start', [null, options])
    
            pjax.state = state
            if (state.title) document.title = state.title
            var beforeReplaceEvent = $.Event('pjax:beforeReplace', {
              state: state,
              previousState: previousState
            })
            container.trigger(beforeReplaceEvent, [contents, options])
            container.html(contents)
    
            container.trigger('pjax:end', [null, options])
          } else {
            pjax(options)
          }
    
          // Force reflow/relayout before the browser tries to restore the
          // scroll position.
          container[0].offsetHeight
        } else {
            locationReplace(location.href)
        }
      }
      initialPop = false
    }
    
    // Fallback version of main pjax function for browsers that don't
    // support pushState.
    //
    // Returns nothing since it retriggers a hard form submission.
    function fallbackPjax(options) {
      var url = $.isFunction(options.url) ? options.url() : options.url,
          method = options.type ? options.type.toUpperCase() : 'GET'
    
      var form = $('<form>', {
        method: method === 'GET' ? 'GET' : 'POST',
        action: url,
        style: 'display:none'
      })
    
      if (method !== 'GET' && method !== 'POST') {
        form.append($('<input>', {
          type: 'hidden',
          name: '_method',
          value: method.toLowerCase()
        }))
      }
    
      var data = options.data
      if (typeof data === 'string') {
        $.each(data.split('&'), function(index, value) {
          var pair = value.split('=')
          form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
        })
      } else if ($.isArray(data)) {
        $.each(data, function(index, value) {
          form.append($('<input>', {type: 'hidden', name: value.name, value: value.value}))
        })
      } else if (typeof data === 'object') {
        var key
        for (key in data)
          form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
      }
    
      $(document.body).append(form)
      form.submit()
    }
    
    // Internal: Abort an XmlHttpRequest if it hasn't been completed,
    // also removing its event handlers.
    function abortXHR(xhr) {
      if ( xhr && xhr.readyState < 4) {
        xhr.onreadystatechange = $.noop
        xhr.abort()
      }
    }
    
    // Internal: Generate unique id for state object.
    //
    // Use a timestamp instead of a counter since ids should still be
    // unique across page loads.
    //
    // Returns Number.
    function uniqueId() {
      return (new Date).getTime()
    }
    
    function cloneContents(container) {
      var cloned = container.clone()
      // Unmark script tags as already being eval'd so they can get executed again
      // when restored from cache. HAXX: Uses jQuery internal method.
      cloned.find('script').each(function(){
        if (!this.src) jQuery._data(this, 'globalEval', false)
      })
      return [container.selector, cloned.contents()]
    }
    
    // Internal: Strip internal query params from parsed URL.
    //
    // Returns sanitized url.href String.
    function stripInternalParams(url) {
      url.search = url.search.replace(/([?&])(_pjax|_)=[^&]*/g, '')
      return url.href.replace(/\?($|#)/, '$1')
    }
    
    // Internal: Parse URL components and returns a Locationish object.
    //
    // url - String URL
    //
    // Returns HTMLAnchorElement that acts like Location.
    function parseURL(url) {
      var a = document.createElement('a')
      a.href = url
      return a
    }
    
    // Internal: Return the `href` component of given URL object with the hash
    // portion removed.
    //
    // location - Location or HTMLAnchorElement
    //
    // Returns String
    function stripHash(location) {
      return location.href.replace(/#.*/, '')
    }
    
    // Internal: Build options Object for arguments.
    //
    // For convenience the first parameter can be either the container or
    // the options object.
    //
    // Examples
    //
    //   optionsFor('#container')
    //   // => {container: '#container'}
    //
    //   optionsFor('#container', {push: true})
    //   // => {container: '#container', push: true}
    //
    //   optionsFor({container: '#container', push: true})
    //   // => {container: '#container', push: true}
    //
    // Returns options Object.
    function optionsFor(container, options) {
      // Both container and options
      if ( container && options )
        options.container = container
    
      // First argument is options Object
      else if ( $.isPlainObject(container) )
        options = container
    
      // Only container
      else
        options = {container: container}
    
      // Find and validate container
      if (options.container)
        options.container = findContainerFor(options.container)
    
      return options
    }
    
    // Internal: Find container element for a variety of inputs.
    //
    // Because we can't persist elements using the history API, we must be
    // able to find a String selector that will consistently find the Element.
    //
    // container - A selector String, jQuery object, or DOM Element.
    //
    // Returns a jQuery object whose context is `document` and has a selector.
    function findContainerFor(container) {
      container = $(container)
    
      if ( !container.length ) {
        throw "no pjax container for " + container.selector
      } else if ( container.selector !== '' && container.context === document ) {
        return container
      } else if ( container.attr('id') ) {
        return $('#' + container.attr('id'))
      } else {
        throw "cant get selector for pjax container!"
      }
    }
    
    // Internal: Filter and find all elements matching the selector.
    //
    // Where $.fn.find only matches descendants, findAll will test all the
    // top level elements in the jQuery object as well.
    //
    // elems    - jQuery object of Elements
    // selector - String selector to match
    //
    // Returns a jQuery object.
    function findAll(elems, selector) {
      return elems.filter(selector).add(elems.find(selector));
    }
    
    function parseHTML(html) {
      return $.parseHTML(html, document, true)
    }
    
    // Internal: Extracts container and metadata from response.
    //
    // 1. Extracts X-PJAX-URL header if set
    // 2. Extracts inline <title> tags
    // 3. Builds response Element and extracts fragment if set
    //
    // data    - String response data
    // xhr     - XHR response
    // options - pjax options Object
    //
    // Returns an Object with url, title, and contents keys.
    function extractContainer(data, xhr, options) {
      var obj = {}, fullDocument = /<html/i.test(data)
    
      // Prefer X-PJAX-URL header if it was set, otherwise fallback to
      // using the original requested url.
      var serverUrl = xhr.getResponseHeader('X-PJAX-URL')
      obj.url = serverUrl ? stripInternalParams(parseURL(serverUrl)) : options.requestUrl
    
      // Attempt to parse response html into elements
      if (fullDocument) {
        var $head = $(parseHTML(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]))
        var $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]))
      } else {
        var $head = $body = $(parseHTML(data))
      }
    
      // If response data is empty, return fast
      if ($body.length === 0)
        return obj
    
      // If there's a <title> tag in the header, use it as
      // the page's title.
      obj.title = findAll($head, 'title').last().text()
    
      if (options.fragment) {
        // If they specified a fragment, look for it in the response
        // and pull it out.
        if (options.fragment === 'body') {
          var $fragment = $body
        } else {
          var $fragment = findAll($body, options.fragment).first()
        }
    
        if ($fragment.length) {
          obj.contents = options.fragment === 'body' ? $fragment : $fragment.contents()
    
          // If there's no title, look for data-title and title attributes
          // on the fragment
          if (!obj.title)
            obj.title = $fragment.attr('title') || $fragment.data('title')
        }
    
      } else if (!fullDocument) {
        obj.contents = $body
      }
    
      // Clean up any <title> tags
      if (obj.contents) {
        // Remove any parent title elements
        obj.contents = obj.contents.not(function() { return $(this).is('title') })
    
        // Then scrub any titles from their descendants
        obj.contents.find('title').remove()
    
          // Gather all script[src] elements
        //console.log(obj.contents);
        //obj.scripts = findAll(obj.contents, 'script[src]').remove()
        //console.log(obj.contents);
        //console.log(obj.scripts);
        //obj.contents = obj.contents.not(obj.scripts)
        //console.log(obj.contents);
      }
    
      // Trim any whitespace off the title
      if (obj.title) obj.title = $.trim(obj.title)
    
      return obj
    }
    
    // Load an execute scripts using standard script request.
    //
    // Avoids jQuery's traditional $.getScript which does a XHR request and
    // globalEval.
    //
    // scripts - jQuery object of script Elements
    //
    // Returns nothing.
    function executeScriptTags(scripts) {
      if (!scripts) return
    
      var existingScripts = $('script[src]')
      scripts.each(function() {
          var src = this.src;
        var matchedScripts = existingScripts.filter(function() {
          return this.src === src
        })
        if (matchedScripts.length) return
    
        var script = document.createElement('script')
        var type = $(this).attr('type')
        if (type) script.type = type
        script.src = $(this).attr('src')
        document.head.appendChild(script)
      })
    }
    
    // Internal: History DOM caching class.
    var cacheMapping      = {}
    var cacheForwardStack = []
    var cacheBackStack    = []
    
    // Push previous state id and container contents into the history
    // cache. Should be called in conjunction with `pushState` to save the
    // previous container contents.
    //
    // id    - State ID Number
    // value - DOM Element to cache
    //
    // Returns nothing.
    function cachePush(id, value) {
      cacheMapping[id] = value
      cacheBackStack.push(id)
    
      // Remove all entries in forward history stack after pushing a new page.
      trimCacheStack(cacheForwardStack, 0)
    
      // Trim back history stack to max cache length.
      trimCacheStack(cacheBackStack, pjax.defaults.maxCacheLength)
    }
    
    // Shifts cache from directional history cache. Should be
    // called on `popstate` with the previous state id and container
    // contents.
    //
    // direction - "forward" or "back" String
    // id        - State ID Number
    // value     - DOM Element to cache
    //
    // Returns nothing.
    function cachePop(direction, id, value) {
      var pushStack, popStack
      cacheMapping[id] = value
    
      if (direction === 'forward') {
        pushStack = cacheBackStack
        popStack  = cacheForwardStack
      } else {
        pushStack = cacheForwardStack
        popStack  = cacheBackStack
      }
    
      pushStack.push(id)
      if (id = popStack.pop())
        delete cacheMapping[id]
    
      // Trim whichever stack we just pushed to to max cache length.
      trimCacheStack(pushStack, pjax.defaults.maxCacheLength)
    }
    
    // Trim a cache stack (either cacheBackStack or cacheForwardStack) to be no
    // longer than the specified length, deleting cached DOM elements as necessary.
    //
    // stack  - Array of state IDs
    // length - Maximum length to trim to
    //
    // Returns nothing.
    function trimCacheStack(stack, length) {
      while (stack.length > length)
        delete cacheMapping[stack.shift()]
    }
    
    // Public: Find version identifier for the initial page load.
    //
    // Returns String version or undefined.
    function findVersion() {
      return $('meta').filter(function() {
        var name = $(this).attr('http-equiv')
        return name && name.toUpperCase() === 'X-PJAX-VERSION'
      }).attr('content')
    }
    
    // Install pjax functions on $.pjax to enable pushState behavior.
    //
    // Does nothing if already enabled.
    //
    // Examples
    //
    //     $.pjax.enable()
    //
    // Returns nothing.
    function enable() {
      $.fn.pjax = fnPjax
      $.pjax = pjax
      $.pjax.enable = $.noop
      $.pjax.disable = disable
      $.pjax.click = handleClick
      $.pjax.submit = handleSubmit
      $.pjax.reload = pjaxReload
      $.pjax.defaults = {
        timeout: 650,
        push: true,
        replace: false,
        type: 'GET',
        dataType: 'html',
        scrollTo: 0,
        maxCacheLength: 0,
        cache:false,//changed by jackchain fire IE cache bug
        version: findVersion
      }
      $(window).on('popstate.pjax', onPjaxPopstate)
    }
    
    // Disable pushState behavior.
    //
    // This is the case when a browser doesn't support pushState. It is
    // sometimes useful to disable pushState for debugging on a modern
    // browser.
    //
    // Examples
    //
    //     $.pjax.disable()
    //
    // Returns nothing.
    function disable() {
      $.fn.pjax = function() { return this }
      $.pjax = fallbackPjax
      $.pjax.enable = enable
      $.pjax.disable = $.noop
      $.pjax.click = $.noop
      $.pjax.submit = $.noop
      $.pjax.reload = function() { window.location.reload() }
    
      $(window).off('popstate.pjax', onPjaxPopstate)
    }
    
    
    // Add the state property to jQuery's event object so we can use it in
    // $(window).bind('popstate')
    if ( $.inArray('state', $.event.props) < 0 )
      $.event.props.push('state')
    
    // Is pjax supported by this browser?
    $.support.pjax =
      window.history && window.history.pushState && window.history.replaceState &&
      // pushState isn't reliable on iOS until 5.
      !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/)
    
    $.support.pjax ? enable() : disable()
    
    })(jQuery);

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-11-15 14:44 , Processed in 0.066649 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表