HTML5 Page Visibility API

Page Visibility API

  • 브라우저에서 탭이 이동해서 안보이는 경우, 비디오는 끄고 싶다.
  • 페이지가 안보이는 중에는 이미지 로테이션을 멈춰두고 싶다.
  • 페이지가 안보이는 중에는 서버에 요청하지 않았으면 좋겠다.

이런 경우에 사용하기 위해 Page Visibility API 스펙이 표준화되고 있습니다. 현재 Working Draft 상태이고, Vendor Prefix 로 지원을 시작했습니다.

지원 현황은 (업데이트가 활발한) MDN을 참고하세요.

입력 필드 내 텍스트 UI, 어떻게 구현하는 것이 좋을까?

요즘 많이 사용하는 UI 중, 입력 필드 내에 입력정보 텍스트를 표시하는 UI 가 있습니다. 아무래도 placeholder속성이 구현되었을 때와 비슷한 모습을 하고 있어서 placeholder 로 오인되는 경우가 있는 것 같습니다.

Label과 Placeholder 의 차이

잠시 label과 placeholder 의 차이를 알아보고, 구현에 대해서는 아래에서 설명하겠습니다. 

HTML5 표준 스펙에 따르면 (clearboth.org 의 한글 번역본을 인용했습니다.)
“label 요소는 사용자 인터페이스에서 캡션을 나타냅니다.”
“placeholder 속성은 짧은 힌트(한 단어나 짧은 구)를 나타냅니다.”

그리고 placeholder 속성의 설명부분에 “placeholder 속성을 label 을 대체하기 위해 사용할수는 없습니다.” 라 명시되어있습니다.

글로는 감이 잘 안오는데 이 둘은 어떤 차이가 있을까요? 차이를 이해하는데, 아래 그림이 도움이 될 것 같습니다.

iOS 메일 설정화면

위 화면은 iOS의 이메일 설정화면 입니다.
말하자면 왼편의 Name, Email, Password, Description 부분이 label요소이고, 오른편의 John Appleseed, [email protected], Required, My Gamil Account 가 placeholder 속성으로 표시한 정보라 할 수 있습니다.
 
label 은 해당하는 인풋 필드에 입력받을 정보를 일반적인 단어를 활용해 표시(캡션)하고 있습니다.
placeholder 는 John Appleseed나 Required 와 같이 입력받을 정보에 대한 힌트를  나타내고 있습니다.
 
 
아래는 각 포털의 로그인화면입니다. 위에서부터, 네이버, 다음, 파란 입니다.

네이버 로그인

다음 로그인

파란 로그인

모두들 입력 필드내에 입력정보 텍스트를 보여주고 있습니다. 그리고 표준에 따르면 ‘아이디’나 ‘비밀번호’는 placeholder속성 보다는 label요소로 구현해야 적합한 컨텐츠이군요.

입력 필드 내에 텍스트를 표시하는 UI는 이처럼 label 요소를 사용해 표현해야하는 경우가 있습니다. placeholder 속성과 혼동하시면 안되요! 🙂

입력 필드 내 텍스트 UI 구현 해보기

이런 UI는 어떻게 구현하는 것이 좋을까요?
아래 구현내용은 http://code.elegantcoder.com/blog-examples/label-ui/ 에서 확인하실 수 있습니다.

1. Custom Attribute Text 받아 넣어주기

텍스트 정보이니, 텍스트를 그냥 활용했으면 좋겠습니다. Custom Attribute 을 만들고, 이벤트에 따라 입력 필드의 value를 변경시키는 방법으로 구현을 해봅니다.

HTML

<label for="ex1-id-input" style="display:none;">이메일 주소</label>
<input type="text" value="이메일 주소" data-placeholder="이메일 주소" id="ex1-id-input" />

JS

(function example1($) {
  var $id = $('#ex1-id-input')
  var $pw = $('#ex1-pw-input')
  var onfocus = function () {
    $(this).val('')
  }
  var onblur = function () {
    var $this = $(this)
    if ($.trim($this.val()).length === 0) {
      $this.val($this.attr('data-placeholder'))
    }
  }
  $id.on('click focus', onfocus).on('blur', onblur);
  $pw.on('click focus', onfocus).on('blur', onblur);

})(jQuery);

