정보 보관 ver1.0

화면 잠그기(wrap)

James Wetzel 2011. 7. 6. 13:19

...More Simple More Efficient... ☞ Guest Book enSimple.net ?
Home Study Q & A Knowledge Base Free Board News

WEB forever
[작성자 : chang] 8/19/2009 4:26:45 PM 에 남기신 글입니다.

제목 : ASP.NET AJAX : 요청 처리 시 사용자 화면 잠그기


이번 글은 앞선 UpdateProgress 컨트롤 연장 선상에서 제공되는 내용으로서 사용자가 비동기 요청 후에 연속해서 다른 요청을 할 수 없도록 화면을 잠그는 기법을 소개한다.

한번에 하나의 작업만 처리하도록 사용자를 강제하자!!!

사실 필자는 앞선 글에서 소개한 진행 상태 보고용 UI(UpdateProgress) 보다는 사용자가 하나의 작업을 처리 중일때, 다른 작업을 시작할 수 없도록 방어(?) 하는 것이 더 중요하다고 본다. (물론 그래야 하는 상황에서 말이다.) 즉. 작업 처리가 동기적으로 이루어 져야 하는데도 불구하고, 하나의 작업이 끝나기도 전에 다른 작업을 시작할 수 있도록 사용자를 방치(?)하는 것은 여러 가지 부작용을 발생시켜, 개발자의 작업량을 증가시킨다. 즉 일반적인 상황에서 작업의 동기화(Synchronization)를 프로그램 입장에서 제공해 주지 않으면 사용자는 곧바로 다른 작업을 시작해도 된다고 인식하므로 사용자의 연속적인 작업 시작을 막을 길이 없고, 그렇다면 프로그래머는 그에 대응하기 위한 로직을 추가해야 하는 상황이 된다.

해서, 우리는 사용자가 버튼을 누름으로서 하나의 작업을 요청했다면, 그 작업 처리 중에는 다시 다른 작업을 요청할 수 없도록 강제하고자 한다.
이를 위해 화면을 랩(Wrap)을 씌워 잠궈 버릴 것인데, 그럼 사용자는 꼼짝없이 작업 처리중에는 멋있는 UpdateProgress 컨트롤의 진행 표시를 보면서 기다리는 수 밖에…
(간혹 이런 경우 웹 브라우저를 아예 꺼버리는 무지막지한 사용자도 있다….이런 사용자들은 대게 싸움을 잘 하므로 건드리지 말기 바란다…..-_-!)

문서에 씌울 랩(Wrap) 만들기

여기서 사용할 방법은 랩(wrap)을 씌워 버리고자 한자, html document 객체에 씌울 랩을 먼저 만들어 두고 평상시에는 보이지 않게 하자.
위치는 절대 포지셔닝을 사용하여 {0,0} 위치에 두도록 한다. 그럼 문서의 좌측 최 상단에 위치할 것이다.색깔은 조금 어둡게 해서 "현재 페이지가 비활성 상태이므로 건드릴 수 없어요"...처럼 보이게 할 것이다.

<div id="lockPane"
style="display: none; position: absolute; top: 0px; left: 0px; height: 0px; width: 0px; text-align: center;vertical-align:middle; font-family: '맑은 고딕'; color: #FFFFFF; background-color: #C0C0C0;">processing the job....</div>


● 랩을 씌우고/벗기는 함수 정의

// 랩 씌우는 함수
function lockPage() {
var lockPane = document.getElementById("lockPane");
lockPane.style.width = getWindowWidth();
lockPane.style.height = getWindowHeight();
lockPane.style.display = "block";
lockPane.onclick = "return false";
document.body.style.cursor = 'wait';
// 랩은 가장 바깥쪽에 씌워야 한다.
lockPane.style.zIndex = 0;
// 랩은 조금 투명해야 내용물이 보인다.
setOpacity(lockPane, 3);
}

// 랩 벗기는 함수
function unLockPage() {
var lockPane = document.getElementById("lockPane");
lockPane.style.display = "none";
document.body.style.cursor = 'auto';
}

// 투명도 설정 함수
function setOpacity(obj, value) {
obj.style.opacity = value / 10;
obj.style.filter = 'alpha(opacity=' + value * 10 + ')';
}
// 브라우저의 문서영역 높이 가져오기
function getWindowHeight() {
var windowHeight = 0;
if (typeof (window.innerHeight) == 'number') {
windowHeight = window.innerHeight;
}
else {
if (document.documentElement && document.documentElement.clientHeight) {
windowHeight = document.documentElement.clientHeight;
}
else {
if (document.body && document.body.clientHeight) {
windowHeight = document.body.clientHeight;
}
}
}
return windowHeight + "px";
}
// 브라우저의 문서영역 너비 가져오기
function getWindowWidth() {
var windowWidth = 0;
if (typeof (window.innerWidth) == 'number') {
windowWidth = window.innerWidth;
}
else {
if (document.documentElement && document.documentElement.clientWidth) {
windowWidth = document.documentElement.clientWidth;
}
else {
if (document.body && document.body.clientWidth) {
windowWidth = document.body.clientWidth;
}
}
}
return windowWidth + "px";
}

● 비동기 포스트백 시작/종료 시에 랩 씌우기/벗기기

비동기 포스트백 요청이 시작될 때 사용자 화면에 랩을 씌워 어떠한 입력도 할 수 없게 만들고, 요청 처리가 완료되면, 랩을 벗겨 내어 다음 작업을 수행할 수 있게 한다.

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
var postBackElement;

function InitializeRequest(sender, args) {
if (prm.get_isInAsyncPostBack()) {
args.set_cancel(true);
}
postBackElement = args.get_postBackElement();
if (postBackElement.id == 'Button1') {
$get('UpdateProgress1').style.display = 'block';
$get('UpdateProgress1').style.visibility = 'visible';
}
else if (postBackElement.id == 'Button2') {
$get('UpdateProgress2').style.display = 'block';
$get('UpdateProgress2').style.visibility = 'visible';
}
lockPage();
}
function EndRequest(sender, args) {
if (postBackElement.id == 'Button1') {
$get('UpdateProgress1').style.display = 'none';
$get('UpdateProgress1').style.visibility = 'hidden';
}
if (postBackElement.id == 'Button2') {
$get('UpdateProgress2').style.display = 'none';
$get('UpdateProgress2').style.visibility = 'hidden';
}
unLockPage();
}

** 위 소스를 완벽하게 파악하려면, Microsoft AJAX Library(클라이언트 라이브러리)에 대한 이해가 필요하며, 이에 대해서는 ASP.NET AJAX 시리즈의 글에 포함될 예정이다.


● 결과 화면

아래와 같이 버튼을 누르면 랩이 씌어져 사용자는 다른 작업을 진행할 수 없으며, 종료되면 랩이 벗겨진다.
** 참고로, 위 소스는 IE6,7,8 및 Safari에서도 작동하도록 구현하였다.



참 유용할 것 같지 않나?..(__!)



첨부파일 : LockPageDemo.zip (2 Kbytes)
List
□ 한줄의 평 이름:

728x90
반응형