차근차근/JAVA Script

ajax뒤로가기 시 이전 데이터 유지

예쁜꽃이피었으면 2023. 9. 5. 13:45

 

지금 개발한 페이지가 게시판 목록인데 '더보기' 버튼을 눌러서 밑으로 계속 목록을 붙여가는 형식이다.

'더보기'나 검색 시 화면이 새로고침되어서는 안된다고 해서 ajax로 작성을 했다.

문제는 상세페이지 혹은 다른 연관 페이지로 이동 후 뒤로가기버튼을 누르거나.

목록가기 버튼을 눌렀을 때 이전의 상태를 그대로 보여줘야 한다고 한다.

 

비동기인데..뒤로가기 했을 때 당연히 이전의 값이 없는게 맞지 라고 생각했지만..

사용자의 생각은 다른가보다..

 

생각해보니 내가 모든 페이지로 ajax를 통해 작성해본 적이 없었다.

어떻게 구현을 할까..방법을 찾는 중이다.

 

일단 급한대로 목록에서 페이지 이동 할 때

세션 스토리지에 현재의 상태값을 저장하고

다시 목록에 돌아왔을 때 그 상태값이 있으면 다시 조회하도록 했다.

목록 조회 후 마지막 위치로 페이지 이동이 되도록 작성했다.

 

약간의 딜레이가 있는데...역시나 말이 나왔다.

 

그래서 다른 방법을 생각 중이다... 

https://lts0606.tistory.com/620
https://blog.iramine.com/entry/Ajax%EB%A1%9C-%EA%B5%AC%ED%98%84%EB%90%9C-%ED%8E%98%EC%9D%B4%EC%A7%80%EB%84%A4%EC%9D%B4%EC%85%98%EC%9D%98-%EB%92%A4%EB%A1%9C%EA%B0%80%EA%B8%B0-%EC%9D%B4%EC%8A%88
https://kaling88.tistory.com/8
https://kingofbackend.tistory.com/178
https://kwangsunny.tistory.com/28
https://naly3512.tistory.com/2623
https://blog.outsider.ne.kr/1276
https://solbel.tistory.com/2083

 

더보기가 아니고 페이징 처리되어있다면 마지막 페이지를 어떤 방식으로든 기억했다가 다시 조회하면 될 것 같다.


1차 작성 중

 

window.history의 내용은 개발자도구 열고 콘솔에 window.history치면 확인할 수 있다.

더보기
var listHtml = "";//초기화되는 시점..생각해봐야할듯 뒤로 왔다가 다른 상세페이지 갔다가 다시 뒤로왔다가..?
var nextbtn = "";
var sharebtn = ""; 



$(document).ready(function(){

	
	//20230905
	if(location.hash){//##이있냐 == 뒤로가기인가
		var data = history.state;
		
		if(data){
			//history.state안에 필요한 것들 저장하고 불러와서 바로 뿌려주기
			document.getElementById("listTotal1").innerHTML = data.listTotal;
			document.getElementById("listTotal2").innerHTML = "전체 "+data.listTotal+"개";
			$(data.list).appendTo($('#List'));
            listHtml = data.list; //더보기 버튼을 누르고 상세갔다가 다시 뒤로가기했을 때 이전 화면 보여주기 위해
			document.getElementById("btnMoreList").innerHTML = data.nextbtn;
			document.getElementById("snsArea").innerHTML = data.sharebtn;
			
			//마지막 위치로 이동
			var scrollPosition = document.querySelector('#'+data.focus).offsetTop; 
			$('html, body').animate({scrollTop:scrollPosition},0);
		}
	}else{
		//목록 조회 (뒤로가기가 아닌 경우)
		fn_getList();
	}
	
})


function fn_getList(){
	
	//목록 조회 조건 생성..
	//목록 조회
		
	$.ajax({
	...
		success : function(Data){
		...
			//html생성 시작
			for(var i = 0; i < resultList.length; i++ ){
				...
				$(innerHTMLText).appendTo($('#List'));
				...
				//20230905 다시 보여줄 html저장
				listHtml += innerHTMLText; 
				...
				//20230905 더보기 버튼 필요하면 저장
				nextbtn = innerHTMLText_btnMoreList;
				...
				//20230905 sns공유 버튼 필요하면 저장
				sharebtn = innerHTMLText_pickbooksns;
			
			
				//20230905 ★다시 왔을 때 필요한 것들 저장 
				history.replaceState({list : listHtml ,listTotal : listTotal, nextbtn : nextbtn , sharebtn : sharebtn , focus : focus},'','list##');
						
			}
		
		}
	
	});

}

 

 

History.replaceState() https://developer.mozilla.org/ko/docs/Web/API/History/replaceState

History.replaceState() 메서드는 현재 history를 수정해 메소드의 매개 변수에 전달 된 stateObj, title, URL로 대체합니다. 이 방법은 특히 일부 유저의 동작에 대한 응답으로 history 객체의 상태나 현재 history의 URL을 업데이트하려는 경우에 유용합니다.

