2015. 11. 11. 10:05

네이버 지도 API를 사용할 일이 생겨서 작업을 진행, 그소스를 남겨둡니다.

네이버 API 안내에 있는 소스를 활용하여 부분 수정하였습니다.

참고로 소스중 src="//openapi.map.naver.com~ 부분에서 http: 를 제거하지 않으면

파폭등에서 블럭시켜서 동작을 하지 않는 경우가 있기에 제거하였습니다.

 

 

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>네이버 지도 TEST</title>
<script type="text/javascript" src="//openapi.map.naver.com/openapi/naverMap.naver?ver=2.0&key=네이버에서 발급받은 키"></script>
<style>
body {
    height:600px;
    width: 500px;
}
</style>
</head>
<body>
<div id="map" style="border:1px solid $000;"><div>


<script type="text/javascript">
var isShow_Slider = true;
var isShow_MapTypeBtn = true;
var isShow_ThemeMapBtn = true;
var isShow_BicycleGuide = false;
var isShow_TrafficGuide = false;
var isShow_trafficButton = true;
var isRun_userClick = false; //사용자 클릭

var oSeoulCityPoint = new nhn.api.map.LatLng(37.5675451, 126.9773356);
var defaultLevel = 11;
var oMap = new nhn.api.map.Map(document.getElementById('map'), {
 point : oSeoulCityPoint,
 zoom : defaultLevel,
 enableWheelZoom : true,
 enableDragPan : true,
 enableDblClickZoom : false,
 mapMode : 0,
 activateTrafficMap : false,
 activateBicycleMap : false,
 minMaxLevel : [ 1, 14 ],
 size : new nhn.api.map.Size(800, 480) });


if(isShow_Slider == true){
 var oSlider = new nhn.api.map.ZoomControl();
 oMap.addControl(oSlider);
 oSlider.setPosition({
  top : 10,
  left : 10
 });
}


if(isShow_MapTypeBtn == true){
 var oMapTypeBtn = new nhn.api.map.MapTypeBtn();
 oMap.addControl(oMapTypeBtn);
 oMapTypeBtn.setPosition({
  bottom : 10,
  right : 80
 });
}


if(isShow_ThemeMapBtn == true){
 var oThemeMapBtn = new nhn.api.map.ThemeMapBtn();
 oThemeMapBtn.setPosition({
  bottom : 10,
  right : 10
 });
 oMap.addControl(oThemeMapBtn);
}


if(isShow_BicycleGuide == true){
 var oBicycleGuide = new nhn.api.map.BicycleGuide(); // - 자전거 범례 선언
 oBicycleGuide.setPosition({
  top : 10,
  right : 10
 }); // - 자전거 범례 위치 지정
 oMap.addControl(oBicycleGuide);// - 자전거 범례를 지도에 추가.
}


if(isShow_TrafficGuide == true){
 var oTrafficGuide = new nhn.api.map.TrafficGuide(); // - 교통 범례 선언
 oTrafficGuide.setPosition({
  bottom : 30,
  left : 10
 });  // - 교통 범례 위치 지정.
 oMap.addControl(oTrafficGuide); // - 교통 범례를 지도에 추가.
}


if(isShow_trafficButton == true){
 var trafficButton = new nhn.api.map.TrafficMapBtn(); // - 실시간 교통지도 버튼 선언
 trafficButton.setPosition({
  bottom:10,
  right:150
 }); // - 실시간 교통지도 버튼 위치 지정
 oMap.addControl(trafficButton);
}


var oSize = new nhn.api.map.Size(28, 37);
var oOffset = new nhn.api.map.Size(14, 37);
var oIcon = new nhn.api.map.Icon('http://static.naver.com/maps2/icons/pin_spot2.png', oSize, oOffset);

var oInfoWnd = new nhn.api.map.InfoWindow();
oInfoWnd.setVisible(false);
oMap.addOverlay(oInfoWnd);

oInfoWnd.setPosition({
 top : 20,
 left :20
});

