Regular Motion

개발자가 상팔자

Tag: JavaScript (page 1 of 5)

Small Tips When You Develop Chrome Extension

  • Content Scripts가 Inject되는 타이밍을 정의 할 수 있다.
    manifest.json의 content_scripts의 속성 중 run_at 속성으로 content_scripts 파일이 Inject되는 시점을 정의 할 수 있다. run_at의 값으로는 document_start, document_end, document_idle 세가지가 올 수 있다. 기본으로 document_idle이 적용되며 Inject되는 시점은 아래와 같다.

      • document_start: DOM이 생성되기전 또는 다른 Script들이 실행되기전에 Script가 Inject 된다. Inject하려는 Script가 1빠로 실행되어야 하면 이 타이밍을 노려보자.
      • document_end: DOM 생성이 완료 된 후, Script가 Inject된다.
      • document_idle: document_idle은 시점이 불명확한데, document_end 이벤트와 window.onload 이벤트가 Fire된 직후 그 사이에 Script가 Inject 된다. 따라서 document_idle로 Inject되는 경우 window.onload 이벤트를 받지 못 할 수 있다.

    * 예전에 Supreme 자동구매 봇을 만든적이 있는데, (참고로 Supreme의 인기 신상은 1~2초 싸움이다) run_at:document_idle에서 제품을 담고, 결제하도록 했을 때와 run_at:document_end:에서 제품을 담고, 결제하도록 했을 때의 성공 확률이 크게 차이났었다.

 

  • Content Scripts는 Web Pages의 DOM에 접근 및 제어가 가능하나, JavaScript Context는 별도로 존재한다.
    Web Pages와 Content Scripts는 각각 별도의 JavaScript Scope를 갖기 때문에, Content Script에서 Web Pages의 변수나 함수를 사용 할 수 없고, Web Pages에서도 Contents Scripts의 변수나 함수에 접근 할 수 없다.  허나  Content Scripts에서 Web Pages의 DOM에 접근 및 제어가 가능하다.  DOM을 제어 할 수 있다는 사실은 실로 대단한 가능성을 내포하고 있다.

 

  • Content Scripts는 Chrome Extension의 Popup과 Background Scripts와 localStorage를 공유하지 않는다.
    localStorage도메인 별로 독립된 저장공간을 사용한다. Content Scripts는 Web Pages와 같은 도메인에서 실행되고, Popup과 Background Scripts는 chrome-extension://으로 시작하는 도메인에서 실행된다.  따라서 Content Scripts와 Popup, Background Scripts는 localStorage를 통해 데이터를 공유 할 수 없다.
    * 글로 적으면 당연한 사실인데 만들다보면 왠지 공유가 될 것 같다. 희망은 이성을 초월하는 것 같다.만약 반드시 Content Scripts와 Popup, Background Scripts간 데이터를 저장/공유해야 한다면 localStorage 대신 chrome.storage를 사용해야 한다. * 알 수 없는 이유로 10분을 허비하기 싫으면, manifest.json의 permissions에 storage 추가하는 것을 잊지 말자.
    사용법은 https://developer.chrome.com/extensions/storage#property-sync 링크를 참고하면 쉽다;localStorage와 다르게 개발자 도구에서 Inspect/Edit를 제공하지 않는다. (2017/05 기준) 만약 chrome.storage를 Heavy하게 사용 할 예정이라면, Storage Area Explorer를 설치해서 사용해야 한다. 아직 정품이 없다.

 

  • Again, Content Script는 Web Pages의 DOM에는 접근/제어가 가능하나, JavaScript Scope는 별도로 존재한다.
    만약, Web Pages에서 필요한 JavaScript 코드가 있다면 Script Element를 이용해 File 또는 Text를 Inject 하는게 제일 편하다.아래의 코드를 통해 File 또는 Text를 Inject 할 수 있고, Inject 하려는 파일은 manifest.json의 web_accessible_resources에 선언되어야 한다. web_accessible_resources에 선언된 파일에 한해 Web Pages에서 접근 가능하다.

     

Getting Literal with Template Strings.

최근 개발하고 있는 기능 중, JavaScript에서 XML String을 생성하는 부분이 있다.  해당 코드는 Template화된 XML String에서, 필요한 값들을 replace하는 방식으로 구현되어 있었다.
문제는 Template에 replace 해야 할 값들이 많을 수록 코드의 미적인 부분과 성능적인 부분이 함께 추락하는 방식이었다.
아래의 코드는 위의 예시와 72% 정도 유사하다.

생성해야 할 XML Template을 String으로 선언한 뒤, 변수로 치환되어야 할 값들을 String.prototype.replace()를 통해 치환하는 구조다.  쉽고, 나름 직관적이다.  사실 크게 문제가 있는 코드라고 보기는 어렵다. 하지만 위에서 언급했듯 치환되어야 할 값들이 늘어나면 replace chaining이 늘어나며 뭔가 문제가 생길 것 같은 불안감을 내포하는 코드다.

그래서 위 코드를 깔끔하게 개선하고 싶어 약간의 조사를 해보니 ES6의 Template Strings을 활용하면 매우/훨씬 깔끔한 코드로 수정 가능 할 것 같았다.  (정말 약간의 조사로 알게되어 애초에 왜 저렇게 구현했나 자괴감이 들었다)

실제로 위 코드를 ES6의 Template Strings을 활용하여 수정한 코드는 아래와 같다.