history.replaceState(stateObj, title[, url])

Parameters

stateObj

state 객체는 replaceState에 전달된 history 항목과 연관된 JavaScript 객체입니다. state object는 null일 수 있습니다.

title

나중에는 사용할 수도 있지만, 대부분의 브라우저는 현재 이 파라미터를 무시하고 있습니다. 이 부분에 빈 String을 전달하면 나중에 메소드가 변화하더라도 안전합니다. 또는, state에 짧은 title을 전달할 수도 있습니다.

url Optional

history 항목의 URL 입니다. 새 URL은 현재 URL과 출처가 동일해야(same origin)합니다. 그렇지 않으면 replaceState에서 예외가 발생합니다.

예제

http://www.mozilla.org/ 에서 아래 JavaScript를 실행한다고 가정합시다:

JSCopy to Clipboard

const stateObj = { foo: "bar" };
history.pushState(stateObj, "", "bar.html");

위 두 줄에 대한 설명은 Working with the History API (en-US) 문서의 Example of pushState() method (en-US)에서 확인할 수 있습니다. 그 다음, http://www.mozilla.org/bar.html 에서 아래와 같은 JavaScript를 실행한다고 가정해보세요:

JSCopy to Clipboard

history.replaceState(stateObj, "", "bar2.html");

이렇게하면 URL 표시줄에 http://www.mozilla.org/bar2.html 이라고 표시되지만, 브라우저가 bar2.html 을 로드하거나 bar2.html파일이 있는지 확인하지는 않습니다.

이제 사용자가 http://www.microsoft.com 으로 이동한 다음, 뒤로가기 버튼을 누른다고 가정해봅시다. 이 때, URL 표시줄에는 http://www.mozilla.org/bar2.html 이 표시됩니다. 사용자가 다시 뒤로가기 버튼을 누르면, URL 표시줄에는 http://www.mozilla.org/foo.html 이 표시되고, bar.html은 완전히 무시되어 표시되지 않습니다.


https://developer.mozilla.org/ko/docs/Web/API/History

 

History - Web API | MDN

History 인터페이스는 브라우저의 세션 기록, 즉 현재 페이지를 불러온 탭 또는 프레임의 방문 기록을 조작할 수 있는 방법을 제공합니다.

developer.mozilla.org


[목록 js - 더보기 버튼을 통해 새로운 페이지를 아래 계속 붙여넣기 하는 형태의 게시판]

var listHtml = "";//초기화되는 시점..생각해봐야할듯 뒤로 왔다가 다른 상세페이지 갔다가 다시 뒤로왔다가..?
var nextbtn = "";
var sharebtn = ""; 



$(document).ready(function(){

	
	//20230905
	if(location.hash){//##이있냐 == 뒤로가기인가
		var data = history.state;
		
		if(data){
			//history.state안에 필요한 것들 저장하고 불러와서 바로 뿌려주기
			document.getElementById("listTotal1").innerHTML = data.listTotal;
			document.getElementById("listTotal2").innerHTML = "전체 "+data.listTotal+"개";
			$(data.list).appendTo($('#List'));
			document.getElementById("btnMoreList").innerHTML = data.nextbtn;
			document.getElementById("snsArea").innerHTML = data.sharebtn;
			
			//마지막 위치로 이동
			//var scrollPosition = document.querySelector('#'+data.focus).offsetTop; 
			//$('html, body').animate({scrollTop:scrollPosition},0);
		}
	}else{
		//목록 조회 (뒤로가기가 아닌 경우)
		fn_getList();
	}
	
})


function fn_getList(){
	
	//목록 조회 조건 생성..
	//목록 조회
		
	$.ajax({
	...
		success : function(Data){
		...
			//html생성 시작
			for(var i = 0; i < resultList.length; i++ ){
				...
				$(innerHTMLText).appendTo($('#List'));
				...
				//20230905 다시 보여줄 html저장
				listHtml += innerHTMLText; 
				...
				//20230905 더보기 버튼 필요하면 저장
				nextbtn = innerHTMLText_btnMoreList;
				...
				//20230905 sns공유 버튼 필요하면 저장
				sharebtn = innerHTMLText_pickbooksns;
			
			
				//20230905 ★다시 왔을 때 필요한 것들 저장 
				//history.replaceState({list : listHtml ,listTotal : listTotal, nextbtn : nextbtn , sharebtn : sharebtn , focus : focus},'','list##');
				history.replaceState({list : listHtml ,listTotal : listTotal, nextbtn : nextbtn , sharebtn : sharebtn},'','list##');
				history.scrollRestoration = "auto";
						
			}
		
		}
	
	});

}

[상세 js - 해당 게시글의 상세 정보를 보여주는 영역이 있고, 그 아래 이전 페이지의 목록을 뿌려주는 부분이 있음]

