Rev. 2.73

Robert Nyman씨는 새로운 파이어버그(Firebug) 확장기능인 파이어파인더(Firefinder)를 배포했습니다. CSS 선택자 또는 XPath를 이용하여 DOM 요소를 빠르게 찾을 수 있게 해 주는 확장기능입니다. 위 화면에서 보는 것 처럼 찾아진 DOM 요소 주변에 빨간 점선으로 표시되고 결과 목록위로 마우스 커서를 가져가면 파란 점선으로 강조합니다. 매번 콘솔을 이용하여 쿼리를 날렸는데 이 짓은 더이상 안해도 되겠군요.

Comments

smile.gif

Jabbify API를 이용해서 뭔가 재미있는 뻘짓을 해 보려고 계속 구상만 하다가 이 번 주말에 맘잡고 삽질했습니다. 자연스레 공통 관심사를 가진 사람을 만나고 즉시 질문하거나 추가적인 정보를 소통할 수 있는 커뮤니케이터이자 상대방의 모습을 아이-트래킹의 방식으로 비주얼라이즈하는 아이디어에 착안하여 만들어 보았습니다. 화면속을 요리조리 떠돌아 다니는 스마일 유령들이 바로 트래커입니다. 이 곳에 접속해 있는 사용자들의 마우스 커서 위치와 접속중인 페이지의 주소 그리고 제목을 스마일 유령을 통해 공유하여 해당 사용자가 위치한 곳으로 즉시 이동하거나 조회 중인 페이지의 제목을 알 수 있고 간략한 메시지를 주고 받을 수도 있습니다. 여기에 사용된 스마일 유령은 100% CSS로 작성된 것으로 나라디자인에서 콘테스트황준상님의 스마일의 마크업을 변조한 것이에요. 덕분에 이미지 파일을 사용하지 않고도 다양한 색상의 유령들을 동적으로 생산할 수 있게 되었습니다. 코드는 Prototype기반 클래스로 작성되었고 아래와 같은 방식으로 구동됩니다.

사용방법 :

<script type="text/javascript" src="/javascripts/prototype.js"></script>
<script type="text/javascript" src="/javascripts/jabbify.js"></script>
<script type="text/javascript" src="/javascripts/eyestracker.js"></script>
EyesTracker({
    name: 'your name', // 사용자 이름 (default: random)
    color: 'c30', // 유령 색상 지정 (default: random)
    timeout: 100, // 포인터 멈춤, 연결 갱신 시간 간격 (default: 240ms)
    callback: function(pkt) {...} // 갱신시 호출되는 콜백
});

다운로드 :

* original - eyestracker.js (9.1kb)
* minified - eyestracker.js (7.1kb)

업데이트 :

* 2009.5.16 - 사용자가 떠난 경우 해당 유령을 실시간으로 사라지게 했습니다.
* 2009.5.16 - IE7에서도 유령을 볼 수 있습니다.
* 2009.5.16 - IE8에서 발생하던 오류가 수정되었습니다.
* 2009.5.17 - 머물러 있는 페이지의 제목을 툴팁으로 출력합니다.
* 2009.5.17 - 소리 효과를 추가했습니다. 툴팁이 표시하거나 메시지를 수신할 때 소리로 알립니다.
* 2009.5.17 - 메시지 송/수신 기능을 추가했습니다. 개인 또는 모두에게 메시지를 주고 받을 수 있습니다.
* 2009.5.17 - IE에서 툴팁 영역이 표시되지 않던 문제를 수정하였습니다.
* 2009.5.17 - 같은 페이지를 조회 중인 유령을 약간 강조했습니다.
* 2009.5.17 - 메시지 수신시 유령이 화면에서 벗어난 경우 위치를 보정합니다.
* 2009.5.17 - 전체 송신 체크박스의 설정을 기억합니다.
* 2009.5.17 - 이름/색상/타임아웃/콜백을 인스턴스 생성시에 설정할 수 있도록 했습니다.
* 2009.5.17 - 툴팁의 위치가 화면을 벗어나지 않도록 보정합니다.
* 2009.5.18 - soundmanager2 라이브러리가 로드되지 않은 경우 소리 재생을 하지 않습니다.
* 2009.5.19 - 흰색 유령은 관리자입니다. ^^;
* 2009.5.25 - 인스턴스화할 필요가 없으므로 Prototype의 클래스를 제거하였습니다.
* 2009.5.27 - 메시지 송/수신시 메시지 박스가 즉시 사라지는 문제를 수정하였습니다.