그렇지만, 이같은 구현방법은 <input type="password" /> 내에 value 가 문제가 됩니다. value 의 내용이 아래와 같이 비밀번호 문자로 가려지기 때문입니다.

비밀번호 요소에서 문제발생!

2. Background Image 사용하기

이를 회피하기 위한 구현으로, (그리고 비표준인 Custom Attribute 을 사용하지 않기 위해서) 많은 곳에서 CSS의 background-image 속성을 활용합니다. 포커스가 가면, 배경 이미지를 지우고, 포커스가 없거나 블러 이벤트가 발생하면 다시 배경 이미지를 채워주는 방식이죠.

이미 많은 곳에서 이렇게 처리하고 있습니다. 확인결과 위에 캡쳐된 세군데 모두 그렇게 구현이 되어있네요.

HTML

<label for="ex2-pw-input" style="display:none;">비밀번호</label>
<input type="password" value="" id="ex2-pw-input" class="ex2-pw-on" />

JS

(function example2($) {
  var $pw = $('#ex2-pw-input')
  $pw.on('click focus', function () {
    $(this).removeClass('ex2-pw-on');
  });
  $pw.on('blur', function () {
    var $this = $(this)
    if ($.trim($this.val()).length === 0) {
      $this.addClass('ex2-pw-on');
    }
  });
})(jQuery);

우선 구현 자체는 되었습니다. 동작도 괜찮게 합니다. 하지만, 이 구현법은 배경으로 사용할 이미지를 미리 잘라놓아야 한다는 단점이 있습니다. 이미지를 잘라 표현하니 OS의 기본 폰트가 다른 경우 어색하기도 합니다. 위 그림의 포털 로그인 모듈들은 모두 윈도우 시스템 폰트인 굴림체로 표현되어 있습니다.

3. Label 을 활용하기

다른 방법으로 이미 코딩되어 있는 label요소를 활용하면 어떨까요? 

HTML

<div style="position:relative;">
  <label for="ex3-pw-input" style="position:absolute;left:4px;top:8px;">비밀번호</label>
  <input type="password" style="position:absolute;z-index:2;background-color:transparent;" value="" id="ex3-pw-input" />
</div>

JS

(function example3($) {
  var $pw = $('#ex3-pw-input')
  $pw.on('click focus', function () {
    $(this).siblings('label').hide()
  });
  $pw.on('blur', function () {
    $this = $(this)
    if ($.trim($this.val()).length === 0) {
      $this.siblings('label').show()
    }
  });
})(jQuery);

position:absolute를 사용해 label과 input 을 같은 곳에 보이도록 포지셔닝하고, label 요소를 input 아래에 위치 시킵니다. 또  input 요소의 배경을 투명하게 해서 label 이 곧바로 보이게 만들면, JS를 사용할 수 없는 경우에도 입력이 가능해집니다.

이렇게 구현하면 굳이 이미지를 잘라쓰지 않아도 되고, 입력 필드 안쪽이 OS 기본폰트로 보여지게 됩니다.

  • 추가: IE용 구현

IE6~IE8 에서는 배경이 투명한 input 요소는 클릭으로 포커스 이동이 되지 않습니다. 투명 gif 를 이용한 구현을 추가합니다. 

<div style="position:relative;">
    <label for="ex4-pw-input" style="position:absolute;left:4px;top:8px;">비밀번호</label>
    <input type="password" style="position:absolute;z-index:2;background:url('./transparent.gif') repeat 0 0 ;" value="" id="ex4-pw-input" />
</div>

생각해볼 만한 패턴

페이스북 검색 - 기본 상태 페이스북 검색 - 포커스 시

사족을 붙이자면, 포커스가 이동한 경우 그 부분에 어떤 값을 입력해야 할지를 계속 표시해두는 것도 좋은 패턴이라고 생각합니다. 페이스북을 보면, placeholder 부분을 포커스가 이동하기 전에는 진하게 표시해두었다가, 포커스가 맞춰지면 옅게 표시 합니다. 그리고 키를 입력하면 완전히 지워줍니다.

모바일 웹 디버깅 툴 – Weinre

국내 모바일 브라우저 시장 점유율은 2011년 12월 현재 Webkit 계열이 99% 이상의 점유율을 가지고 있다(Statcounter 기준, Android, iPhone, iPod Touch, Dolfin 을 합한 수치).

