기본 콘텐츠로 건너뛰기

tutorial - radio button을 이용한 tree 구조 만들기

http://jsbin.com/cikuga/edit?html,css,output IE 호환을 위해 jQuery를 사용했다. 안해도 되지만 이 편이 그래도 좀 읽기 쉽지 않나 싶다. 접히고 펼쳐지는 트리구조를 만드는 데 있어 핵심 아이디어는 같은 깊이에 인접한(sibling ) 요소들끼리는 radio button을 사용하면 된다는 것이다. 가령 <input type="radio" name="group1"> <input type="radio" name="group1"> <input type="radio" name="group1"> 이렇게 했을 경우 같은 이름(name)을 가지고 있으므로 셋 중 하나만 radio 버튼이 들어오고 <input type="radio" name="group1"> <input type="radio" name="group2"> <input type="radio" name="group2"> <input type="radio" name="group2"> <input type="radio" name="group1"> <input type="radio" name="group1"> 이와 같이 구성하면 group2는 group2끼리 group1은 group1끼리 각각 구성할 수 있다. 따라서 각각의 radio button에 대한 id가 1   1-1   1-2 2   2-1     2-1-1     2-1-2 3 일 경우엔 1,2,3을 top 1-1, 1-2는 1 2-1은 2 ...

Meteor DDP subscribe 처리 시 주의할 점

