Tag Archives: Front-end

브라우저 자동완성 기능의 미래

Form element 에 autocomplete 기능이 소개된 것은 1999년 Internet Explorer 5이 최초였다. 이후 각 브라우저 별로 산발적으로 지원하던 자동완성 기능은 HTML5에 이르러 표준화 되었다.

HTML5 스펙은 2012년 12월 17일 버전으로 기준으로 함.

이전 스펙에서 autocomplete attriute 는 “on” 또는 “off” 값만 가질 수 있었으나 최근의 스펙에서는 on, off 외에 공백으로 분리된 토큰들을 가질 수 있다. 이에 따르면 attribute 이 on, off 가 아니라면 아래와 같은 순서로 동작한다.

  1. 첫 8글자가 “section-” 으로 시작하는 경우 필드가 이름을 가진 그룹에 속함을 나타낼 수 있다. (선택사항)

예를들어, 양식에 두개의 배송주소가 있을 때 아래처럼 마크업 할 수 있다.

<fieldset>
 <legend>Ship the blue gift to...</legend>
 <p> <label> Address:     <input name=ba autocomplete="section-blue shipping street-address"> </label>
 <p> <label> City:        <input name=bc autocomplete="section-blue shipping region"> </label>
 <p> <label> Postal Code: <input name=bp autocomplete="section-blue shipping postal-code"> </label>
</fieldset>
<fieldset>
 <legend>Ship the red gift to...</legend>
 <p> <label> Address:     <input name=ra autocomplete="section-red shipping street-address"> </label>
 <p> <label> City:        <input name=rc autocomplete="section-red shipping region"> </label>
 <p> <label> Postal Code: <input name=rp autocomplete="section-red shipping country"> </label>
</fieldset>
  1. 어떤 토큰은 둘 중 하나일 수 있다. (선택사항)

    • shipping 은 이 필드가 배송 주소 또는 연락처 정보의 일부임을 나타냄
    • billing 은 이 필드가 청구 주소 또는 연락처 정보의 일부임을 나타냄
  2. 다음 두 옵션 중 하나

    • 어떤 토큰이 아래 autofill field string 중 하나:
      • “name”
      • “honorific-prefix”
      • “given-name”
      • “additional-name”
      • “family-name”
      • “honorific-suffix”
      • “nickname”
      • “organization-title”
      • “organization”
      • “street-address”
      • “address-line1”
      • “address-line2”
      • “address-line3”
      • “locality”
      • “region”
      • “country”
      • “postal-code”
      • “cc-name”
      • “cc-given-name”
      • “cc-additional-name”
      • “cc-family-name”
      • “cc-number”
      • “cc-exp”
      • “cc-exp-month”
      • “cc-exp-year”
      • “cc-csc”
      • “language”
      • “bday”
      • “bday-day”
      • “bday-month”
      • “bday-year”
      • “sex”
      • “url”
      • “photo”
  • 아래 순서대로
    1. 어떤 토큰이 아래 값들 중 하나 (선택사항)
      • home, work, mobile, fax, pager
    2. 어떤 토큰이 아래 autofill field 스트링 중 하나
      • tel, tel-country-code, tel-national, tel-area-code, tel-local, tel-local-prefix, tel-local-suffix, tel-extension, email, impp

즉, 이 스펙에 따르면 아래와 같은 경우의 수가 존재한다.

<input name="country" autocomplete="on">
<input name="country" autocomplete="off">
<input name="country" autocomplete="country">
<input name="country" autocomplete="shipping country">
<input name="country" autocomplete="section-a shipping country">
<input name="billing_home_tel" autocomplete="section-a billing home tel">

이런 상세한 분류를 통해 브라우저가 앞으로 더 강력한 자동완성기능을 갖게 될 것이다.

예를 들어 명세서 청구주소는 집이지만, 배송은 회사에서 받게 되는 경우가 있을 수 있다. 이런 경우 billing 에 집 주소, 집 연락처가 저장될 것이고 shipping 에는 회사 연락처 등이 저장되는 형태로 세분화가 가능해질 것이다.