하지만 Webkit 계열의 브라우저로 천하통일되었더라도 모바일 사이트를 구축하는 것은 여전히 쉽지 않은 일이다.

단말기가 다양할 뿐 아니라 단말기마다 사용된 웹킷 브라우저 버전이 각각 다르고, 단말기에 적용된 OS 버전에 따라서도 다르다. 심지어는 제조사의 커스터마이징이 이루어진 경우도 심심치 않게 볼 수 있다. 같은 회사에서 나온 라인업(갤럭시 S, 갤럭시 K 등) 에서도 다르게 동작하는 경우마저 있다. 

일반적인 모바일 사이트를 개발은 사파리, 크롬과 같은 PC용 웹킷 브라우저에서 이루어지고, 이후 모바일 브라우저에서 확인과정을 거치는 경우가 많다.

하지만 모바일 브라우저에서 명백히 잘못된 작동을 하는 경우에도 Firebug나 Web Inspector 등 디버깅 툴을 내장하고 있지 않으므로 정상 동작하는 코드로 되돌려내는 것은 결국 삽질을 통할 수 밖에 없다. Developer Toolbar가 지원되지 않는 IE6 대응 사이트를 만드는 것과 별반 다르지 않다.

Weinre 는 내장 디버깅 툴이 없는 모바일 브라우저를 위한 원격 디버깅 툴이다. Webkit 계열의 개발자 도구인 Web Inspector 를 사용할 수 있도록 해준다.

모바일에서도 이와 같은 디버깅이 가능해진다!

모바일에서도 위와 같은 디버깅이 가능해진다!

Weinre 개요

처음보면 어떻게 발음해야할지 갸우뚱한 이 프로그램은 포도주 양조장이라는 ‘와이너리’라 부른다. Patrick Mueller http://muellerware.org/ 가 만든 이 프로젝트는 웹킷의 원격 디버깅 프로토콜 http://www.webkit.org/blog/1620/webkit-remote-debugging/ 을 이용해 개발되었고 하이브리드 앱 개발 도구인 Apache Callback(Phonegap) 의 서브 프로젝트이다.

Weinre를 통한 디버깅은 세가지 파트로 나뉜다.

  • 서버(Server)
  • java기반(Jetty)의 http 서버이다.

  • 대상(Target)

  • 디버깅할 모바일 디바이스 브라우저. 웹킷 계열만 지원한다.

  • 클라이언트(Client)

  • Safari, Chrome 등에 내장된 Web Inspector와 비슷한 외관의 클라이언트 페이지. -webkit- prefix 를 통한 CSS3만 지원하므로 웹킷 브라우저가 필수.

 

설치 방법

서버

서버는 프로젝트 홈페이지에서 jar 파일을 다운로드 받아 실행한다.

$ java -jar weinre.jar

옵션설명

--help (or -? or -h)

이 도움말 화면을 보여줌.

 

--httpPort [포트번호]

HTTP 서버가 동작할 포트 번호.

기본값 : 8080

 

--boundHost [hostname | ip address | -all-]

서버에 바인딩할 아이피 주소

기본값 : localhost

 

기본값인 localhost 로는 다른 기기에서 접속할 수 없다. 따라서 다른 기기에서 접속하기 위해서는 다른 호스트네임이나 IP 주소를 바인딩해야한다. -all- 을 사용하면 이 기기로 연결가능한 모든 인터페이스를 사용할 수 있다.

 

맥이나 라눅스에서는 ifconfig 을 사용하고, 윈도우에서는 ipconfig 를 사용해 ip 주소를 얻어올 수 있다.

 

--verbose [true | false]

stdout 을 통해 소소한 것까지 출력함. 

기본값: false

 

--reuseAddr [true | false]

Jetty 의 reuseAddr 옵션을 설정함. 

기본값: false

 서버를 주기적으로 재시작할 때 필요할 수 있다.

 

--readTimeout [seconds]

기본값: 5 

--deathTimeout [seconds]

기본값: 3 * readTimeout

 

대상

대상은 디버깅용 JS파일을 임포트 한다. 이 디버깅용 파일은 HTML 소스에 고정적으로 로드하거나, 북마클릿을 통해 동적으로 로드할 수 있다.