Meteor에서 logout 시 독특한 패턴으로 websocket이 날아오기 때문에 주의해야한다. 먼저 logout을 보내면 ["{\"msg\":\"method\",\"method\":\"logout\",\"params\":[],\"id\":\"3\"}"] 가입 되있던 모든 publish에 영향 받는 collection이 removed 된다. a["{\"msg\":\"removed\",\"collection\":\"users\",\"id\":\"ySWmTt329QeLQZTEc\"}"] 80 23:56:26.494 ......... a["{\"msg\":\"ready\",\"subs\":[\"CPSzK3DsirQq4fSmo\",\"87ojrAZZKFwu9LTeH\",\"5ynAG9oTZg7i3DMCs\",\"KZBaQRzyPiF33BoLz\",\"w3JwjFeWaFmxXiiaL\",\"ZM9oXYRjZ7cfSxvMY\",\"Q7XAmPJC35NjLdBYL\"]}"] 189 23:56:26.529 정체불명의 subs 가 array로 뭉텅 날아오고 a["{\"msg\":\"updated\",\"methods\":[\"3\"]}"] 46 23:56:26.530 logout method 에 대한 updated 와 a["{\"msg\":\"res...

decaffeinate hack - Rx.js 를 import 해보자!

http://decaffeinate-project.org/repl 평소에 coffee를 좋아하지만 ecma6로 바꿔서 보여줘야 좋아하는 분들이 종종 있어서 decaffeinate를 쓰다보니 나름 console.log 만 띡 나오는게 꽤 쓰기 좋아서 자주 쓰는데. 쓰다보니 아쉬운 점이 외부 라이브러리를 불러올 수가 없어서 약간의 hack을 해보기로 했다. script = document.createElement('script') script.src = "//cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.0-rc.2/Rx.js" x=document.getElementsByTagName('script')[0] x.parentNode.insertBefore script, x 단순하게 생각하면 이런 식 script tag을 하나 만들고 src를 Rx.js CDN 라이브러리로 지정하고 insertBefore를 사용해서 밀어넣으면 될거라고 생각했는데 repl.js?t=2015-03-09T08:30:22-07:00:7 Uncaught Error: module is not supported in the browser, you need a commonjs environment such as node.js/io.js, browserify/webpack etc 이런 오류가 난다. 보니까 의도적으로 decaffeinate에서 "module", "exports", "require" 이라는 말을 쓰면 저지하도록 되있더라   ["module", "exports", "require"].forEach(function(commonVar){     Object.defineProperty(window, commonVar, {       get: function () {         throw n...

Bluestacks OS X를 android 개발용으로 쓰는 법

먼저 docker 를 설치했다면 꺼준다. 둘 다 가상화를 쓰는 시스템이라 충돌한다. vi ~/Library/Preferences/com.BlueStacks.AppPlayer.plist 로 들어가서 width 와 height 부분을 바꿔준다. <key>Width</key> <integer>420</integer> <key>Height</key> <integer>700</integer> 420x700 으로 바꾸면 720p 노트북에서 그럭저럭 볼만하다.

RxJS - ReactiveX 인터뷰

A: 왜 RxJS입니까 B: javascript는 참 쉽고 친숙한 언어죠. A: 별로 그렇게 생각 안합니다만. B: 그래서 좀 어렵고 있어보이는게 뭘까 싶어서... A: 네? B: 함수형이라는게 유행하기도 하고 f(x) 좋쟎습니까? 미스테리~ 미스테리~ 정수정짱짱 으아아 이런 수학선생님이라면 수포자 따윈 A: ... B: 그리고 반응형이라는 말 뭔가 A: 뭔가? B: 대충대충해도 막 알아서 할거 같고... A: 그럴리가요? B: 안그렇겠죠? A: 네 B: 네 (잠시만 기다려주세요) A: 그래도 뭔가 매력이 있으니 이렇게 시간을 내셔서 이것저것 Rx에 대해 글도 쓰고 이야기도 하고 그러시는거 아닌가요? B: 매력이라. 으음. 제가 팔꿈치 터널 증후근이 좀 있어요. 오른손 세끼손가락, 약지손가락이 저립니다. A: 무슨 상관이? B: 그래서 각종 괄호를 쓰는게 너무 힘듭니다. 소중대괄호 만든 사람 죽었으면. Hello world (ASCII): https://esolangs.org/wiki/Parenthesis_Hell A: 이미 옛날에 돌아가셨겠죠. B: 그렇겠네요. 아무튼 그래서 소중대괄호 의존이 적은 커피스크립트를 쓰는데요. A: 빨리 본론을 말씀해주시죠. B: 커피스크립트에서 가로로 80자 이상쓰면 Line exceeds maximum allowed length 라고 경고해요. A: 그래서요? B: 근데 Rx를 쓰면 코드를 가늘게 쓸 수가 있더라구요. A: 호오? B: 그리고 = 쓰는 것도 너무 힘듭니다. A: 네? B: 오른손을 쓰쟎아요. A: ... 그러니까 정리하면 1. 괄호가 힘들다 2. 커피를 쓴다 3. 커피는 길게 쓰면 경고 4. Rx를 쓰면 코드가 가늘다 5. 대입문을 줄이고 싶다. B: 네 하지만 5번은 생각보다 별로... A: B: B: 아! A: ? B: 코드가 가늘어서 좋은 점이. A: 네. B: 핸드폰에서 코드를 보...

RxJS 에서 requestAnimationFrame 을 사용하려면?

http://jsbin.com/qosigic/edit?html,js,output 소스는 이쪽. 게임과 같은 분야는 타이밍 처리가 매우 중요하기 때문에 UI를 갱신하는 무한 루프를 놓고 delta 시간을 얻어와서 처리하는 로직을 많이 쓰는데 이걸 Javascript 에서 할 땐 전통적으로 setTimeout 을 걸어놓은 함수를 재귀하는 식으로 썼는데 문제는 setTimeout(setInterval도 마찬가지)이 굉장히 부정확한 타이밍을 가지고 있었고 이를 보완하기 위해 requestAnimationFrame 이라는 것을 만들어 사용하기 시작했다. 문제는 역시 지원하지 않는 몇몇 브라우저(ex. IE < 10)들 때문에 안타깝게도 RxJS 5.x 의 defaultScheduler에선 setTimeout( https://github.com/Reactive-Extensions/RxJS/blob/6dac0365ad22f87a92197fc4dcee70e72a11ddbb/src/modular/scheduler/defaultscheduler.js#L119 )을 쓰고 있는데 물론 권장하는 방식은  https://github.com/Reactive-Extensions/RxJS/tree/8fa95ac884181fb6cbff8ce7c1d669ffb190f5e4/examples/crop  의 예처럼 RequestAnimationFrameScheduler 를 사용하는 것이지만 RxLua 처럼 기본으로 타이머가 없고 외부패키지에 의존하는 환경도 있고해서 기본 RxJS 환경에서 직접 만들어보기로 했다. Scope 을 위해 일단 function으로 감싸보았다. (function() {   var canvas=document.getElementById('canvas1');   var ctx = canvas.getContext('2d');   var start = 0;   var step = functi...

RxJS Basic - 기초

http://reactivex.io/rxjs/manual/tutorial.html  글을 대충 번역해서 쓰는 글입니다. jsbin/codepen 같은 곳에서 RxJS 라이브러리를 추가한 후 연습해봅시다. 현재 가장 최근 버전은  https://cdnjs.com/libraries/rxjs/5.0.0-rc.1  에서 확인하세요. Observable 로 변환하기 하나 혹은 n 개의 값으로부터 Rx.Observable.of('foo', 'bar'); =>foo =>bar 배열로부터 Rx.Observable.from([1,2,3]); =>1 =>2 =>3 이벤트로부터 Rx.Observable.fromEvent(document.querySelector('button'), 'click'); =>button을 누를 때 마다 event로 변환 Promise로부터 Rx.Observable.fromPromise(fetch('/users')); =>/user 주소의 내용을 fetch한 것을 변환 마지막 인자가 콜백인 경우 콜백으로부터 /* node.js */ var exists = Rx.Observable.bindCallback(fs.exists); exists('file.txt').subscribe(exists => console.log('Does file exist?', exists)); var rename = Rx.Observable.bindNodeCallback(fs.rename); rename('file.txt', 'else.txt').subscribe(() => console.log('Renamed!')); Observable 만들기 외부로부터 새로운 이벤트를 생성한다. var myObservable = Rx.Subject.create(); myObserv...