var oLabel = new nhn.api.map.MarkerLabel(); // - 마커 라벨 선언.
oMap.addOverlay(oLabel); // - 마커 라벨 지도에 추가. 기본은 라벨이 보이지 않는 상태로 추가됨.

oInfoWnd.attach('changeVisible', function(oCustomEvent) {
 if (oCustomEvent.visible) {
    oLabel.setVisible(false);   
 }
});

 

//마커 추가
var oUserPoint = new nhn.api.map.LatLng(37.5675451, 126.9773356);
var oUserMarker = new nhn.api.map.Marker(oIcon, { title : '서울~'});
oUserMarker.setPoint(oUserPoint);
oMap.addOverlay(oUserMarker);
// 마커라벨 표시
var oUserLabel = new nhn.api.map.MarkerLabel(); // 마커 라벨 선언
oMap.addOverlay(oUserLabel);// 마커 라벨 지도에 추가. 기본은 라벨이 보이지 않는 상태로 추가됨
oUserLabel.setVisible(true, oUserMarker);// 마커 라벨 보이기

 


               
var oPolyline = new nhn.api.map.Polyline([], {
 strokeColor : '#f00', // - 선의 색깔
 strokeWidth : 5, // - 선의 두께
 strokeOpacity : 0.5 // - 선의 투명도
}); // - polyline 선언, 첫번째 인자는 선이 그려질 점의 위치. 현재는 없음.
oMap.addOverlay(oPolyline); // - 지도에 선을 추가함.

oMap.attach('mouseenter', function(oCustomEvent) {

 var oTarget = oCustomEvent.target;
 // 마커위에 마우스 올라간거면
 if (oTarget instanceof nhn.api.map.Marker) {
  var oMarker = oTarget;
  oLabel.setVisible(true, oMarker); // - 특정 마커를 지정하여 해당 마커의 title을 보여준다.
 }
});

oMap.attach('mouseleave', function(oCustomEvent) {

 var oTarget = oCustomEvent.target;
 // 마커위에서 마우스 나간거면
 if (oTarget instanceof nhn.api.map.Marker) {
  oLabel.setVisible(false);
 }
});


if(isRun_userClick == true){

 oMap.attach('click', function(oCustomEvent) {
  var oPoint = oCustomEvent.point;
  var oTarget = oCustomEvent.target;
  oInfoWnd.setVisible(false);
  // 마커 클릭하면
  if (oTarget instanceof nhn.api.map.Marker) {
   // 겹침 마커 클릭한거면
   if (oCustomEvent.clickCoveredMarker) {
    return;
   }
   // - InfoWindow 에 들어갈 내용은 setContent 로 자유롭게 넣을 수 있습니다. 외부 css를 이용할 수 있으며,
   // - 외부 css에 선언된 class를 이용하면 해당 class의 스타일을 바로 적용할 수 있습니다.
     // - 단, DIV 의 position style 은 absolute 가 되면 안되며,
   // - absolute 의 경우 autoPosition 이 동작하지 않습니다.
   oInfoWnd.setContent('<DIV style="border-top:1px solid; border-bottom:2px groove black; border-left:1px solid; border-right:2px groove black;margin-bottom:1px;color:black;background-color:white; width:auto; height:auto;">'+
              '<span style="color: #000000 !important;display: inline-block;font-size: 12px !important;font-weight: bold !important;letter-spacing: -1px !important;white-space: nowrap !important; padding: 2px 5px 2px 2px !important">' +
              'Hello World <br /> ' + oTarget.getPoint()
               +'<span></div>');
   oInfoWnd.setPoint(oTarget.getPoint());
   oInfoWnd.setPosition({right : 15, top : 30});
   oInfoWnd.setVisible(true);
   oInfoWnd.autoPosition();
   return;
  }
  var oMarker = new nhn.api.map.Marker(oIcon, { title : '마커 : ' + oPoint.toString() });
  oMarker.setPoint(oPoint);
  oMap.addOverlay(oMarker);

   var aPoints = oPolyline.getPoints(); // - 현재 폴리라인을 이루는 점을 가져와서 배열에 저장.
  aPoints.push(oPoint); // - 추가하고자 하는 점을 추가하여 배열로 저장함.
  oPolyline.setPoints(aPoints); // - 해당 폴리라인에 배열에 저장된 점을 추가함
 });
}
</script>
</body>
</html>

 

