Rev. 2.73

scriptaculous.jpg

Script.aculo.us를 만든 Thomas Fuchs씨가 RailsToItaly 07에서 발표한 Script.aculo.us 2.0 슬쩍 미리보기(PDF, ~3 MB)라는 슬라이드입니다. 슬라이드만 봐서는 어떤 내용을 강연하셨는지는 잘 알 수 없군요. 우선 Prototype 1.6에 기반하여 개발되며, Operator가 추가되어 CSS 기반으로 된 사용자가 만든 애니메이션 효과를 재사용할 수 있게 하고, transitions의 사용방법을 간편화 하며, 북마크릿 기반의 자체적인 콘솔이 추가되는 등의 내용입니다. 콘솔에서는 엘리먼트 강조, 이벤트 로깅, Firebug를 필요로 하지 않으며, 어떠한 브라우저에서도 사용할 수 있다고 하네요. 미리보기판을 곧 릴리즈 하신다고 합니다. 그나저나 시연하신 코드를 보니 기존의 코드를 대대적으로 변경해야하는 난관이 들이닥칠지도 모르겠습니다.

$('foo').morph({
  duration: 0.5,
  transition: 'easeFromeTo',
  change: function() {
    $('foo').update('Lorem ipsum dolor sit amet...');
    $('foo').addClassName('error');
  }
});

Comments

Remy Sharp씨는 jQueryPrototype 프레임웍의 차이점을 대조하는 슬라이드를 공개했습니다. 플래시로 만들어진 이 슬라이드는 Utility 함수들과 셀렉터, DOM 교정, DOM 작업, 이벤트, Ajax 송/수신, 그리고 브라우저 구분에 사용되는 코드만을 대조하고 있습니다.

기능상의 차이점 보다는 작동원리와 문법에 대한 내용을 주로 다루고 있으며, 자바스크립트 프레임웍 선정에 도움이 될만한 내용들로 구성되어 있습니다. Prototype은 1.6대 버전에 들어서면서 사용성이 좋아지긴 했지만 jQuery가 추구하는 사용성과는 차이가 있어보입니다.

Comments

Mislav Marohnić씨는 Ruby기반의 블로그 도구인 Radiant CMS를 Prototype 1.6.0으로 교체하는 작업을 진행하면서 기존에 사용하던 Prototype APIs가 어떻게 변경하는지에 대한 이해하기 쉬운 예제를 공개했습니다. DOM, Event, Class, Hash 크게 4부분으로 나누어 설명하고 있으며, 그 내용은 다음과 같습니다.

DOM 노드 찾기와 교정하기

// before:
this.tab_container = document.getElementsByClassName('tabs', this.element).first();
// after:
this.tab_container = this.element.down('.tabs');
// returns all elements under the current element matcing the selector
this.element.select('.tabs');

// before:
new Insertion.Bottom(
  this.tab_container,
  '<a class="tab" href="javascript:TabControl.controls[\'' + this.control_id + '\'].select(\'' + tab_id + '\');">' + caption + '</a>');
// after:
this.tab_container.insert(
  '<a class="tab" href="javascript:TabControl.controls[\'#{id}\'].select(\'#{tab_id}\');">#{caption}</a>'.interpolate({
    id: this.control_id, tab_id: tab_id, caption: caption
  })
);

// before:
divs = $$("div.tag-description");
$A(divs).each(function(div){ Element.show(div) });
// after:
$$("div.tag-description").invoke('show');

// before:
var sibling = row.nextSibling;
// after:
var sibling = row.next();

// before:
Element.removeClassName(row, 'children-visible');
Element.addClassName(row, 'children-hidden');
// after:
row.removeClassName('children-visible');
row.addClassName('children-hidden');

// before:
onMouseOverRow: function(event) {
  this.className = this.className.replace(/\s*\bhighlight\b|$/, ' highlight');
},
onMouseOutRow: function(event) {
  this.className = this.className.replace(/\s*\bhighlight\b\s*/, ' ');
},
// after:
onMouseOverRow: function(event) {
  this.addClassName('highlight');
},
onMouseOutRow: function(event) {
  this.removeClassName('highlight');
},

// before:
isExpander: function(element) {
  return (element.tagName.strip().downcase() == 'img') && /\bexpander\b/i.test(element.className);
},
// after:
isExpander: function(element) {
  return element.match('img.expander');
},

// before:
initialize: function(element_id) {
  var table = $(element_id);
  var rows = table.getElementsByTagName('tr');
  for (var i = 0; i < rows.length; i++) {
    this.setupRow(rows[i]);
  }
}
// after:
initialize: function(element_id) {
  $(element_id).select('tr').each(this.setupRow, this)
}

이벤트 핸들링

// before:
Event.observe(row, 'mouseover', this.onMouseOverRow.bindAsEventListener(row));
Event.observe(row, 'mouseout', this.onMouseOutRow.bindAsEventListener(row));
// after:
row.observe('mouseover', this.onMouseOverRow);
row.observe('mouseout', this.onMouseOutRow);

클래스와 상속

// before:
var SiteMap = Class.create();
// Inherit from RuledTable:
SiteMap.prototype = Object.extend({}, RuledTable.prototype);
Object.extend(SiteMap.prototype, {
  ruledTableInitialize: RuledTable.prototype.initialize,
  initialize: function(id, expanded) {
    this.ruledTableInitialize(id);
    this.expandedRows = expanded;
  },
  ...
});
// after:
var SiteMap = Class.create(RuledTable, {
  initialize: function($super, id, expanded) {
    $super(id);
    this.expandedRows = expanded;
  },
  ...
});

해시 API

// new Hash instance:
this.tabs = $H();
// old style:
this.tabs[tab_id] = tab;
var object = this.tabs[something];
// new style:
this.tabs.set(tab_id, tab);
var object = this.tabs.get(something);

Comments