src/sap.ui.core/src/jquery.sap.history.js
function detectHashChange(oEvent, bManual){
			//Firefox will decode the hash when it's set to the window.location.hash,
			//so we need to parse the href instead of reading the window.location.hash
			var sHash = (window.location.href.split("#")[1] || "");
			sHash = formatHash(sHash);

			if (bManual || !mSkipHandler[sHash]) {
				aHashChangeBuffer.push(sHash);
			}

			if (!bInProcessing) {
				bInProcessing = true;
				if (aHashChangeBuffer.length > 0) {
					var newHash = aHashChangeBuffer.shift();

					if (mSkipHandler[newHash]) {
						reorganizeHistoryArray(newHash);
						delete mSkipHandler[newHash];
					} else {
						onHashChange(newHash);
					}
					currentHash = newHash;
				}
				bInProcessing = false;
			}
		}
function detectHashChange(oEvent, bManual){
			//Firefox will decode the hash when it's set to the window.location.hash,
			//so we need to parse the href instead of reading the window.location.hash
			var sHash = (window.location.href.split("#")[1] || "");
			sHash = formatHash(sHash);

			if (bManual || !mSkipHandler[sHash]) {
				aHashChangeBuffer.push(sHash);
			}

			if (!bInProcessing) {
				bInProcessing = true;
				if (aHashChangeBuffer.length > 0) {
					var newHash = aHashChangeBuffer.shift();

					if (mSkipHandler[newHash]) {
						reorganizeHistoryArray(newHash);
						delete mSkipHandler[newHash];
					} else {
						onHashChange(newHash);
					}
					currentHash = newHash;
				}
				bInProcessing = false;
			}
		}
function detectHashChange ( oEvent , bManual ) { //Firefox will decode the hash when it's set to the window.location.hash, //so we need to parse the href instead of reading the window.location.hash var sHash = ( window . location . href . split ( "#" ) [ 1 ] || "" ) ; sHash = formatHash ( sHash ) ; if ( bManual || ! mSkipHandler [ sHash ] ) { aHashChangeBuffer . push ( sHash ) ; } if ( ! bInProcessing ) { bInProcessing = true ; if ( aHashChangeBuffer . length > 0 ) { var newHash = aHashChangeBuffer . shift ( ) ; if ( mSkipHandler [ newHash ] ) { reorganizeHistoryArray ( newHash ) ; delete mSkipHandler [ newHash ] ; } else { onHashChange ( newHash ) ; } currentHash = newHash ; } bInProcessing = false ; } }
This function is bound to the window's hashchange event, and it detects the change of the hash.
When history is added by calling the addHistory or addVirtualHistory function, it will not call the real onHashChange function
because changes are already done. Only when a hash is navigated by clicking the back or forward buttons in the browser,
the onHashChange will be called.

@private
This function is bound to the window s hashchange event and it detects the change of the hash . When history is added by calling the addHistory or addVirtualHistory function it will not call the real onHashChange function because changes are already done . Only when a hash is navigated by clicking the back or forward buttons in the browser the onHashChange will be called .