참고

SSI를 이용한 HTML 산출물 모듈화

개요

SSI 는 Server Side Include 의 약자로, 웹서버에서 직접 제공하는 서버사이드 스크립트 언어 입니다.

PHP, ASP, JSP 등도 서버사이드 스크립트 언어의 범주에 들어가지만, SSI 는 대부분의 웹서버에서 직접 지원하고, 문법이 HTML 형식이라는 특징이 있습니다.

문법을 살펴보면,

<!--#include virtual="../quote.txt" -->

와 같이 HTML 의 주석 문법에 #을 붙인 형태로 지시자를 작성하고, attirubte 을 사용해 파라미터를 전달합니다.

일반적인 지시자들

일반적으로 많이 사용하는 지시자들 입니다.

#include
다른 파일을 이 파일 내부로 불러들이기
#exec
외부 명령 실행
#set
변수 선언
#echo
변수 프린트
#if, #else, #elif, #endif
조건문

특징

대부분의 웹서버에서 동일 문법으로 사용 가능

Apache, Nginx, Tomcat, Web sphere 등 다양한 웹 서버에서 동일한 문법으로 사용 가능합니다. 확인결과 Apache, Nginx, Tomcat 에서는 설치가 필요하지 않고, 설정만으로 곧바로 사용 가능합니다.

제한된 기능

SSI 는 간단한 스크립트를 작성하는데 최적화 된 언어입니다. 반복문이 없고, 모든 문법이 HTML 주석을 포함한 형태여서 코드가 길어집니다. 따라서 복잡한 작업에는 어울리지 않습니다.

활용방안

기능이 작고, 대부분의 웹서버와 호환된다는 면에서 HTML 산출물의 모듈별관리에 매우 적합합니다. 게다가 문법이 웹 퍼블리셔에게 친숙한 HTML 문법으로 작성하므로 러닝커브 면에서 꽤 괜찮은 선택입니다.

KTH FI팀에서는 현재 SSI를 활용해 HTML을 모듈별로 관리하고 있습니다.

HTML 의 모듈화는 서버사이드 언어의 지원을 받지 않으면 실현 불가능한 명제 입니다. 그래서 많은 퍼블리셔들이 반복되는 부분에 대해 아얘 모듈화하지 않거나, PHP 같은 언어의 지원을 받아 구현을 합니다.

아직 모듈화하고 있지 않다면 꼭 고려해보세요.

HTML 산출물을 작성할 때 Plain HTML 을 사용한다면 반복되는 코드는 모두 중복될 수 밖에 없습니다. 이 방법은 다른 파일에 의존성없이 완전한 결과물을 볼 수 있다는 장점이 있지만, 중복되는 부분에 변경이 발생하면 일괄 변경해야 하는 어려움이 있습니다.

모듈화된 HTML 을 사용하면

  • 변경이 간편해집니다.
  • 모듈을 퍼블리셔가 직접 지정하므로 개발자와의 커뮤니케이션 공수가 줄어듭니다.
  • 파일 내에서 공통 부분이 차지하는 코드의 양이 적어지므로 실제로 작업할 내용에 대해 집중도가 높아집니다.

만약 다른 방법으로 목적을 달성하고 있더라도 한번 고려해보세요.

사실 SSI는 이미 많이 알려진 방법이고, 굉장히 오래 전에 사용되었던 방법입니다. 하지만 시선을 HTML 산출물의 모듈관리로 돌려보면 이보다 좋은 솔루션을 찾기 어렵습니다.

  • 러닝커브가 크지 않습니다.
  • 대부분의 웹서버에서 동작합니다.
  • 웹서버에 언어모듈을 올리지 않아도 되므로 더 간단한 구조로 구현할 수 있습니다.
  • (물론 mod_includes 모듈이 로드되어야 하긴 하지만, 나도모르는 사이에 로드되어 있는 경우가 많고, 모듈 크기도 더 작습니다)