Posted by 작은0악마
2015. 1. 29. 11:42

jquery를 이용한 QR코드를 생성하는 오픈 소스를 소개해 드리겠습니다.

라이센스는 MIT 라이센스이며 소스는 github제작자의 홈페이지에서 다운로드 받으실 수 있습니다.

제작자의 사이트 좌측 하단에 보면 "Buy me a beer"라는 후원 베너가 있네요. 제작자의 위트가 엿보입니다. ^^

 

 

 

제작자의 홈페이지 화면입니다.

라이센스 정보와 github 주소등의 정보가 있으며 사용 설명도 잘 되어 있습니다.

 

저는 github에서 소스를 다운받아 demo폴더에서 실행을 했더니 처음에는 동작을 하지 않았습니다.

데모 폴더의 index.html을 열어보니

<script src="../jquery.qrcode-{{pkg.version}}.js"></script>

란 코드가 보입니다. 그래서 해당 코드에서 -{{pkg.version}} 부분을 삭제하였습니다.

 

그러나 역시 동작하지 않았습니다. ㅡㅡ;

 

다시 폴더들을 확인하였더니 src 폴더에 있는 "jquery.qrcode.js" 파일의 크기와

dist 폴더에 있는 "jquery.qrcode.js" 파일의 크기가 다릅니다.

그래서 dist 폴더에 있는 파일을 복사한 후 실행하였더니 이번엔 성공~~

 

 

위와 같이 QR코드가 잘 보입니다. ^^

 

참고로 전 크롬브라우저에서 테스트를 하였으며

위 이미지를 보시면 우측 항목중 "LABEL"이라는 항목에 적은 문구가 QR코드 중간에 있습니다.

그런데 좌측 상단에 있는 "REDER MODE"를 DIV로 하게되면 "LABEL"이 적용되지 않습니다.

 

QR코드 관련한 작업을 할때 유용할것 같습니다.^^

Posted by 작은0악마
2015. 1. 15. 10:28

이벤트와 관련한 작업을 하다보면 예기치 못한 문제가 종종 발생한다.
이번에는 이벤트가 서브에서 상위로 순차적으로 발생하는 문제(이벤트 버블링)를 만나고
이를 처리하였다.

 

지난번 포스팅한 글 "object is not a function 에러 발생!!" 의 예제를 가지고
살펴보겠다.

(코드는 Syntax Highlighter가 적용되어 모바일에서는 안보일 수 있습니다.)

 


 

일단 구조는 지난번과 같다. 그룹1과 그룹2를 클릭하면 하단의 맴버 목록이 숨김/표시를 반복하는것이다.
여기에 하나를 추가하자. 위 소스를 보면 지난번 포스팅과 다르게
"<a href='javascript:void(0);' onClick='subclick(); return false'>"란 코드가 들어가 있다.
즉, 그룹을 클릭하면 토글 시키고 맴버를 클릭하면 다른 동작을 하게 하는 것이다.
추가한  A 태그내에 href속성에 과 onclick 이벤트에 주어진 void(0), return false 등을 쓴 이유는
"A 태그에서 onClick 이벤트 사용"에 설명해놓았다.


이제 코드를 붙여보자.

(코드는 Syntax Highlighter가 적용되어 모바일에서는 안보일 수 있습니다.)

 


 

역시 지난번 코드에서 subclick() 함수만 추가하였다.
이제 이를 실행해보면 다음 그림과 같이 된다.

 

 

 

 

 

 

 

그런데 이때 문제가 발생한다.
맴버를 클릭하고 alert창을 닫으면 마치 그룹을 클릭한것처럼 맴버목록이 숨겨진다.
이는 클릭이벤트가 맴버에서 그룹까지 전해진것인데 이를 이벤트 버블링이라고 한다.

지금 상황에서 이는 내가 원하지 않는 동작이다.


그럼 이를 어떻게 처리할까? 버블링을 막는 것이다.

 

