가끔 웹페이지에 걸려있는 링크를 타고 들어가 보면 타이머를 걸어 놓고서 일정 시간이 지난 후에야, 가령 특정 form의 자료 입력과 같은, 작업을 진행할 수 있게 해 놓은 곳과 마주치곤 한다. 보통 링크 클릭을 통한 광고와 수익의 창출을 목적으로 이런 현상이 퍼지는데, 이럴 때마다 불편함과 함께 은근 짜증을 일으키게 한다.

그래서 이런 때를 대비해서 아래와 같은 JavaScript timers의 지연 시간을 아주 짧게 써는 실험 목적의 주문을 만들어 봤다. 주문이 잘 먹히면 더딤 없는 쾌속 진행의 길을 뚫을 수 있다. (물론, 사이트에서 어떤 추가 확인장치를 해 놓은 곳이라면 이것도 별 소용이 없겠지만.)

var originalInterval = this.setInterval, originalTimeout = this.setTimeout;
this.setInterval = function(func, delay) {
  originalInterval(func, 10);
};
this.setTimeout = function(func, delay) {
  originalTimeout(func, 10);
};

이를 이용한 간편 사용 목적의 bookmarklet: fastTimer – 가속기가 달린 고장난(?) Timer.

꼬리표:

CSS3에서 새로 소개된 rem(root em) unit은 em unit과 마찬가지로 상대성을 띤 Relative length units 중 하나지만, 기존 부모 요소를 기준으로 한 em unit과 달리 root element, 그러니까 html element를 기준으로 그 크기 값이 정해지면서 부모 요소의 중첩으로 생기는 뻥튀기의 부작용을 걱정할 필요가 없다는 것이 장점이다.

그래서, 어느 하나의 요소를 기준으로 또 다른 요소의 상대적 크기를 정해주고 싶을 때 많이 사용되는데, 문젠 언제나 그렇듯 IE < 9을 포함해서 아직 만족스럽지 못한 rem unit의 브라우저 지원 상황을 고려해서, 미지원 브라우저에서도 인식되도록 적절한 대응 값을 함께 정의해 줘야 하는 성가심이 있다.

이런 상황에서 SaasLESS 혹은 Stylus와 같은 CSS pre-processor의 힘을 빌린다면 효율적인 CSS 작성에 큰 도움이 된다는 것은 이미 잘 알려져 있다. 하나의 좋은 본보기로, CSS pre-processor를 써서 rem unit의 fallback을 구현한 예.

한편 아래는 실험 삼아 지금 한창 논의되고 있는 CSS VariablesCalc() function만을 써서 rem unit의 fallback을 구현해 보았는데, 여기에 꼭 안성맞춤으로 CSS polyfill임을 자처하면서 지금 한창 개발중인 또 하나의 CSS preprocessor인 Myth의 힘을 빌려서 바로 적용해 보았다.

:root {
  var-base-font-size: 10;
  var-body-font-size: 14;
  var-heading1-font-size: 18;
}

html {
  font-size: calc(var(base-font-size) / 16 * 100%);
}

body {
  font-size: calc(0px + var(body-font-size));
  font-size: calc(0rem + var(body-font-size) / var(base-font-size));
}

h1 {
  font-size: calc(0px + var(heading1-font-size));
  font-size: calc(0rem + var(heading1-font-size) / var(base-font-size));
}

이렇게 작성된 CSS는 Myth를 통해 다음과 같이 변환된다.
CSS Variables와 Calc() function을 써서 rem unit의 fallback 구현하기 제목의 글 마저 읽기 »

보통 JavaScript function을 작성하다 보면, 경우에 따라 딱히 정해져 있지 않은 수의 parameters를 받아서 처리해야 할 때가 있다. 이럴 땐, 아래 코드처럼 전달된 각 parameter의 타입을 확인해서 전달받지 못한 놈은 미리 정해진 기본값을 지정해서 사용하는 패턴이 많이 쓰인다.

function foo(a, b) {
  a = typeof a !== 'undefined' ? a : 'default_a';
  b = typeof b !== 'undefined' ? b : 'default_b';
  ...
}

이런 사용 패턴의 쓰임새가 점점 늘어남에 따라, ECMAScript 6에선 parameters에 default values를 아주 쉽게 지정할 수 있는 용법이 제안되었는데, 그 사용 예를 들면 다음과 같다.

/* ECMAScript 6에 포함된 Default Function Parameters */
function multiply(a, b = 1) {
  return a * b;
}

multiply(5); // 5

참고로, ES6의 default function params 웹브라우저 지원 상황을 보면, Firefox(v.15 이상)에서만 지원해서 아직 실제로 사용하기엔 이른 아쉬움이 있다.

