앵귤러 작업 중 

window.open 작업이 있었다.


SPA에서 window.open 이 좀 이상하지만 

설계상 어쩔 수 없이 작업을 하게 되었는데.


router 작용으로 인해 새창을 열어줘도 동일한 페이지로 인식하여

로딩현상이 없었다.


window.open 시 팝업이름을 설정안하면 새창이 열리겠지만

여러개 새창열리는게 마음에 들지 않으므로


팝업이 열려있는지 체크하여 팝업이 열려있으면 닫고 다시 여는 방법을 선택했다.



<script>
printWin = null; // 인쇄용 팝업

fnPrint() {
// 팝업 있는 지 확인 하여 있으면 닫고 다시 연다.
if (! (!this.printWin || this.printWin.closed) ) {
this.printWin.close();
}

this.printWin = window.open(`/#/print`, 'printWindow', 'width=1000, height=1000');
}
</script>


이번 프로젝트에서 뷰단을 스프링부트의 기본 템플릿 엔진인 thymeleaf을 사용하게 되었다.

처음에는 조금 어색하였지만 사용하다 보니

jsp보다 오히려 더 편한거 같다.


thymeleaf에서 model로 내려온 변수를 자바스크립를 사용하는 방법을 보면 다음과 같다.


1. script 영역에서 사용시 CDATA 블럭으로 묶어서 ${모델변수}를 이용


controller에서 

model.addAttribute("result", "성공하였습니다.");

로 뷰단으로 result를 내린 경우


<script th:inline="javascript">

    /*<![CDATA[*/

var result = /*[[ ${result} ]]*/;

/*]]*/

    $(document).ready(function(){

alert(result);

    });

</script>


CDATA로 묶어서 사용


2. 태그내에 onclick이벤트 등 함수에 파람값 설정시

<button th:attr="onclick=|pageMove('${nowPage}', '${pageSize}')|">

th:attr 사용


자바스크립트 정규식..

가끔 쓰게되는 정규식입니다.


// 이메일 체크 정규식

function isEmail(asValue) {

var regExp = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i;

return regExp.test(asValue); // 형식에 맞는 경우 true 리턴

}


// 핸드폰 번호 체크 정규식

function isCelluar(asValue) {

var regExp = /^01(?:0|1|[6-9])-(?:\d{3}|\d{4})-\d{4}$/;

return regExp.test(asValue); // 형식에 맞는 경우 true 리턴

}


비밀번호 체크 정규식

function isJobPassword(asValue) {

var regExp = /^(?=.*\d)(?=.*[a-zA-Z])[0-9a-zA-Z]{8,10}$/; //  8 ~ 10자 영문, 숫자 조합

return regExp.test(asValue); // 형식에 맞는 경우 true 리턴

}





어느날인가 부터 운영하는 홈페이지의 지도가 보이지 않았다.


다음 API 지도를 사용하고 있었는데 맵이 빈 공간으로 나왔다.


오류메세지도 없이...


해당 소스를 열어 확인해 보니


API는 다음것을 쓰고 있었다.


<script type="text/javascript" src="https://apis.daum.net/maps/maps3.js?apikey=키값&libraries=services"></script>


검색해 보니 2019년1월1일부터 다음API가 종료되었다고 한다.


종료된 API는 카카오API를 이용해야 한다고 한다.


걱정 마시라 그냥 API키 받아서 임포트 하는 자바스크립트만 바꿔주면 된다.


https://developers.kakao.com

카카오개발자 사이트로 가서 로그인하고 앱개발시작하기 버튼이나 이름을 클릭하고 내 애플리케이션으로 이동한다.


앱만들기 버튼을 클릭해서 구분할수 있는 앱이름을 입력하고 앱을 만든다.

이후 앱설정으로 들어가서 플랫폼을 추가한다.

웹인경우 웹을 선택하고 도메인을 입력한다. 도메인은 여러개 입력 가능하다. 개발용과 서비스용을 같이쓸려면 해당 URL을 다 등록하면된다.