첫번째 방법은 subclick() 함수내에서 처리하는것으로
event.cancelBubble = "true"; 를 삽입한다.


두번째 방법은 jquery로 페이지가 onload일때 다음 코드로 처리하는 방법이다.
$(".group a").click(function(e) {
 e.stopPropagation();
});
 
두가지 모두 테스트 해보았고 정상적으로 동작하였다.

최종적인 소스는 아래와 같다.

(코드는 Syntax Highlighter가 적용되어 모바일에서는 안보일 수 있습니다.)

 


 

Posted by 작은0악마
2015. 1. 9. 14:21

jquery를 사용하여 동적으로 하위 리스트를 숨김/표시 하는 기능을 만들던 중

"object is not a function" 이라는 에러를 만났다.

 

  • 그룹1
    • 맴버1
    • 맴버2
    • 맴버3
  • 그룹2
    • 맴버4
    • 맴버5
    • 맴버6

 

위와 같은 html코드가 있을때 브라우저에서는 다음과 같이 나타난다.

(코드는 Syntax Highlighter가 적용되어 모바일에서는 안보일 수 있습니다.)

 

 

여기서 jquery를 사용하여 그룹1, 그룹2를 클릭할때 그 하단의 맴버 목록을 숨김/표시하는 기능을 넣고

처음 페이지가 보여질때 목록이 숨겨진 상태로 표시하려 하였다.

 

그래서 코드를 다음과 같이 작성하였다.

(코드는 Syntax Highlighter가 적용되어 모바일에서는 안보일 수 있습니다.)

 


 

위와 같이 하면 "object is not a function" 이라는 에러가 난다.

 

그래서 alert으로 다음과 같이 찍어보았다. 그 결과는

1. alert($(this)); -> [object Object]
2. alert($(".group").get(0)); -> [object HTMLLIElement]

 

결과적으로 두 방식은 서로 다른 타입의 object를 반환하여 생기는 문제...

 

그래서 아래와 같이 처리하였다.

(코드는 Syntax Highlighter가 적용되어 모바일에서는 안보일 수 있습니다.)

 


 

다른 해결 방법도 있겠지만 일단 패스~~~ ^^;

 

* 추가 사항

위 코드에서

(코드는 Syntax Highlighter가 적용되어 모바일에서는 안보일 수 있습니다.)

 

var obj_id= $(".group").get(i).id;
$("#"+obj_id).children("ul").css("display", "none");

 

부분을 아래와 같이 해도 된다.

(코드는 Syntax Highlighter가 적용되어 모바일에서는 안보일 수 있습니다.)

 

$($(".group").get(i)).children("ul").css("display", "none");

 

 

 

Posted by 작은0악마
2014. 12. 19. 11:12

Javascript에서 window.open()을 사용할때는 대부분이
아래와 같은 GET방식을 이용한다.

 



팝업

 