기능이 제한된다는 것은 일견 나쁠 수도 있지만 다시 생각해보면 장점으로 생각할 수도 있습니다. 단 몇가지를 위해 기능이 과도하게 많은 언어를 사용하는 것은 닭잡는데 소잡는 칼을 쓰는 것과 다르지 않기 때문입니다.

사용해보기

설정

설정은 아파치를 기준으로 합니다.

.htaccess 설정

# +Includes 를 넣었습니다. 이것은 httpd.conf 에서 <Directory> 설정을 상속받아 Includes를 추가해주어야 하므로
# Options Includes 가 아니라  Options +Includes 입니다.
# .htaccess 를 사용하려면 <Directory> 에서 AllowOverride All 로 설정하세요.
AddOutputFilter INCLUDES .html
Options +Includes

Include 사용해보기

설정이 끝나면 간단히 include 문을 테스트 해봅니다.

미리보기: http://code.elegantcoder.com/blog-examples/SSI/html5_boilerplate.html

본체- html5_boilerplate.html

  • include 문을 주의해서 봐주세요.

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <!--#include virtual="_header.html" -->
        <title>html5_boilerplate</title>
      </head>
    
      <body>
        <div>
          <header>
            <h1>html5_boilerplate</h1>
          </header>
          <nav>
            <p>
              <a href="/">Home</a>
            </p>
            <p>
              <a href="/contact">Contact</a>
            </p>
          </nav>
    
          <div>
    
          </div>
    
          <footer>
            <!--#include virtual="_footer.html" -->
          </footer>
        </div>
      </body>
    </html>
    

header – _header.html

     <meta charset="utf-8" />

    <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
    Remove this if you use the .htaccess -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

    <meta name="description" content="" />
    <meta name="author" content="elco" />

    <meta name="viewport" content="width=device-width; initial-scale=1.0" />

    <!-- Replace favicon.ico & apple-touch-icon.png in the root of your domain and delete these references -->
    <link rel="shortcut icon" href="/favicon.ico" />
    <link rel="apple-touch-icon" href="/apple-touch-icon.png" />

footer – _footer.html

<p>
&copy; Copyright by elco
</p>

그 외의 활용 예

User-Agent Sniffing

모바일 웹에서 User Agent Sniffing 이 필요한 경우 JS를 사용하거나 다른 서버사이드 언어에 의존할 수 밖에 없는데, SSI 는 이런 간단한 작업에 적합합니다. Server 변수들은 바로 SSI 에서 사용가능하고, Apache 의 mod_rewrite 를 통하면 URL 에 따른 변수 지정도 가능합니다.

미리보기- http://code.elegantcoder.com/blog-examples/SSI/user-agent.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>User Agent Sniffing Example</title>
    </head>
    <body>
        <h1>User Agent Sniffing Example</h1>
        <div><span>User-agent String:</span><span><!--#echo var="HTTP_USER_AGENT" --></span></div>
        <!--#if expr="$HTTP_USER_AGENT = /Chrome/" -->
        <!--#set var="ua_result" value="Chrome" -->
        <!--#elif expr="$HTTP_USER_AGENT = /Safari/" -->
        <!--#set var="ua_result" value="Safari" -->
        <!--#elif expr="$HTTP_USER_AGENT = /Firefox/" -->
        <!--#set var="ua_result" value="Firefox" -->
        <!--#elif expr="$HTTP_USER_AGENT = /MSIE/" -->
        <!--#set var="ua_result" value="Internet Explorer" -->
        <!--#endif -->
        <div><span>so, u r using : </span><span><!--#echo var="ua_result" --></span></div>
    </body>
</html>

참고

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 부분을 변경해 서버 하나에 프로젝트마다 또는 각 사용자마다 아이디를 줄 수 있다.

북마클릿의 활용

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