728x90

 

#무한스크롤

 

기존 페이징 방식에서 벗어나 최근 떠오르는 페이징 방식이다.

 

특정 개수만큼만 로딩하고 특정 뷰포트를 넘어가면 다음 아이템을 로딩하는 방식으로 

비동기 방식으로 html을 누적 생성해낸다. 

 

최근 다양한 sns에서 적용하고 있는 방식이다. 

기존의 페이지네이션은 끝에 도달하면 다음 동작을 해야 다음 컨텐츠를 확인할 수 있는데 

무한 스크롤은 끝에 도달했다고 인지하기도 전에 이미 다음 컨텐츠를 보여주고 있기 때문에 

컨텐츠가 끝없이 쏟아지고 심리적으로 페이지네이션보다 클라이언트를 더 붙잡아두는 경향이 있다. 

 

IntersectionObserver Interface는 

특정 요소를 observe 하면서 해당 요소가 다른 요소와 교차하게 되는 시점을 감지하는 interface이다. 

이 인터페이스를 활용하면 아이템 뷰포트를 옵서브 대상으로 지정하고

뷰포트가 다음 요소와 교차될 때, 혹은 교차되기 이전에 다음 아이템을 렌더링하여 무한 스크롤을 구현할 수 있다.

 

우리가 할 일은 교차를 감지하였을 때 어떤 동작을 할지 콜백함수를 작성해주는 일이다.  

 

#IntersectionObserver 생성자

 

new IntersectionObserver(callback[, options])

 

 

callback(entries, observer) 

콜백함수는 entries와 observer를 매개변수로 받을 수 있다. 

 

observer는 콜백을 호출한 intersectionObserver 객체이다.

 

#intersectionObserverEntry(배열) Properties 

 

- boundingClientRect

타겟 요소의 사각형 바운드

 

- intersectionRect

타켓의 가시 영역

 

- intersectionRatio

boundingClientRect에서 intersectionRect의 교차 비율로 백분율로 표현한다. 

 

- rootBounds

observer의 root 바운드 

 

- isIntersecting

observer의 root를 교차한 상태인지를 boolean 값으로 반환 

 

- target

교차가 발생한 요소

 

- time

교차 시간

 

 

#options

 

- root

 대상 요소의 조상 element

 root의 바운딩을 감지기의 뷰포트로 사용

 

- rootMargin

 교차 영역 계산시 사용할 바운드에 적용할 오프셋 문자열로

 계산할 바운딩 영역을 증가시키거나 감소시킬 수 있다.

 기본값은  "0px 0px 0px 0px"이다. 
 값을 잘못 설정하면 syntax error가 발생한다. 

 

- threshold

 대상의 가시영역과 바운딩 영역의 교차 비율에 대한 역치

0.0~ 1.0 사이의 숫자 값을 갖는다. 

0.0은 root가 가시영역에 조금이라도 보일 때 대상을 볼 수 있는 것으로 감지하고 

1.0은 root가 가시영역에 온전히 보였을 때 대상을 볼 수 있는 것으로 감지한다. 

 

 

threshold를 0.8로 설정하면 

스크롤을 내리다 타겟요소의 0.8을 넘으면 observer가 콜백함수를 호출한다. 

 

threshold의 범위를 초과하여 설정하면 range error가 발생한다. 

 

 

#메소드

 

- disconnect() 

모든 대상의 주시를 해제 

 

- observe()

 주어진 대상 요소를 주시

 

- takeRecords() 

 모든 주시 대상에 대한 entries를 반환

 

- unobserve()

 특정 대상 요소에 대한 주시를 해제

 

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

 

IntersectionObserver - Web API | MDN

Intersection Observer API (en-US)의 IntersectionObserver 인터페이스는 대상 요소와 상위 요소, 또는 대상 요소와 최상위 문서의 뷰포트가 서로 교차하는 영역이 달라지는 경우 이를 비동기적으로 감지할 수

developer.mozilla.org

 

 

 

 

 #구현 예시

 

const $result =$("#toObserve");
const $end = document.createElement("div");
$end.id = 'product-list-observed';
$result.append($end);

const callback = (entries, observer) => {
	entries.forEach((entry) => {
		if (entry.isIntersecting) {
			firstResult += 20;
			filterDto.firstResult = firstResult;
			api.continueSearchResult(filterDto, observer);
		}
	});
}
const options = {
	root: null, // 뷰포트를 기준으로 타켓의 가시성 검사
	rootMargin: '0px 0px 0px 0px', // 확장 또는 축소 X
	threshold: 1 // 타켓의 가시성 0%일 때 옵저버 실행
};
const observer = new IntersectionObserver(callback, options);
observer.observe($end);
Product