이후 네이티브 앱 키, REST API 키, JavaScript 키, Admin 키가 표시되는데 이중 

자바스크립트 키를 복사해서 아래 스크립트 임포트하는 부분에 붙여넣고

기존 소스를 변경해 주면된다.


<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=키값"></script>


맵을 호출 스크립트는 변경할 필요가 없다.







메인 화면에 bxslider를 이용한 배너 슬라이더가 있다.


웹접근성 조사에서 아래와 같은 지적사항이 나왔다.


키보드에 의한 초점은 논리적으로 이동해야 하며, 시각적으로 구별할 수 있어야 한다.

① 초점 이동 순서가 논리적이지 않거나 일관성이 없는 경우

② 초점 또는 키보드의 위치를 나타내는 개체가 시각적으로 표시되지 않은 경우

③ 숨겨진 콘텐츠 및 의미 없는 개체에 초점이 이동 되는 경우


이중 3번이 지적사항으로 나왔다.


1.숨겨진 콘텐츠에 초점이동

-키보드 tab키를 이용하여 탐색 시 숨겨진 콘텐츠에 접근되어 초점이 사라집니다.

*숨겨진 콘텐츠에 접근시 화면에 노출되거나, 숨겨진곳에 접근되지 않도록 제공해야 합니다.


우선 기존 소스를 보면


var mainSlider = $('.mainSlider').bxSlider({

auto: true,

autoControls: true,

stopAutoOnClick: true,

pager: true,

speed:500,

autoControlsCombine: true,

responsive: true,

pause: 5000

});


소스를 아래의 빨간색 부분을 추가해주었다.


var mainSlider = $('.mainSlider').bxSlider({

auto: true,

autoControls: true,

stopAutoOnClick: true,

pager: true,

speed:500,

autoControlsCombine: true,

responsive: true,

pause: 5000,

// 웹접근성 추가

onSliderLoad: function(){

$(".bx-clone").find("a").prop("tabIndex","-1");

},

onSlideAfter: function(){

$(".mainSlider").children("li").each(function(){

if($(this).attr("aria-hidden") == "false"){

$(this).find("a").attr("tabIndex","0");

}else{

$(this).find("a").attr("tabIndex","-1");

}

});

}

});


// 웹 접근성

$('.mainSlider a').focusin(function () {

mainSlider.stopAuto();

});


bxSlider 제공 함수인 

onSliderLoad 에 복사되는 항목의 포커스를 가져가는 a태그를 찾아 tabIndex를 -1로 설정합니다.

onSlideAfter 에는 현재 보여지는 슬라이드의 a태그에는 tabIndex를 0으로 설정하고

숨어있는 슬라이드는 -1로 설정합니다.

이는 탭이동시 숨어있는 슬라이드로 포커스가 들어가는 것을 방지하기 위함입니다.


그리고, 슬라이드 안의 a태크에 포커스가 갔을때 슬라이더를 중지시크는 명령을 추가합니다.

이는 포커스 상태인데 슬라이딩이 되어 포커스가 숨는 것을 방지하기 위함입니다.

요런  jquery 달력인 datepicker를 사용하고 있었다.




<!doctype html>

<html lang="en">

 <head>

  <meta charset="UTF-8">

  <title>datepicker</title>

  <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

  <script src="https://code.jquery.com/jquery-1.7.2.js"></script>

  <script src="https://code.jquery.com/ui/1.9.1/jquery-ui.js"></script>

<script type="text/javascript">

$( function() {

var options = {

showOn : 'button'

, buttonImage : 'https://jqueryui.com/resources/demos/datepicker/images/calendar.gif'

, buttonText : '날자선택'

, buttonImageOnly : true

, showMonthAfterYear : true

, changeYear : true

, changeMonth : true

, dateFormat : 'yy-mm-dd'

, monthNamesShort : ['1월','2월','3월','4월','5월','6월','7월','8월','9월','10월','11월','12월'] // 월의 한글 형식.

, dayNamesMin : ['일','월','화','수','목','금','토']

};

    $(".datepicker").datepicker(options);

});

</script>

 </head>

 <body>

