Problem Description:

When listening to popState events under android wechat version 7.0.4 to 7.0.8, when clicking the physical key to return, the browser will force the page to refresh, which will affect some events defined in POPState due to refresh, such as the pop-up window and flash back phenomenon.

The solution

  • inpopstateThe use oflocalStorage.setItemWhen the page is refreshedlocalStorage.getItemCan determine whether the physical key (i.e. the back button) is returned.
  • This method is compatible with the version number in question. It can also be compatible with the return event of other versions of ios or Android.
var wxPopState = (function() {
	// The wechat version number that the browser forces to refresh when you return
	var problemVersions = ['7.0.4'.'7.0.5'.'7.0.6'.'7.0.7'.'7.0.8'];
	// Set the cache key
	var setItemKeyName = '_wx_popstate';
	// Check whether the current version is matched
	varisProblemVersion = !! ~problemVersions.indexOf(getWxVersion()) && isAndroid();// Return the refreshed callback after processing, i.e. equivalent to the event defined in popState
	var callback = null;

	// Get the wechat version number
	function getWxVersion() {
		return navigator.userAgent.match(/MicroMessenger\/(\d+\.\d+\.\d+)[\.\s]? /) [1];
	}
	// Whether android
    function isAndroid() {
        return /android/i.test(navigator.userAgent)
    }

	// push the history stack
	function pushState() {
		var state = {
			title: "".url: "#"
		};
		window.history.pushState(state, state.title, state.url);
	}

	return {
		register: function(options) {
			var needPushState = options.needPushState;
			callback = options.callback;
			if(! callback) {return
			}
			if (needPushState) {
				pushState();
			}
			// The value of setItemKeyName can be used to determine whether the key is returned.
			// If the value is present, the events defined in the back are executed, and the return events and push history stack are no longer registered.
			// If the value does not exist, the action that needs to be set when returned will be registered.
			if (localStorage.getItem(setItemKeyName)) {
				this.popstateEven();
				var that = this;
				setTimeout(function () {
				    // Since the page will be refreshed on return, the history stack will be incremented by 1, so we need to subtract 1
					that.popState()
				}, 0)
				return
			}
			window.addEventListener('popstate'.function() {
				// Handle the problem version
				if (isProblemVersion) {
					// This step is very important in order to determine whether the key is returned
					localStorage.setItem(setItemKeyName, '1');
					// The purpose of this step is to refresh the above problematic versions when they return
					// To ensure that it must be refreshed, consider setting the following methods
					window.location.reload();
					return
				}
				// The non-problem version will have normal registration logiccallback && callback(); })},popState: function() {
			window.history.go(- 1);
		},
		popstateEven: function() {
			if(! isProblemVersion) {return
			}
			// A callback function defined in register will be executed for physical returns in previous versions
			callback && callback();
			localStorage.setItem(setItemKeyName, ' '); }}}) (); wxPopState.register({needPushState: true.// Whether to push the history stack. If this operation already exists on the page, ignore this parameter
	callback: function() {
		// do something}});Copy the code

Participating Contributor: Zeifenbing

The resources

  • Android wechat V7.0.4, popState triggered the page will refresh