- 뒤로가기 버튼을 history.back(); / history.go(-1); 로 만 해두면 상세페이지 내에서 다른 상세페이지도 이동 후에 목록가기 버튼을 눌렀을 때 이전 상세페이지가 보이기 때문에 따로 처리 필요. 방법이 떠오르지 않아서.. 상세페이지에서 상세페이지로 이동하는 경우 세션 스토리지에 횟수 저장하고. 목록가기 버튼 눌렀을 때 history.go(-이동횟수);해서 목록으로 보냄.

function fn_Detail(seq){
	
	//상세페이지에서 상세페이지로 몇번 이동했는지 카운트
	var DetailMoveCnt = sessionStorage.getItem("DetailMoveCnt") == null ? '1' : sessionStorage.getItem("DeatilMoveCnt");
	DetailMoveCnt = parseInt(DetailMoveCnt) + 1;
	sessionStorage.setItem("DetailMoveCnt", DetailMoveCnt);
	
	location.href='../detail/'+seq;
//	location.replace(''../detail/'+seq);
}


function fn_goList(){
	...
	
	//20230906 
	var DetailMoveCnt = sessionStorage.getItem("DetailMoveCnt");
	DetailMoveCnt = DetailMoveCnt * -1 ;
	
	history.go(DetailMoveCnt);
	
	...
}

일단 이렇게 처리했고..

 


(20230914)

문제점 발견.

상세페이지 하단연관 목록에서 다시 상세로 이동하다가

뒤로가기를 눌렀을 때

DetailMoveCnt와...실제 history.go();할 횟수가 일치하지 않는다.

뒤로가기를 감지해서 DetailMoveCnt의 수를 내가 하나씨기 줄여야 할까..

이게 맞나..

 

 

https://velog.io/@jinyoung234/2.-React-%EB%92%A4%EB%A1%9C%EA%B0%80%EA%B8%B0-%EB%A7%89%EA%B8%B0-%EB%B0%8F-%EC%83%88%EB%A1%9C%EA%B3%A0%EC%B9%A8-%EC%95%8C%EB%A6%BC-%EB%9D%84%EC%9A%B0%EA%B8%B0-%EA%B5%AC%ED%98%84

 

React - 뒤로가기 막기 및 새로고침 알림 띄우기 구현(popstate, beforeunload 이벤트)

🚫 뒤로가기 막기 > History.pushState() 브라우저의 세션 기록 스택에 상태를 추가 매개변수 state 새로운 세션 기록 항목에 연결할 상태 객체, 사용자가 새로운 상태로 이동할 때마다 popstate 이벤트

velog.io

https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event

 

Window: popstate event - Web APIs | MDN

The popstate event of the Window interface is fired when the active history entry changes while the user navigates the session history. It changes the current history entry to that of the last page the user visited or, if history.pushState() has been used

developer.mozilla.org

 

 

https://velog.io/@bclef25/%EC%9B%B9%EC%97%90%EC%84%9C-%EB%92%A4%EB%A1%9C%EA%B0%80%EA%B8%B0%EB%A5%BC-%EB%A7%89%EA%B3%A0-%EB%AA%A8%EB%8B%AC%EC%9D%84-%ED%81%B4%EB%A1%9C%EC%A6%88-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0-%EC%9C%84%ED%95%9C-%EB%B0%A9%EB%B2%95

 

웹에서 뒤로가기를 막고 모달을 클로즈 처리하기 위한 방법

같은 document에 관한 두개의 히스토리 엔트리에 변화가 일어날 때마다, popstate event가 window 객체에 붙게 된다. 만약 활성화된 엔트리가 history.pushState() 메서드나 history.replaceState() 메서드에 의해 생

velog.io

 

 

 

https://dirtycoders.net/jabaseukeuribteu-dwirogagi-ibenteu-gamjihagi-yejewa-eungyong/

 

자바스크립트 뒤로가기 이벤트 감지하기: 예제와 응용

서론 뒤로가기 버튼은 웹사이트에서 중요한 역할을 합니다. 이 기능을 제대로 활용하면 사용자 경험을 크게 향상시킬 수 있습니다. 이 글에서는 자바스크립트를 사용하여 뒤로가기 이벤트를 어

dirtycoders.net

 

https://gurtn.tistory.com/192

 

[JS] 뒤로가기 막기, 뒤로가기(이전페이지) 링크 만들기

사용자가 방문한 모든 URL을 포함하는 객체로는 history라는 JavaScript 객체가 존재합니다. 뒤로가기 링크 제작 history.back(); // 이전페이지로 이동 History 객체에는 사용자가 방문한 모든 URL을 스택 방

gurtn.tistory.com

https://www.w3schools.com/js/js_window_history.asp

 

JavaScript Window History

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

- 일단 뒤로가기 이벤트 감지가..됐다 안됐다 함.

뒤로가기 이벤트가 감지되면 DetailMoveCnt -1 해주면 금방 해결될거라고 생각했는데..

 

더 생각해봐야 함..

반응형