<script src="http://a.b.c:8080/target/target-script-min.js#anonymous"></script>

  • 여기서 a.b.c:8080 은 설치된 서버의 아이피/도메인을 의미함.

클라이언트

이제 사용할 준비가 완료 되었다. 브라우저를 통해 http://a.b.c:8080/client 에 접속하면 아래와 같은 Web Inspector를 볼 수 있다. 

Weinre Remote Debug Client Weinre Remote Element Panel

활용

아이디를 이용한 여러 프로젝트 분기

스크립트 URL : http://a.b.c:8080/target/target-script-min.js#anonymous

클라이언트 접속 URL: http://a.b.c:8080/client/#anonymous

에서 마지막의 #anonymous 부분을 변경해 서버 하나에 프로젝트마다 또는 각 사용자마다 아이디를 줄 수 있다.

북마클릿의 활용

특히 긴급한 상황에서 북마클릿을 활용해 스크립트를 로딩하면 디버그가 가능하다. 

Semantic URL 를 프로젝트 내 소통수단으로!

Semantic URL이란?

Semantic URL 은 Clean URL, Fancy URL, Rewritten URL 으로 불리기도 합니다. 위키피디아에서는 Semantic URL과 Clean URL을 각각 다른 용어로 정의하고 있기는 하지만 내용을 살펴보면 근본적으로는 비슷합니다. 

즉, 비전문가(사용자)에게 친숙한, (의미를 표현하는)구조적인 URL입니다. 

Semantic URL 이 유행하기 시작한 것은 대략 업계에 웹 2.0, Semantic 이라는 키워드가 유행하기 시작할 때 쯤부터 였던 것 같습니다.

Semantic URL과 일반적인 URL의 차이는 한 눈에 드러납니다.  

일반 URL Semantic URL
board.php?id=notice&mode=list&page=1 board/notice/list/1 
board.php?id=notice&mode=view&entry=10  board/notice/10 

 

더 짧을 뿐 아니라 URL만 보고도 어떤 역할을 하는 페이지인지 쉽게 짐작할 수 있습니다.  

Semantic URL을 사용하면 

  • 깔끔한 URL을 유지할 수 있습니다.
  • 사용자가 URL을 기억하기 쉽습니다.
  • 주요정보를 변수로 처리하지 않고 디렉토리 인 것처럼 다루므로 SEO 에도 도움이 됩니다. 

이 모든 장점은 Semantic URL 자체가 충분히 의미적일 때 가능합니다. 

여기에 프로젝트 관점에서의 Semantic URL의 활용을 생각해봅니다. 

1. 어휘(Vocabulary)의 통일

프로젝트마다 내부에서 통용되는 어휘들이 있습니다. 하지만 역할에 따라 비슷하지만 전혀 다른 어휘들을 사용하기도 합니다.

예를 들어 회원가입 페이지를 두고

  • 기획자 : (PPT를 보며) “사용자(user)가 이 곳을 클릭해서 가입(sign up) 합니다.”
  • 프론트엔드 개발자 : (HTML/JS 소스를 보며) “이 버튼에 onclick 이벤트가 발생하면 POST로 넘겨줍니다”
  • 개발자 : (백엔드 소스를 보며) “account table에 insert 합니다”

회원가입 페이지 하나를 두고도 각 담당자가 사용하는 어휘가 이렇게도 다양합니다. 기획자의 user와 개발자의 account 는 비슷한 의미를 가지지만 다른 어휘들로 표현될 수 있습니다. 기획자의 user는 개발자의 입장에서는 account 뿐 아니라 session 까지 포함하는 상위개념이라고도 할 수 있겠네요. 

Semantic URL은 일반적으로 “/user/signup”, “/board/(show)list” 과 같이 주체(Subject) 혹은 객체(Object)의 행동(Action)까지 한 덩이로 이루어 집니다. 여기서 주체와 객체는 프로젝트 내의 주요개념에 대응하고, 행동은 기능에 대응시킬 수 있을 것입니다. 

개념 기능 URL
사용자  가입  /user/join 
  탈퇴  /user/leave 
  정보 수정  /user/update 
게시판  리스트  /board/(게시판이름)/list 
  글 보기  /board/(게시판이름)/(글번호) 
  글 수정  /board/(게시판이름)/update/(글번호)  

