Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need to click twice to go back in history (using pushState)

People also ask

Does history pushState reload page?

But this function is not intended to reload the browser. All the function does, is to add (push) a new "state" onto the browser history, so that in future, the user will be able to return to this state that the web-page is now in.

What is the use of history pushState?

In an HTML document, the history. pushState() method adds an entry to the browser's session history stack.

What is the difference between pushState and replaceState?

replaceState() operates exactly like history. pushState() except that replaceState() modifies the current history entry instead of creating a new one. replaceState() is particularly useful when you want to update the state object or URL of the current history entry in response to some user action.


When the popstate event is fired and you loop through the select fields, if the condition $( this ).val() != parameterNames[index].value is satisfied, the current select value will be altered, but will also fire the change event, which, in turn, will call again the function that pushes a new state into the history. That way, if you go back in the history, you will get the same state-object.

Hence, the solution would be check if the popstate event was fired, and if so, do not call history.pushState, but, instead, history.replaceState.

function handleHistoryStates(popstateEventWasFired = false) {
    $(".chosen-select-field").each( function ( index ) {
        parameterNames[index].value = $( this ).val();
    });
    
    if (popstateEventWasFired) {
        history.replaceState(parameterNames, '', newUrl);
    } else {
        history.pushState(parameterNames, '', newUrl);
    }
}

$(".chosen-select-field").chosen().change(handleHistoryStates);


var restoreState = function(event) {
    event = event.originalEvent;
    parameterNames = event.state;
    $(".chosen-select-field").each( function ( index ) {
        if ($( this ).val() != parameterNames[index].value){
            $( this ).val(parameterNames[index].value);
            handleHistoryStates(true);
            $( this ).trigger('chosen:updated');
        }
    });
};

// Bind history events
$(window).bind("popstate",restoreState);

I guess you are Pushing the current state when you reach the state,Instead of that you Push the previous state when u reach current state.. That why when u first press the back button your poping the current state,And u need to pop the previous state and go there ...

let boxes = Array.from(document.getElementsByClassName('box'));

function selectBox(id) {
  boxes.forEach(b => {
    b.classList.toggle('selected', b.id === id);
  });
}

boxes.forEach(b => {
  let id = b.id;
  b.addEventListener('click', e => {
    history.pushState({
      id
    }, `Selected: ${id}`, `./selected=${id}`)
    selectBox(id);
  });
});

window.addEventListener('popstate', e => {
  selectBox(e.state.id);
});

history.replaceState({
  id: null
}, 'Default state', './');
.boxes {
  display: flex;
}

.desc {
  width: 100%;
  display: flex;
  align-items: center;
  padding: 3rem 0;
  justify-content: center;
  font-weight: bold;
}

.box {
  --box-color: black;
  width: 50px;
  height: 50px;
  margin: 20px;
  box-sizing: border-box;
  display: block;
  border-radius: 2px;
  cursor: pointer;
  color: white;
  background-color: var(--box-color);
  border: 5px solid var(--box-color);
  font-size: 14px;
  font-family: sans-serif;
  font-weight: bold;
  text-align: center;
  line-height: 20px;
  transition: all 0.2s ease-out;
}

.box:hover {
  background-color: transparent;
  color: black;
}

.box.selected {
  transform: scale(1.2);
}

#box-1 {
  --box-color: red;
}

#box-2 {
  --box-color: green;
}

#box-3 {
  --box-color: blue;
}

#box-4 {
  --box-color: black;
}
<div class="boxes">
  <div class="box" id="box-1">one</div>
  <div class="box" id="box-2">two</div>
  <div class="box" id="box-3">three</div>
  <div class="box" id="box-4">four</div>
</div>
<div class="desc">
  Click to select Each box and u can navigate back using browser back button
</div>

Check this codepen : https://codepen.io/AmalNandan/pen/VwmrQJM?editors=1100