<input type="text" class="datepicker" id="date1">

~

<input type="text" class="datepicker" id="date2">

 </body>

</html>



퍼블리셔 분이 datepicker에 대한 수정을 요청하셨다. 웹접근성에 맞게 작동해야 한다는 것이다.


날짜 input안에서 탭을 하면 달력 이미지로 포커스가 가고 거기서 앤터를 치면 달력이 펼쳐져야 된다는 것이다.


현재소스에서는 input 옆에 버튼이 생기지만 이미지만 있어서 그쪽으로는 포커스가 가질 않는다.


그래서 엄청난 삽질을 했다.


datepicker를 통제하기 위해 무지막지한 스크립트를 덕지덕지 붙이기 시작했다.


그러던 중 buttonImageOnly 라는 속성이 뭐지... false로 주면 어떻게 되나...

false로 설정하고 새로 고침을 하니...


button이 생성되고 이미지가 button안에 BG로 보이는 것이다.


역시... tutorial을 제대로 읽어야 한다.


그래야 고생을 안한다.


buttonImageOnly : false


요것만 바꿔주면 된다.. 




홈페이지 작업 중 리뉴얼 작업등이 생겨서

랜딩 페이지가 변경되는 경우

아니면 OS등을 체크해서 특정 페이지등으로 이동시킬때


프론트단 언어로 페이지를 이동시키는 방법은 2가지가 있다.


1. 자바스크립트로 이동

2. 메타태그로 이동


1. 자바스크립트로 이동하는 방법


<script type="text/javascript">

location.href="이동할주소";

</script>


2. 메타태그를 이용하는 방법


<meta http-equiv='refresh' content='0;url=이동할주소'>


이동할 주소가

내부사이트면 /login/login.do 이런 형식으로 내부 링크 주소를

외부 사이트면 http://www.naver.com 처럼 외부 링크 주소를 적어주면 된다.


메타태그에서 숫자 0은 0초후 이동하라는 의미로 즉시 이동하게 된다.

3초후 이동을 원하면 3을 입력하면 된다.






javascript로 브라우저 창이 닫히거나 페이지 이동시 이벤트 처리하는 방법이다.

 

보통 팝업 윈도우에서 특정 로직을 처리하고

정상적으로 닫기 버튼을 눌렀을때나

글을 작성하다 취소나 저장을 누르고 해당 페이지를 빠져나오면

개발자가 이벤트 처리를 통제하기 쉽다..

 

그런데 클라이언트 요구 중 브라우저의 오른쪽 위에 있는 "x"를 눌러서 닫을때

경고를 주거나 작성중인 글을 저장해주길 원한다.

 

이럴때 사용되는 이벤트가 beforeunload 이벤트 이다.

 

소스 적용방법은 다양하다.

 

1. jquery

$(window).bind("beforeunload", function (e){

return "창을 닫으실래요?";

});

 

2. 이벤트 추가

window.addEventListener("beforeunload", function (event) {

  event.returnValue = "진짜 나감?";

});

 

3. 이벤트 선언

window.onbeforeunload = function() {

    return "나가실래요?";

}

 

4. 태그에 이벤트 넣기

<script>

function abc(){

event.returnValue = "정말닫음?";

}

</script>

<body onbeforeunload="abc();">

 

이런식으로 return 또는 event.returnValue 의 문자열이 익스플로러인 경우 닫힘 경고창에 표시되게 된다.

 

크롬

 

익스플로러

 

 

크롬인 경우는 경고창에 해당 문구가 표시되지 않는다.

 

 

 

 

그럼 경고창 없이 특정 로직을 처리하고 싶을때는 어떨까.

return이나 event.returnValue를 삭제하고

특정 로직을 수행하는 함수를 실행시킨다.

 

이 경우 서버에서 처리할 무엇인가가 있다면

ajax를 이용하게 된다.

 

ajax를 이용하는 경우 

 