문장을 감싸는 부호를 single quotes(‘)에서 back-ticks(´)으로 대체했고, 값들을 치환하는 replace() chaining 구문이 사라졌다. (JavaScript 엔진에 의해 자동으로 치환된다는 의미다.)
코드가 간결해졌다는 것은 시력이 0.2 이상인 사람은 모두 육안으로 확인 가능하고, 성능이 빨라졌다는 것은 간단한 Benchmark를 통해 증명 가능하다.  (https://jsfiddle.net/6xnutcsd/)
* 위의 예제는 크롬에서 7~10배 정도의 성능 향상이 있으며, 치환되어야 할 값들이 많을수록 성능 개선 효과도 크게 나타났다.

 

예제로 글을 시작했으니, 이제 문법과 활용 범위에 대해 알아보자.
(글 끝부분의 Reference 링크를 참고하시는게 더 낫다)

Syntax
Template String은 일반적으로 String을 감쌀 때 사용하던 single quote(‘)나 double quote(“) 대신 back-ticks(`)을 사용하면된다.  쉽다;


String Substitution
문자열에 JavaScript Expression을 삽입 할 수 있는 String Substitution은 Template String의 가장 큰 장점이라고 할 수 있다. 심지어, 거의 모든 JavaScript Expression이 허용되며,  치환/처리가 필요한 Expression을 중괄호{}로 감싼 뒤, 앞에 달러($)를 붙여주기만 하면 된다. (아, 이놈의 자본주의, 그놈의 돈돈돈)

Expression에는 단순히 변수의 이름이나, 간단한 수식은 물론이고, Instance의 property나 method등 일반적인 JavaScript Expression 대부분 허용된다. (개발자한테 참 좋은데, 설명할 방법이 없다.)

Tagged Templates
Tagged Templates은 함수를 이용하여 Template String의 출력을 변형하기 위한 목적으로 사용 할 수 있다. 사용법은 함수의 이름 뒤에 Template String을 선언하면 된다. 그러면 함수의 첫번째 인자로 Template String의 문자열이 Array 형태로 전달되고, Expression이 순서대로 함수의 인자로 전달된다.

상상력이 미천한건지 아직까지 Tagged Templates의 활용할 코드는 발견하지 못했다.

 

References

 

Bootstrap #1 Boot Bootstrap

{ What is ‘Bootstrap’? }

Twitter 개발자들에 의해 개발된 front-end toolkit으로써, Button, Navigation, Label, Typhography, Alert 등의 기본 UI Component와 유용한 Interaction을 제공한다.

http://twitter.github.com/bootstrap/

장점

  • 간단한  Markup 작업으로 Rich하면서 Responsive한 UI를 구성할 수 있다.
  • 타 UI Framework에 비해 더 나은 성능을 보여준다.

 

{ Bootstrap Components }

Bootstrap에서 기본적으로 제공하는 UI Component들은 아래와 같다.

Button, Navigation, Labels, Badges, Typography, Thumbnails, Alerts, Progress Bars, Miscellaneous

 

{ Import Bootstrap }

Bootstrap의 구성은 아래와 같다.

  • bootstrap.css :  Basic Element들과 UI Component들의 CSS 속성이 정의되어있다.
  • bootstrap-responsive.css : UI Component들이 Responsive하게 구성되도록 정의되어있다.
  • bootstrap.js : Bootstrap이 지원하는 Javascript Plugin들을 하나로 합쳐 놓은 파일.
  • jquery.js : bootstrap은 jQuery Plugin으로 구현되어 있기 때문에 jquery를 포함해줘야 한다.
* 필요한 Javascript Plugin만 따로(Ex : bootstrap-transition.js, bootstrap-alert.js) import 할 수도 있다. 

 

{ more about… }

 

[Javascript] draglist.js : Drag가능한 List Library.

Project 진행 중 Drag가능한 List Library가 필요해서 한번 만들어봤습니다.

– SourceCode & Simple Usage –

https://github.com/RegularMotion/draglist

– Demo –

* 개인적으로 Chrome, FF, Opera, Safari, IE(8.0), iOS, Android에서 정상 동작 확인하였습니다.

  • A
  • B
  • C
  • D
  • E
  • F



[Javascript] draggable.js : Drag & Drop Library.

Project 진행 중 Drag&Drop Library가 필요해서 한번 만들어봤습니다.

– SourceCode & Simple Usage –

https://github.com/RegularMotion/draggable

– Demo –

* 개인적으로 Chrome, FF, Opera, Safari, IE(8.0), iOS, Android에서 정상 동작 확인하였습니다.

http://the-next.tv/draggable/ 

– Drag & Drop Library ‘draggable’을 구현하면서 배운 3가지 – 

1. Object 또는 Pointer의 위치를 Tracking할 필요가 있는 경우 Event Listener를 등록할 때 함수대신 Object를 넘겨주고 

    Object에 handleEvent 함수를 override하는 것이 좋다.

아래와 같은 방식으로 구현할 경우 Object 변수에 closure를 발생시키지 않고 접근할 수 있기 때문에

Object변수를 Tracking할 필요가 있는 경우 이점이 되는 것 같습니다.

2. ‘touchmove’나 ‘mousemove’의 경우 지나치게 자주(1초에 100회 이상) 호출되는 함수이기 때문에 해당 함수의 listener를 가볍게 구현하거나, 그렇지 않은 경우 filtering을 해주는 작업이 필요했습니다.

전부 처리할 경우 Android Device에서 버벅거림이 심해지는 것 같습니다.

저는 20ms이내에 다시 호출될 경우 listener가 동작하지 않도록 pending 변수를 두었습니다.

3. Javascript에서 css의 z-index값을 수정할 경우 style[“z-index”]가 아닌 style[“zIndex”]를 사용해야
모든 브라우저에서 동일하게 동작함.

‘draggable’이 다른 분들께 도움이 되었으면 합니다.

Older posts

© 2017 Regular Motion

Theme by Anders NorenUp ↑