{{name}}

{{totalPrice}}원

{{optionSetDesc}}
{{updateTime}}

 

'Javascript' 카테고리의 다른 글

SPA AJAX Request With JQuery  (0) 2023.09.25
js 모듈 의존성 줄이기  (0) 2023.09.24
AJAX using JQuery  (0) 2023.09.24
JQuery event  (0) 2023.09.23
Javascript this  (0) 2023.09.23
728x90

이전에 만들었던 버전은 핸들바의 script 태그를 이용해 메인 html에 여러 페이지의 템플릿을 숨겨두고 요청에 따라 템플릿을 보여주었는데 이번에는 네비게이터를 만들었다. 

href의 #해시 요청과 button의 클릭 이벤트 발생시 hash를 바꿔주어 hashchange 이벤트가 발생하면 

navigator에서 hash의 url을 확인하고 템플릿을 꺼내고 필요한 AJAX 요청을 한다. 

 

function navigate() {

const hash = window.location.hash;

const path = hash.substring(1);

let html = "";

hash는 #로 시작하므로 지저분한 #을 떼주고 path만 남도록 substring으로 정리해주었다. 

템플릿을 받을 html 변수를 생성

if (path == '/guest_main') {

html = guest_main();

} else if (path == '/guest_list') {

ajaxRequest(GUEST_LIST.method,GUEST_LIST.url,function(responseJsonObject){

html = guest_list(responseJsonObject);

$('#content').html(html);//????

});

}

이런식으로 path를 구분하여 main으로 보낼지 list로 보낼지 결정한다. 

문제는 list의 ajax 요청이다. 

ajax 요청이라하면 요청을 하고 응답을 받는 동안 쓰레드가 계속 돌아야하는데 

ajax 요청의 콜백함수에서 guest_list의 템플릿에 json 데이터를 핸들바로 바인딩하여 완성된 템플릿을 받아 html에 초기화 시킬때까지 기다리게 된다. 

이문제는 추후 promise 객체로 해결한다. 

 

여기서 guest_main, guest_list 함수는 

import { guest_main } from "./template-guest-main.js";

import { guest_write_form } from "./template-guest-write-form.js";

import { guest_list } from "./template-guest-list.js";

import { ajaxRequest } from "./request.js";

import {GUEST_DETAIL,GUEST_MODIFY_ACTION,GUEST_MODIFY_FORM,

GUEST_REMOVE_ACTION,GUEST_LIST,GUEST_WRITE_ACTION} from "./request-url.js";

template을 반환하는 함수를 가진 js 모듈을 import한 것이다.

 

템플릿 함수는 대략 이런 구조를 가진다.

let htmlTemplate = `

<table >

<tbody>

<tr>

<td>번호</td>

<td>제목</td>

<td>이름</td>

<td>날짜</td>

</tr>

{{#each data}}

<tr class="guest_item">

<td>{{guest_no}}</td>

<td>

<a href="#/guest_detail/{{guest_no}}" class="user guest_item_a">{{guest_title}}

</a>

</td>

<td>{{toUpper guest_name}}</td>

<td>{{substring guest_date 0 10}}</td>

</tr>

{{/each}}

</tbody>

</table>`;

let bindTemplate = Handlebars.compile(htmlTemplate);

let resultTemplate = bindTemplate(responseJsonObject);

return resultTemplate;

html 템플릿 텍스트를 Handlebars.compile 하여 만들 bindTemplate 함수에 Ajax 요청에 대한 응답으로 받은 responseJsonObject를 넣어준뒤 완성된 템플릿인 resultTemplate을 만들어반환한다.

 

else if(path.startsWith('/guest_modify_form/')){

const guest_no = path.substring(path.lastIndexOf('/')+1);

ajaxRequest(GUEST_MODIFY_FORM.method,GUEST_MODIFY_FORM.url.replace('@guest_no',guest_no),function(responseJsonObject){

html = guest_modify_form(responseJsonObject);

$('#content').html(html);

})

}

수정폼에선 기존의 데이터를 가져와야하기 때문에 guest_no가 필요하다 

guest_no는 view(detail)에서 가져온다.

<input type="button" data-navigate="/guest_modify_form/{{data.[0].guest_no}}" value="수정" >

view 버튼 중에 수정 버튼은 data-navigate라는 custom attribute를 가지고 있다. 

버튼을 클릭하면 클릭이벤트가 발생하는데 이 클릭이벤트가 발생하면 해쉬체인지 이벤트가 발생하도록 해준다.

$(document).on('click',function(e){

if(e.target.getAttribute('data-navigate')){

window.location.hash=e.target.getAttribute('data-navigate');

}

});

data-navigate의 /guest_modify_form/guest_no 를 가져올수 있게된다.

navigate에서는 여기서 가져온 guest_no로 restController의 guests/guest_no에 필요한 guest_no를 채울수 있게된다.

else if(path.startsWith('/guest_modify_action/')){

const guest_no = path.substring(path.lastIndexOf('/')+1);

데이터 검증 생략

let sendJsonObject = {

guest_no: $('#guest_modify_form [name="guest_no"]').val(),

guest_date: "",

guest_name: $('#guest_modify_form [name="guest_name"]').val(),

guest_email: $('#guest_modify_form [name="guest_email"]').val(),

guest_homepage: $('#guest_modify_form [name="guest_homepage"]').val(),

guest_title: $('#guest_modify_form [name="guest_title"]').val(),

guest_content: $('#guest_modify_form [name="guest_content"]').val()

};

 

ajaxRequest(GUEST_MODIFY_ACTION.method,GUEST_MODIFY_ACTION.url.replace('@guest_no',guest_no),function(responseJsonObject){

if (responseJsonObject.status == 1) {

//쓰기 성공시 HashChange 이벤트 발생

window.location.hash='/guest_detail/'+guest_no;

} else {

alert(responseJsonObject.msg);

}

},sendJsonObject)

}

ajax request가 성공하면 

window.location.hash를 변경해주어 guest_detail 템플릿을 뿌리도록 이벤트를 발생시킨다.

'Javascript' 카테고리의 다른 글

Intersection Observer 무한스크롤 구현하기  (0) 2023.11.24
js 모듈 의존성 줄이기  (0) 2023.09.24
AJAX using JQuery  (0) 2023.09.24
JQuery event  (0) 2023.09.23
Javascript this  (0) 2023.09.23
728x90

function addJavaScript(jsFilePath){

var headElement = document.getElementsByTagName('head')[0];

var newScriptElement = document.createElement('script');

newScriptElement.setAttribute('type','module');

newScriptElement.setAttribute('src',jsFilePath);

headElement.appendChild(newScriptElement);

}

addJavaScript('js/app.js');

addJavaScript('js/request.js');

addJavaScript('js/request-url.js');

 

html 파일에서 include.js만 추가하고

<script src="js/ref/guest_js_include.js" type="text/javascript"></script>

 

include.js 내에서 

추가할 모듈을 추가한다. 

'Javascript' 카테고리의 다른 글

Intersection Observer 무한스크롤 구현하기  (0) 2023.11.24
SPA AJAX Request With JQuery  (0) 2023.09.25
AJAX using JQuery  (0) 2023.09.24
JQuery event  (0) 2023.09.23
Javascript this  (0) 2023.09.23
728x90

-form을 이용한 jQuery AJAX 요청

$('#f').on('submit',function(e){

/*let parameter1=$('#f').serialize();

console.log(parameter1);*/

let parameter2 = $(e.target).serialize();

let jsonArray = $(e.target).serializeArray();

 

e.preventDefault();

});

form.on('submit',function) 

form에 submit 이벤트 리스너 등록 

 

>form의 input parameters (json data) 생성

 

++('#f') 폼으로 접근하는것은 권장하지 않는다. 

이벤트가 발생한 event target으로 접근 

 

let parameter2 = $(e.target).serialize();

serialize() 함수 => property=value&property=value&... 형식으로 data 생성 

 

let jsonArray = $(e.target).serializeArray();

serializeArray() 함수 =>json 배열 형태로 data 생성

 

++element의 속성값 접근하기 

//attribute set

$('#p_image').attr('src','icon1.png');

//attribute get

console.log($('#p_image').attr('src'));

attr('attributeName'[,value])

 

++폼 태그의 입력값에 접근할 때

console.log("1.$('#id').attr('value') [x]:"+$('#id').attr('value'));

console.log("1.$('#id').val() [o]:"+$('#id').val());

attr('value') value 속성의 값에 접근하는 방법은 사용하지 않는다. 

val() 함수를 사용하면 DOM 생성 이후 동적으로 변하는 value 값을 읽을 수 있다. 

 

 

>jQuery AJAX 요청

 

$.ajax(url[, settings])

settings type = plainObject == json == { url:xx, setting1:xx, setting2:xx...}

 

ㅁ settings

 

method: type(String) default('GET')

Http요청 보낼 방식

 

contentType: type(boolean or String) default('application/x-www-form-urlencoded; charset=UTF-8')

서버로 데이터를 보낼 때 데이터의 타입 : multipart/form-data, text/plain...

 

data: type(plainObject or String or Array) default({})

서버로 보낼 데이터 

body를 가질 수 없는 requestMethod(GET) 의 경우 data가 URL에 붙여진다.

 

dataType: type(String) default(jquery가 xml, json, script, html 중 적절한 타입을 찾아 설정, 보통 json) 

서버로부터 받은 응답의 데이터 타입 

 

timeout: type(number) default(0) 

number ms 만큼 timeout 한 후에야 send 된다. 

 

statusCode: type(PlainObject==json) default({})

응답의 상태 코드

요청이 성공적으로 이루어지면 success callback 

3xx(redirect)를 포함한 4xx,5xx(error) 발생시 error callback 

$.ajax({

statusCode: {

404: function() {

alert( "page not found" );

}

}

});

404 코드일때 function() 실행 

 

 

beforeSend: type(function(jqxhr,settings{})

요청 전 실행될 함수

 

success: type(function(data, textStatus, jqxhr))

요청 성공시 실행될 함수

 

error: type(function(jqxhr,textStatus,errorThrown))

error 발생시 실행될 함수

 

complete: type(function(jqxhr, textStatus))

success, error callback 함수가 실행된 이후 실행될 함수

 

 

 

$.ajax({

url:`01.ajaxRequestPOST/${idStr}`,

method:`POST`,

data: parameter 또는 jsonArray,

contentType:'application/json;charset=UTF-8',

dataType:'json',

success:function(responseJsonObject){

...

},

});

 

>prevent default submit

e.preventDefault();

 

 

GET 방식 AJAX 요청 예제 

$('#id').keyup(function (e) {

let idStr = $(e.target).val();

if (idStr.trim() == '') return;

 

$.ajax({

url: `01.ajaxRequestGET/${idStr}`,

method: `GET`,

data: {},

contentType: 'application/json;charset=UTF-8',

dataType: 'json',

success: function (responseJsonObject) {

if (responseJsonObject.status == 1) {

$('#msg').html(responseJsonObject.msg).css('color', 'green');

} else if (responseJsonObject.status == 2) {

$('#msg').html(responseJsonObject.msg).css('color', 'orange');

}

},

error: function (xhr, textStatus) {

alert('error!!' + textStatus);

}

})

});

keyup 이벤트가 발생할 때 입력된 값을 받고 ajax 요청을 한다. url로 id를 맵핑하기 때문에 data가 필요없다.

 

POST 방식 AJAX 요청 예제

$.ajax({

url:`01.ajaxRequestPOST/${idStr}`,

method:`POST`,

data:{},

contentType:'application/json;charset=UTF-8',

dataType:'json',

beforeSend:function(){

$('#msg').html('<img src="loading.gif" width="20px" height="20px/>');

},

success:function(responseJsonObject){

if(responseJsonObject.status==1){

$('#msg').html(responseJsonObject.msg).css('color','green');

}else if(responseJsonObject.status==2){

$('#msg').html(responseJsonObject.msg).css('color','orange');

}

},

error:function(xhr,textStatus){

alert('error!!'+textStatus);

}

});

beforeSend 함수도 만들어주어 send 직전부터 response를 받을때까지 실행할 함수를 등록

 

setInterval 함수를 이용하여 정해진 시간 간격마다 AJAX 요청 실행 

$(function(){

setInterval(function(){

$.ajax({

url:'04.newsTitlesJSON',

method:'GET',

dataType:'json',

success:function(responseJsonObject){

let html= `<ul>`;

$.each(responseJsonObject.data,function(i,newsJsonObject){

 

html+=`<li>${newsJsonObject.title}[${newsJsonObject.company}]${newsJsonObject.date}</li><br>`;

 

});

html+=`</ul>`;

$('#newsDiv').html(html);

}

});

},1000);

})

 

 

 

 

jQuery API document

https://api.jquery.com/jquery.ajax/

 

jQuery.ajax() | jQuery API Documentation

Description: Perform an asynchronous HTTP (Ajax) request. The $.ajax() function underlies all Ajax requests sent by jQuery. It is often unnecessary to directly call this function, as several higher-level alternatives like $.get() and .load() are available

api.jquery.com

 

'Javascript' 카테고리의 다른 글

SPA AJAX Request With JQuery  (0) 2023.09.25
js 모듈 의존성 줄이기  (0) 2023.09.24
JQuery event  (0) 2023.09.23
Javascript this  (0) 2023.09.23
JQuery effect  (0) 2023.09.22
1234

+ Recent posts