$.ajax({

url : "처리페이지url",

cache : "false", //캐시사용금지

method : "POST",

data : $("#frm").serialize(),

dataType: "html",

async : false, //동기화설정(비동기화사용안함)

success:function(args){   

//$("#result").html(args);      

},   

error:function(e){  

//alert(e.responseText);  

}

});

 

이런식으로 서버에 ajax로 호출하여 서버처리를 완료하고

완료되면 창이 닫히는 효과를 볼 수 있다.

tabs upload 예제 소스


Set Upload = Server.CreateObject("TABS.Upload")

Upload.Start "C:\저장할폴더"


Upload("업로드파일input명").Save, True

filename = Upload("업로드파일input명").FileName


filename 디비 저장.




tabs upload 다운로드 소스 예제


Set Download = Server.CreateObject("TABS.Download")

Download.FilePath = "물리적파일경로"


Download.FileName = "다운로드될때저장될파일이름"


Download.TransferFile true


set Download = Nothing



<table border=1>
<%
'servervariables 컬렉션값 출력하기
for each key in request.servervariables 
 response.write "<tr><td>"&key&"</td><td>"
 
 if request.servervariables(key) = "" then
  response.write "&nbsp;" & vbcrlf        
 else
  response.write request.servervariables(key) & vbcrlf
 end if
 
 response.write "</td></tr><tr>"
next
%>
</table>

 

 

ALL_HTTP : HTTP_ACCEPT:*/* HTTP_ACCEPT_LANGUAGE:ko HTTP_CONNECTION:Keep-Alive HTTP_HOST:localhost HTTP_USER_AGENT:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0) HTTP_COOKIE:ASPSESSIONIDCCATQBAS=NJODAKCBGFNGAMOJOFJMFLLG HTTP_ACCEPT_ENCODING:gzip, deflate
ALL_RAW : Accept: */* Accept-Language: ko Connection: Keep-Alive Host: localhost User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0) Cookie: ASPSESSIONIDCCATQBAS=NJODAKCBGFNGAMOJOFJMFLLG Accept-Encoding: gzip, deflate
APPL_MD_PATH : /LM/W3SVC/1/ROOT
APPL_PHYSICAL_PATH : D:\LEEJJ\ex\
AUTH_PASSWORD :
AUTH_TYPE :
AUTH_USER :
CERT_COOKIE :
CERT_FLAGS :
CERT_ISSUER :
CERT_KEYSIZE :
CERT_SECRETKEYSIZE :
CERT_SERIALNUMBER :
CERT_SERVER_ISSUER :
CERT_SERVER_SUBJECT :
CERT_SUBJECT :
CONTENT_LENGTH : 0
CONTENT_TYPE :
GATEWAY_INTERFACE : CGI/1.1
HTTPS : off
HTTPS_KEYSIZE :
HTTPS_SECRETKEYSIZE :
HTTPS_SERVER_ISSUER :
HTTPS_SERVER_SUBJECT :
INSTANCE_ID : 1
INSTANCE_META_PATH : /LM/W3SVC/1
LOCAL_ADDR : 127.0.0.1
LOGON_USER :
PATH_INFO : /asp/servervariables.asp
PATH_TRANSLATED : D:\LEEJJ\ex\asp\servervariables.asp
QUERY_STRING :
REMOTE_ADDR : 127.0.0.1
REMOTE_HOST : 127.0.0.1
REMOTE_USER :
REQUEST_METHOD : GET
SCRIPT_NAME : /asp/servervariables.asp
SERVER_NAME : localhost
SERVER_PORT : 80
SERVER_PORT_SECURE : 0
SERVER_PROTOCOL : HTTP/1.1
SERVER_SOFTWARE : Microsoft-IIS/5.0
URL : /asp/servervariables.asp
HTTP_ACCEPT : */*
HTTP_ACCEPT_LANGUAGE : ko
HTTP_CONNECTION : Keep-Alive
HTTP_HOST : localhost
HTTP_USER_AGENT : Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
HTTP_COOKIE : ASPSESSIONIDCCATQBAS=NJODAKCBGFNGAMOJOFJMFLLG
HTTP_ACCEPT_ENCODING : gzip, deflate

+ Recent posts