*옵션은 left, top, width, height, toolbar, statuso, scrollorbarso, resizable 등등을 조합하여 사용한다.
(좀더 자세한 사항은 http://www.w3schools.com/jsref/met_win_open.asp 를 참조)

 

 

그런데 예를 들어 인수로 넘긴값을 사용자가 변경하면 안될때와 같이
window.open()을 사용할때 POST방식을 이용해야만 할때가 있다.


그럴때는 다음과 같은 방법을 사용하면 된다.

 



팝업

 


그런데 팝업으로 open될 페이지의 소스에서 주의해야 할 것이 있다.
당연한 것인데... 

GET 전송으로 넘어오는 값은 무시하게 해야 한다는 것이다.
GET을 허용하면 POST로 전송하는 것이 무의미한 것이 때문이다.

Posted by 작은0악마
2014. 10. 1. 09:50

사용자가 마우스로 드래그하여 영역의 크기를 조정하는 기능을 구현하던중

 

3개의 DIV를 가지고 테스트를 할때는 별 무리가 없었는데

 

실제 좀 복잡한 UI에서 적용을 하니 이상한 동작이 일어났다..

 

마우스로 드래그를 하는데 left 값이 순차적으로 변하는게 아니라 널뛰기 하듯 튀는 현상이 발생!!!

 

여러가지로 확인을 해보았으나 이해할 수가 없었는데...

 

브라우저의 개발자 도구로 확인을 해보니 draggable을 적용한 DIV에 내가 지정하지 않은 값이 들어가 있는것을 확인.

 

결론은 div 에 draggable을 적용하면 draggable에서 해당 div의 여러가지 값을 변경하거나 지정한다.

 

이번 경우는 draggable에서 해당 DIV 에 position값을  relative로 변경하여서 발생하였던것..

 

그래서 draggable을 적용하고 바로 다음줄에서 해당 DIV에 position 값을 변경하여 해결!!

 

 

$('#div_b').draggable({
  axis : 'x',
  containment : [
   41,
   0,
   300,
   0
  ],
  drag : splitter
 });
 
 //draggable 함수가 position을 강제로 relative로 변경해서..
 $('#div_b').css("position","static");

Posted by 작은0악마
2014. 6. 23. 12:02

프로젝트를 진행하면서 explorer 8버전 이하에서 화면이 깨지는등의 문제가 발생하였다

(HTML5, CSS 등에 의해)

 

일차적으로 asOne님의 블로그 http://as-one.tistory.com/entry/IE8-에-html5-쉽게-적용하기 를 보고 어느정도 해결하였으나

해결되지 않는 문제가 있었다.

시간을 들여 방법을 찾으면 될 수도 있겠지만

본래 이 프로젝트가 HTML5 기준이므로

지원하지 않는 브라우저는 무시하는게 맞지만 클라이언트가 이해를 잘 못한다...

 

그래서 찾은 타협점..

explorer 9버전 미만에서는 사용자에게 알림(alert)을 띄우자..

 

그래서 이에 대해 작업을 하였다

일단 브라우저 정보를 가지고 있는 navigator 객체를 이용.

이 객체에 대한 자세한 설명은 자바킹님의 블로그 를 참고.

 

버젼을 가져오는것은 블로그 http://jskimmail.blog.me/40137030492를 참고하여 본인에게 맞게 수정하였다.

 

또한 익스 11에서는 기존의 방법들로서는 문제가 발생한다.

이에대한 대책으로 지단로보트님의 블로그를 참고하였다.

 

작성한 코드는 다음과 같다.

 

<script language="javascript">
window.onload = function(){
 
   var isExplorer = false;
   if (navigator.appName == 'Microsoft Internet Explorer') {
      isExplorer = true;
   }
 
   if(isExplorer == false){
    //익스 11에서는 appName을 Netscape로 인식하므로 Trident란 Mircosoft가 Internet Explorer에 사용하는 레이아웃 렌더링 엔진의 이름을 이용
    if (navigator.appName == 'Netscape' && navigator.userAgent.search('Trident') != -1) {   
      isExplorer = true;
    }
 }

 

  if(isExplorer == true){ //익스플로러라면 버젼 확인 
      re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");

      if (re.exec(navigator.userAgent) != null){
         rv = parseFloat(RegExp.$1);
         if(rv < 9){
            alert("익스플로러 8 이하에서는 정상적으로 보이지 않을 수 있습니다.");
         }
      }
  }

 
}

</script>

 

일단 위의 코드로 당장 원하는 것은 얻었다...그러나 여기에도 문제는 있다.

이 프로젝트는 특정 버젼 이하 여부만 알면 끝이었지만

버젼별로 다른 동작을 해야한다면 문제가 있다

 

직접 확인해 보지는 않았지만 (아직 익스 11은 설치하지 않았다.)

지단로보트님의 블로그를 보면 익스 11의 userAgent에는 MSIE가 없다.

따라서 익스 11에서는 버젼을 가져오는것이 위의 코드로는 불가능하다.

다만 지단로보트님이 적어주신 userAgent값을 봤을때

거의 끝부분에 rv:11.0이라는 값이 있는데

이것이 익스 11의 버젼을 말하는것이 아닌가 싶다.

 

 

Posted by 작은0악마