Comments

kangax씨는 또다시 재미있는 함수를 만들었습니다. 브라우저별로 특징을 가지는 CSS 프로퍼티의 지원여부를 분석하는 함수입니다. "BorderRadius" CSS 프로퍼티를 지원하는 브라우저에서만 사용되도록 스크립트를 작성할 수 있게 하는 것입니다. 이것은 아래와 같은 원리로 지원여부를 분석할 수 있습니다.

var el = document.createElement('div');
typeof el.style.marginLeft == 'string'; // true
typeof el.style.marginLeft2 == 'string'; // false

'marginLeft' in el.style; // true
'marginLeft2' in el.style; // false

그리고 다음과 같이 성능까지 고려한 함수로 작성하여 사용할 수 있게 하였습니다.

var getStyleProperty = (function(){
 
  var prefixes = ['Moz', 'Webkit', 'Khtml', 'O', 'Ms'];
  var _cache = { };
 
  function getStyleProperty(propName, element) {
    element = element || document.documentElement;
    var style = element.style,
         prefixed,
         uPropName;
 
    // check cache only when no element is given
    if (arguments.length == 1 && typeof _cache[propName] == 'string') {
      return _cache[propName];
    }
    // test standard property first
    if (typeof style[propName] == 'string') {
      return (_cache[propName] = propName);
    }
 
    // capitalize
    uPropName = propName.charAt(0).toUpperCase() + propName.slice(1);
 
    // test vendor specific properties
    for (var i=0, l=prefixes.length; i<l; i++) {
      prefixed = prefixes[i] + uPropName;
      if (typeof style[prefixed] == 'string') {
        return (_cache[propName] = prefixed);
      }
    }
  }
 
  return getStyleProperty;
})();

예를 들어 DOM 요소를 기울이거나 모양 자체에 변형을 가할 수 있는 "transform" CSS 프로퍼티는 최신 브라우저들(Safari3, FF3.5, Chrome2)에서만 사용할 수 있습니다. 이 CSS 프로퍼티의 지원여부를 알아내려면 "getStyleProperty('transform')"을 호출하는 것으로 단방에 처리할 수 있게 되는 것입니다. 멋지죠?

var transform = getStyleProperty('transform'); // MozTransform
if (transform) element.style[transform] = 'rotate(90deg)';

덧. 아래는 Prototype에서 사용될 수 있도록 직접 수정한 코드입니다.

Element.addMethods({
  getStyleProperty: (function(){
    var prefixes = ['Moz', 'Webkit', 'Khtml', 'O', 'Ms'], _cache = {};
    return function(element, propName) {
      if (!propName) {
        propName = element;
        element = document.documentElement;
      }

      var style = element.style, prefixed;
      // check cache only when no element is given
      if (arguments.length == 1 && typeof _cache[propName] == 'string')
        return _cache[propName];
      // test standard property first
      if (typeof style[propName] == 'string')
        return (_cache[propName] = propName);

      // test vendor specific properties
      for (var i = 0, l = prefixes.length; i < l; i++)
        if (typeof style[prefixed = prefixes[i] + propName.capitalize()] == 'string')
          return (_cache[propName] = prefixed);
    }
  })()
});

$('element').getStyleProperty('transform'); // MozTransform
Element.getStyleProperty('transform'); // MozTransform

Comments