그런데 이렇게 function에 전달할 parameters의 개수가 가령 세 개 이상으로 늘어나면 이에 대응하는 각 parameter의 타입을 확인하는 과정도 늘어날 수밖에 없고, 또 전달된 parameters의 순서도 그 결과 값에 중대한 영향을 미치게 된다. 이는 실제 function 사용 시 parameter의 순서를 착각해서 다르게 전달한다면 커다란 문제를 일으키게 될 소지가 있으므로 주의해야 한다.
JavaScript function의 default parameters 설정 법 제목의 글 마저 읽기 »

JavaScript 실행 환경에서 global에 새로운 변수를 등록할 때는 또 다른 제3의 스크립트가 등록한 변수와의 있을지 모를 충돌을 피하려는 노력의 하나로 지극히 제한되게 그 사용을 최소화하도록 권장하고 있다. JavaScript의 기본 문법에는 Module을 구현하는 기능을 갖추고 있지 않아서 (ECMAScript 6th Edition, Harmony에선 Module System이 추가될 전망), 이를 비슷하게나마 구현하기 위한 여러 패턴이 소개됐으며 그 중 가장 널리 쓰이는 패턴이 바로 Rrevealing Module Pattern이다.

아래는 개인적으로 이 패턴에다 IIFE를 더 해서 쓰고 있는 snippet.

;(function(global, doc, nameSpace, undefined) {
  'use strict';
  
  var privateVar = 1;
  var privateMethod = function(args) {
    
  };
  
  nameSpace.publicMethod = function(args) {
    
  };
  
  global.nameSpace = nameSpace;
}(this, this.document, this.nameSpace || {}));

JavaScript의 function scope와 closures 덕분에 function 안에 선언된 methods나 variables는 기본적으로 외부에 노출되지 않어서, 그 안의 또 다른 function 이외엔 접근할 수 없도록 차단되어 있는데, 그 중 원하는 것만 꼭 집어서 global에 하나로 공개된 자기만의 namespace가 가지고 있는 property에다 갖다 붙여준다. 이렇게 하면 global 환경에 공개된 기존의 variables와 methods 이름과의 충돌을 최소화할 수 있다.

맨 앞에 희한하게 붙어 있는 세미콜론(;)은 JavaScript 로딩 속도를 최소화하려고 압축해서 다른 스크립트 파일과 하나로 합치는 과정에서, 만약에 다른 스크립트 파일에 있는 마지막 statement 끝에 세미콜론이 빠져있을 경우, 합치는 과정에서 IIFE가 함수 arguments로 오인되는 일을 미리 방지하기 위한 것인데, 이와 관련된 자세한 내용의 글. – IIFE Leading semicolon

남의 밭에서 신발 끈 묶을 땐 항상 조심스럽게.

JavaScript 파일을 웹페이지에 추가하는 방법은 여러 가지가 있는데, 과거엔 주로 head tag에다 추가해 줄 때가 많았으나, 이렇게 하면 브라우저가 JavaScript 파일을 다 읽어 들이는 동안 웹페이지의 렌더링이 잠깐 멈추게 되는 부작용이 있어서, 최근엔 웹페이지를 되도록 빠르게 화면에 뿌려주려고 body tag 마지막에 얹어 주는 것을 권장하고 있다.

그런데 최근 날로 웹 애플리케이션의 개발과 그 활용 방법론이 많이 알려지면서 JavaScript 파일이 점점 더 커지는 경향이 있는데, 무조건 내려받게 되는 이런 JavaScript 파일의 용량을 조금이라도 줄이려는 노력도 따라서 필요해진다. 그래서 페이지에 얹어진 JavaScript 파일 중에 특정 기능이 빈번히 사용되지 않고 특별한 경우에만 쓰이는 것이라면, 이마저도 주요 JavaScript 파일에서 빼어내 특정 조건에 따라 필요할 때만 로딩해주는 기술이 쓰일 수 있다.

jQeury에선 이럴 때에 꼭 안성맞춤인 jQuery.getScript() 함수를 제공하고 있는데, 사용법은 다음과 같다.

$.getScript("ajax/test.js", function(data, textStatus, jqxhr) {
   console.log(data); //data returned
   console.log(textStatus); //success
   console.log(jqxhr.status); //200
   console.log('Load was performed.');
});

jQuery를 쓰지 않고 일반 JavaScript로 구현하려면 javascript_loader.js를 참고해서 구현해 볼 수도 있다.
웹페이지 로딩 후, 필요할 때에만 특정 JavaScript 파일을 읽어 들이는 방법 제목의 글 마저 읽기 »