기능정의에서부터 Semantic URL을 활용하면, 프로젝트에서 통용되는 개념과 기능을 일관성있고 쉽게 파악할 수 있지 않을까요? 

2. 산출물들 간 디렉토리 구조 및 파일 이름을 통일 

디자인 – 프론트엔드 – 백엔드에 이르기까지 프로젝트 구성원들은 서로다른 네이밍 노하우를 가지고 있습니다. 따라서 이에 대한 가이드가 없다면 “회원가입.psd”, “join.html”, “signup.jsp”, 심지어 “project_0001.html” 에 이르기까지 구성원들 수 만큼이나 다양한 파일이름이 등장합니다. 문제가 생겨 파일들을 뒤져보려고 하면 “기획서의 이 페이지가 어떤 파일이에요?” 를 반복해야 합니다. 커뮤니케이션 로스가 생깁니다. 

생각해보세요. 문제가 생기면 해결하는데 시간을 온전히 쏟아도 모자랄텐데 그에 앞서 메신저로 파일명을 물어보거나, 메일에서 파일이름을 검색하고 있는 것은 한심하지 않나요? 

Semantic URL 을 디렉토리 – 파일 구조로 대입해 user/signup.psd, user/signup.jsp, user/signup.html 로 산출물을 구조화하면   서로의 산출물을 열람하기가 월등히 쉬워질 겁니다. 파일이름이 곧 용도이므로, 전달하면서 “이 파일은 이런 용도고 기획서에서 어떤 이름 이고 ..”  와 같은 군색한 메일을 적을 이유가 없습니다.  

결론

도메인네임은 http://kthcorp.com/ 처럼 회사를 대표하거나 http://im-in.com 처럼 프로젝트를 대표합니다. Semantic URL은 하위 URL을 구조화합니다. 하지만 많은 사람들이 도메인네임에는 수많은 고려를 하면서도 하위 URL에 대해서는 등한히 하는 경우가 많습니다. URL 을 결정하는 일은 막상 개발이 시작되고 난 후, 개발자의 몫이 될 때가 있습니다. 이런 경우는 곧 개발자의 작명센스(?)나 경험, 인터넷 한영사전에 의해 URL이 결정됩니다. 

하지만 개념과 기능을 정의하는 작업은 기획시기 부터 이루어지는 작업입니다. 따라서 Sementic URL에 대한 고민은 이 때부터 시작되어야 한다고 생각합니다. 서비스에 의미를 부여하는, 게다가 SEO 에까지 영향을 미치는 작업을 개발자의 잠깐 고민으로 결정해버릴 수는 없으니까요.  

ps : 저는 영어를 못하는데요! 라고 걱정하시는 분이 있다면, 페이스북에서 제공하는 ‘Translations’ 이 참고할만 합니다. 예를 들어 “탈퇴”라는 키워드를 검색하면 굉장히 다양한 표현들이 등장합니다. 적합한 표현을 찾아 프로젝트만의 사전을 만들어두는 것도 좋은 방법이 될 수 있습니다. 

맥에서 hosts 파일 관리 – Gas Mask

Gas Mask 스크린샷

프론트엔드 작업에서는 hosts 파일을 다루어야 하는 일이 많은데요, 관리하는 프로젝트가 많아질 수록 복잡해지기 마련입니다.

그동안 Terminal 에서 vi 를 통해 hosts 파일을 관리했었습니다. 조금 더 쉽게 관리하는 방법이 없을지 살펴보다 Gas Mask 라는 프로그램을 알게 되었습니다. Gas Mask 는 OSX 에서 hosts 파일을 쉽게 관리하도록 도와주는 어플리케이션 입니다.

주요기능은

  • Syntax Highlight 를 지원하는 에디터
  • 외부에 hosts 파일을 두면 자동 업데이트 가능
  • 전역 단축키 지원

등 입니다.

가장 큰 특징은 hosts 파일을 여러 개 두고 전환해가며 사용할 수 있다는 점입니다. 개발 – 테스트 – 스테이징 – 실서버에 이르기까지 각 개발 단계마다 hosts 파일이 변경되어야 하는 경우를 편리하게 관리할 수 있습니다.

당장 한번 사용해보세요.

http://www.clockwise.ee/gasmask/