
ç§ã¯äžæ žä»¥å€ã®æè²ãš10幎以äžã®çµéšãæã€Webéçºè
ã§ãã ç§ã¯é¡§å®¢ã®ããã«ãæã«ã¯äžåžã«ããèµ·ãããªããŠã§ãã®ããã«ãã¹ãŠãããŸããã ãã®ä»äºã倧奜ãã§ãã ããããããã§ãç§ã¯ãŸã£ããç¬ããã«ããããšãããã€ããããŸãã ãããã®1ã€ã¯ãã¡ã€ã«ã¢ããããŒããŒã§ãã æåãã-ããã誰ã«ãèµ·ãããã«ajaxã«ãªã£ããšã-ãããŠä»ãŸã§-ããã¯åçã®ãµã€ãºã倿Žããããã€ãã®ã¹ããªãŒã ã«ãã¡ã€ã«ãã¢ããããŒãããã¯ããã«-ããã¯ç§ã«ãšã£ãŠæãæãããŠããªãã¿ã¹ã¯ã®1ã€ã®ãŸãŸã§ã ãªããšãåŠçã§ããããã§ãã èå³ãããã°ãç«ãžããããã
ã¡ãã£ãšããCoffeescriptãjQueryã«é¢ããããªãã®äžæºã$ .Deferredã®ç°¡åãªèª¬æãã€ã³ãã¬ãŒã¹ãšã¢ãŠããªããã¬ãŒã¹ã®äžæ³šæã«é©çšããããã¿ãŒã³ããããŠé¢çœãé¢çœãæ¬ãžã®ãªã³ã¯ãããªããåŸ
ã£ãŠããŸãã
ãããã£ãŠãç§ãã¡ã®åã®ã¿ã¹ã¯ã¯ããã¡ã€ã«ã¢ããããŒããŒããµã€ãã«ã¢ããããŒãããããšã§ãã ãã¡ãããAJAXã¯ãã¡ãããé²è¡äžã§ãããã¡ãããæ¢ã«å®æãããã¶ã€ã³ã§ãã ãããã-ãªããããåé¡ãªã®ã§ããïŒ ã¯ãã¹ãã©ãŠã¶ã å€ãè¯ãããªãã¯ïŒi-frameã§ã®a-laéä¿¡ãã©ãŒã ïŒã¯é²æ©ãããããããæ°ãããã®ïŒxhr.sendïŒã¯å€ããã©ãŠã¶ã§ã¯æ©èœããŸããã ãã©ãŠã¶ã®
æšæºåã çªç¶åæ¢ããã¯ãã¹ãã©ãŠã¶ã®åé¡ãæ»ãªãªãããã«ãšãã
åžæããããŸããã 远å ã®ã¿ã¹ã¯ã¯ããã©ãã°ã¢ã³ãããããã§ãã input'aã®å€èгã«ã¯ãŸã åé¡ããããŸãã
ã©ã®ãããªãªãã·ã§ã³ããããŸããïŒ
æ¹æ³No. 1ãGoogleäž»å°ã®éçº
Shustrenkoã¯ãå¿
èŠãªãã¹ãŠã®æ©èœãå®è£
ããããªã人æ°ã®ããjQueryã©ã€ãã©ãªãŒãgoogleããŸãã ã¢ãããŒãã¯æéã®äžè¶³ã§æ£ããã§ãã ãããžã§ã¯ãã«éåžžã«è¿
éã«çµ±åããããã©ãŠã¶ãšã®äºææ§ãå¿é
ãããã©ãŒããããããDOMã衚瀺ããŸãã çµå±ã®ãšãããDOMãã¹ã¿ã€ã«ã§åå å·¥ããŠãåé¡ã¯ãããŸããïŒjQueryã䜿çšããŠãããããäž»ãªå°éåéã§ãããïŒãæ©èœã«ã€ããŠèå³ã®ããé¢ä¿è
ïŒãã¯ããããã§ã¯ãããŸãããããããå¶çºçã«çºçãããããã®çš®é¡ãèŠãŠãã ãããæ¬åœã«ãããã§ããïŒãïŒã ãããŠããã¹ãŠãã¹ãŒããŒã§ããããã«èŠãããã¹ãŠãçŽ æŽãããããã§ãã 1æ¥éããããåŠçããŠãã¹ãã«æž¡ãããšã¯ããªãå¯èœã§ãã ãããããã®åŸ...æåã®ããã¡ã¯ãã¶ã€ããŒããé£ã³åºããŸã-ããã€ãã®æå§«ãåºãŸããïŒèª°ããããŠã³ããŒããäžæããããå¥ã®ãããšããŸããã¯ãªç¶æ³ãäœãåºããŸããïŒ ãããããã®divã¯è¡šç€ºãããªãã£ããããæ§ããã«èšã£ãŠãããã®divã®ã¹ã¿ã€ã«ã¯ãŸã£ããåãã§ã¯ãããŸããã ãã¶ã€ããŒã®åœç¶ã®éé£ãæ¶åãããã¹ã¿ãŒã®ä»£è¡šå£ã®å°çã芳å¯ããŸãã äŒæ¥ã®æšæºã«ããããŠãŒã¶ãŒã®XXããŒã»ã³ãïŒããã³æã䟡å€ã®ãããŠãŒã¶ãŒïŒãåããŠããçŽ æŽããããã©ãŠã¶ãŒã§ã¯ãé²è¡ç¶æ³ã衚瀺ãããŸããã ãã©ãŒ ãã¹ã¿ãŒãå°çã«éã£ãŠãã ããïŒããã©ãŠã¶ããµããŒãããŠããªãå Žåãã©ãããã°ããã§ããïŒãïŒãåå©ã®è¡šæ
ã§ãããã®ããã¯ãã¹ãããããŸãïŒãVkontakteã¢ããããŒãã¯ãã®ãã©ãŠã¶ã§åäœããŸãïŒã ãããŠãã®ç¬éããããžã§ã¯ãã«å¯ŸããŠææªã®ç¯çœªã®1ã€ãç¯ããŸãããã®çŽ æŽããããã©ã°ã€ã³ã®ãœãŒã¹ã³ãŒãã«ã¢ã¯ã»ã¹ããŸãã ïŒãªãã·ã§ã³ãšããŠãæšå¹Žããåã«ãã©ã°ã€ã³ãã©ãã«ãŒã§ãã®ãšã©ãŒã«é¢ããã¡ãã»ãŒãžãèŠã€ããéãè¯ããã°ããã®ç¹å®ã®åé¡ããã©ã°ã€ã³ããäœããã®æŸèæãèŠã€ããŠãã ããïŒã å®éãããã¯ããã°ã©ããŒã»ã©æããªãã ããªãã¯èª°ãã®ã³ãŒããèªãããšãåŠã¶ã§ããã-æã«ã¯è¯ããæã«ã¯...ç°ãªãã ãããã¬ãŒãããäžåºŠäœ¿çšããŸãã jQueryã®ãã©ã°ã€ã³éçºè
ã«ã€ããŠæªãããšãèšãããã¯ãããŸããã ç§ãåºäŒã£ãã»ãšãã©ã®å Žåã圌ãã®ã³ãŒãã¯éšå€è
ããµããŒãããããã«èšèšãããŠããªãã ãã§ãã ãããããããžã§ã¯ãã®ã¿ã€ãã³ã°ãçãå§ããå¯èœæ§ããããŸãã æéããªãããããã®ãªãã·ã§ã³ãéžæããããšãèŠããŠããŸããïŒ
ããã§ãããŸã ãã©ã°ã€ã³ããã©ã°ã€ã³ããŠããå Žåã¯ããããžã§ã¯ããªããžããªã«ãã©ã°ã€ã³ã®çž®å°ããŒãžã§ã³ã®ã¿ãæ®ããŠãã ããã ãŸãããã©ã°ã€ã³ãµã€ããžã®ãªã³ã¯ãã©ãã«ãæ®ããªãã§ãã ããã
èŠçŽïŒãã¶ã€ã³ãšæ©èœãè£ãããšãã§ããå Žåã«ã®ã¿ã銎æã¿ã®ãªããã©ã°ã€ã³ã䜿çšããŸãã ãŸãããŸãã¯ãã¶ã€ããŒãä»ã®ãã¹ã¿ãŒã®åŸ©//ãã¬ãŒãã³ã°ã®ããã«ã ãŸãã¯ããªããŒã¹ãšã³ãžãã¢ãªã³ã°ã¹ãã«ã®ãã¬ãŒãã³ã°ãšããŠã
ãã¹çªå·2ãå±¥æŽ
ãïŒ å幎åãç§ãã¡ã¯ãã§ã«ãã®ãããªãã®ãæžããŸããã ãªã©ã³ã人ïŒã®ãªã·ã£äººããªãŒã¹ãã©ãªã¢äººããã«ã·ã£äºº...ïŒ ç·è²ã®æ¥å圢ã®é²è¡ç¶æ³ããŒããŸã ãããŸããã å€ããããžã§ã¯ããéããŸãïŒå¥ã®ã³ã³ãã¥ãŒã¿ãŒãçãå°œãããªããžããªãŒãããã³ããã»ã©åçŽã§ã¯ãªãå¥ã®100500ã®çç±ïŒã ã¢ããããŒããŒãèŠããç
ã®çš®é¡ã ãããŠãã...æåã«-ææ°ã®ãã©ãŠã¶ã®ã¿ã®ãµããŒãã æ¬¡ã«ãã¯ã©ã€ã¢ã³ãåŽã®ãã©ãã·ã¥ã®ãµã€ãºå€æŽã 第äžã«ããã®æãèšæ¶ã«æ®ãæ¥å圢ïŒãã¶ã€ããŒã¯ã¹ã«ã ã§ãïŒïŒé²è¡ç¶æ³ã¯ã¢ããããŒããŒã³ãŒãèªäœã«çµã¿èŸŒãŸããŠããŸãã 4çªç®ã5çªç®ãªã© ããã«ããã®ç¹å®ã®ãããžã§ã¯ãã®è©³çŽ°ã®æã åã³ã®èгç¹ãã-ãŸããæ°·ã§ã¯ãããŸããã å幎ã®ããŒã«ããã¯-çŸä»£ã®æè¡ã®å±±ã®é«ãã«æèãé£ã°ãã®ã§ã¯ãªãã
èŠçŽïŒé¢çœããªãã 6ãæåã«ç¬¬äžäººè
ã§ãããé«å質ã®ã³ãŒãã®ã¿ãæäŸãããšããŠãããšã«ããã¯ãŒã«ã«ãªããŸããã
ãã¹çªå·3ãäºæ³å€ã®
ããã§ã¯ãå°ã倢ãèŠãŠã¿ãŸãããã äœã欲ããïŒ ïŒããŒã«ãé£äººãç«ã«å ããŠïŒã å°ãªããšã-ã¢ããããŒããŒãäœãããã§ãã æå€§éãäžåºŠã ãé·ãéãããããšæã£ãŠããŸãã çŸåšã®ãããžã§ã¯ãããç°¡åã«åãåºããŠãæå°éã®å€æŽã§æ¬¡ã®ãããžã§ã¯ãã«è²Œãä»ããããšãã§ããŸãã ã¡ãªã¿ã«ããã®æ¬²æ±ã¯ãEricãšElizabeth Freimenovã«ãããDesign Patternsããšãã1ã€ã®é¢çœãå°ããªæ¬ã«è§ŠçºãããŠããŸãã ããããããã¯èª°ããèªãã¹ã4人çµã®ãªãªãžãã«ã®æ¬ã§ã¯ãããŸããã ãã®ãã1ã€ã®æ¹ãã¯ããã«ç°¡åã§ãã ããã»ã©åŒ·ããªãããèªã¿ãããã èè
ãèªè
ã®é ã«è¿œã蟌ãããšããæåã®ååã®1ã€ã¯ãå€åããŠãããã®ãã«ãã»ã«åããããšã§ãã ç§ãã¡ã®å Žåãã¢ãŒããã¯ãã£ã®æãå¯å€çãªåŽé¢ã¯ããµãŒããŒã«ããŒã¿ãéä¿¡ããæ¹æ³ã§ããå¿
èŠããããŸãïŒããã ãã§ãªããåŸã§è©³ãã説æããŸãïŒã èŠããŠãããªããjQueryãã©ã°ã€ã³ã®åã«ãã®åé¡ã«ã€ããŠè°è«ããŸããã ãããã£ãŠããµãŒããŒã«ããŒã¿ãéä¿¡ããããã®ã¡ã«ããºã ã®ããŒã«ãäœæãïŒããå€ãã®OOPã®å®åŒåãå¿
èŠãªå Žå-å
±éã®ã€ã³ã¿ãŒãã§ã€ã¹ãæã€ã¯ã©ã¹ã®ã»ããããããŸãïŒãã¢ããããŒããŒãšã®å¯Ÿè©±ã€ã³ã¿ãŒãã§ã€ã¹ãå®çŸ©ãããš-1ã€ã®å€§ããªåé¡ã¯ããã€ãã®å°ããªåé¡ã«åå²ãããŸãã ãããŠããããã解決ããããšã¯ãã§ã«ããè¯ãã§ãã ã©ã®ããã«èŠããŸããïŒ éåžžã«ã·ã³ãã«ïŒ
Uploader = senders: [xhrFile, formDataFile, formDataForm, iframe] send: (options)-> stream = false $.each @senders, (i, func)=> if stream = func(options) false stream
2èªã§-颿°ã®é
åãäžŠã¹æ¿ãïŒjavascriptãåãã§ãïŒïŒãå颿°ã«ã¯ãªãã·ã§ã³ããããŸãïŒå®éã«è§Šèšºããå
容ãåãããªãããã倧éšåã¯ïŒãæåã«è¿ããã空ã§ãªãçµæãéä¿¡ã«äœ¿çšãããŸãã ïŒãªãã·ã§ã³ãšããŠãäŸå€ãã¹ããŒããªãã£ãæåã®ãã®ãããæ£ç¢ºã§ããããããŸã§ã®ãšããæ zyã§ããïŒãã®å Žåãæãã䟡å€ã®ããã颿°ã¯é
åã®æåã§ãããæåŸã¯ãã§ã€ã«ã»ãŒãã§ãïŒåãsubmit-form-to-iframeã¡ãœããïŒã ã¯ããdeferredã颿°ãè¿ããšæ¢ã«æšæž¬ããŠããŸã-ãããŠãã¢ããããŒããŒã€ã³ã¿ãŒãã§ãŒã¹ã§ãé¢å¿ã®ãããã¹ãŠã®ãªã¹ããŒããã³ã°ã¢ããããŸãïŒãããŠããããããªãã·ã§ã³ã«æž¡ããŸããïŒã 圌ã¯ã颿°ã®äŸã®åŸããã¿ãã¬ã®äžã§å°ãæ··ä¹±ããŠããããšã説æããŸããã
ããã§ããã®èšäºã®ã³ãŒãã®å質ã«é¢ããæ°è¡ïŒ
-ã³ãŒããjQueryã«é¢é£ä»ããããŠããã®ã¯ãäœè
ããããžã§ã¯ããé
ããæ©ããããã䜿çšãããšèããŠããããã§ã¯ãªããDeferredãå«ãäžå®æ°ã®ãã¢ã¡ããã£ãã®ããã§ãã
-éšåçã«ã³ãŒãã¯1ã€ã®
çŽ æŽããããã©ã°ã€ã³ããåãã
ãŸã ã æ£çŽã«èšããšããã®ãã©ã°ã€ã³ãšãããæ³£ããèªãããšããã¢ã€ãã¢ãçãŸããŸãããããŸãããªãããªãããžãã¯ãå®è£
ããåé¢ãããªãã®ã§ããïŒã
-çŸæç¹ã§ã¯ãã³ãŒãã®ãã¹ãã¯ããªãäžååã§ãããããã¯ã¢ãŒããã¯ãã£ã®åãªãäŸç€ºã§ãã
颿°ã®äŸïŒ
iframe = (options)-> return false unless options.input && options.input.value id = 'frame' + Math.random() $form = $ '<form>', method: options.method, enctype:'multipart/form-data', target: id, action: options.url $('<iframe>', name: id ).appendTo($form).on 'load', -> try response = @contents() throw new Error unless response.length && response[0].firstChild dfd.resolve response, name: options.input.value catch e dfd.reject response, name: options.input.value $form.hide().appendTo('body').submit() (dfd = $.Deferred()).promise()
ããã¯ãå€ããã©ãŠã¶ãŒã®å Žåãšåãã¢ããã¿ã€ã æ©èœã§ãã èŠããã«ããã©ãŒã ãäœæããiframeãç®æããŠãéä¿¡ããŸãã é
å»¶ãè¿ããŸããããã¯ãã¿ãŒã²ããiframeãããŒãããããšã§è§£æ±ºãŸãã¯ãªãã€ã¬ã¯ããããŸãã deferredã«æž¡ãããåŒæ°ã¯ãå€éšãªã¹ããŒã§åä¿¡ãããŸãã å»¶æã®èª¬æãå®å
šã«æç¢ºã§ãªãå Žåãæ¬¡ã®æ©èœã®åŸã«ã¹ãã€ã©ãŒãæè¿ããŸããããã¡ããã
ããã
ããã¥ã¡ã³ãã® æçš¿ãªã©ãèªãããšãã
å§ãã
ãŸã ã
formDataFile = (options)-> return false unless options.files && options.files.length && window.FormData $.when.apply $, options.files.map (f)-> formData = new FormData() formData.append options.name, f xhr = new XMLHttpRequest() dfd = $.Deferred() xhr.onload = xhr.onerror = ->dfd[@status == 200 && 'resolve' || 'reject'] @response, file if xhr.upload xhr.upload.onprogress = (e)->dfd.notify e, file xhr.open options.method, options.url, true xhr.responseType = 'text' xhr.send formData dfd.promise()
ãã§ã«ãã£ãšé¢çœããã®ãããã§ãããã æå®ãããåãã¡ã€ã«ïŒoptions.filesãã©ãããæ¥ãŠããã®äžã«äœããããïŒããšã«ãåå¥ã®XMLHttpRequestãäœæããé
å»¶ããŸãã æåã®äŸã®ããã«ããµãŒããŒããããŒã¿ãããŒãããããã«ãªãã€ã¬ã¯ããŸãã¯è§£æ±ºããŸãã ãã§ã€ã«ã»ãŒãã®æ¹æ³ãšã¯å¯Ÿç
§çã«ã解決/æåŠã«å ããŠããã©ãŠã¶ãæ¯é
ããå Žåãã¢ããããŒãã®é²è¡ç¶æ³ã«é¢ããé
å»¶ããŒã¿ïŒxhr.upload.onprogress =ïŒeïŒ-> dfd.notify eãfileïŒãéä¿¡ããŸãã deferredã䜿çšããŠã$ .whenã䜿çšããŠãããã1ã€ã«ã°ã«ãŒãåããŠæ»ããŸãã ãã®å Žåãwhenã®äœ¿çšãå®å
šã«æ£åœåãããããã§ã¯ãªãã®ã§ãã³ã¡ã³ãã§ãã®çç±ãåãã§èªã¿ãŸãã
å°ããªãã®ã®ããã«å»¶æå€§ãŸãã«èšã£ãŠãé
å»¶ã¯ãã€ãã³ããã³ãã©ãŒã®è¿œå ããããã®ãã³ãã©ãŒã®åŒã³åºãããåé¢ããããã®ã¡ã«ããºã ã§ãã éåæåŒã³åºãã§äœ¿çšãããšéåžžã«ã¯ãŒã«ã§ãã äŸãšããŠãç§ã¯ajaxãªã¯ãšã¹ããæãé »ç¹ã«äœ¿çšãããã»ãšãã©ã®Webããã°ã©ããŒã«éŠŽæã¿ã®ãããã®ãšããŠåŒçšããŸãã 以åã¯æ¬¡ã®ããã§ããã
$.get('/some/url/for/ajax', function(){ alert('got response'); }, function(){ alert('got error'); })
ä»ãã®ããã«ïŒ
var request = $.get('/some/url/for/ajax'); request.done(function(){ alert('got response'); }); request.fail(function(){ alert('got error'); })
äœãå€ãã£ãã®ïŒ ç§ãã¡ã«ãšã£ãŠæãéèŠãªããšã¯ãããªããèŠæ±ãå®è¡ããåã«ãããªãã¯ãã§ã«ããªããçããã©ãããããç¥ãå¿
èŠããããšããããšã§ãïŒãã³ãã©é¢æ°ã¯$ .getã®åŒã³åºãæã«æž¡ãããªããã°ãªããŸããã§ããïŒã ä»ã¯ããªãã§ãã ããã ãªã¯ãšã¹ã倿°ïŒé
å»¶ãªããžã§ã¯ãã¯ãã®äžã«ä¿åãããŸãïŒãã³ãã©ãŒã§ãã³ã°ããããšãã§ããŸã
ãªã¯ãšã¹ãã®å®äºæã«ã 確ãã«ããã³ãã©ãŒã®å³æå¿çã«åããå¿
èŠããããŸãã ããã¯Deferredã®ã¯ã©ã€ã¢ã³ãïŒ "ã³ã³ã·ã¥ãŒã"ïŒåŽã§ã-$ .getã¡ãœããããé
å»¶ãããç¶æ
ãå€åããã®ãåŸ
ã¡ãŸãã ãããŒã¯ããªåŽé¢ãjQueryã®ããã«æããŸãïŒ
var def = $.Deferred(); def.done(function(){
ã¡ãœããã®
解決 -
解決æžã¿ã§ãã æåã®ãã³ãã©ãŒã¯ã解決æžã¿ãç¶æ
ãžã®é·ç§»ã«ãã³ãã©ãŒã远å ãã2çªç®ã®ãã³ãã©ãŒã¯ãªããžã§ã¯ãããã®ç¶æ
ã«ããè¿œå æžã¿ã®ãã¹ãŠã®ãã³ãã©ãŒãåŒã³åºããŸãã
倱æã®2çªç®ã®ãã¢-
æåŠã¡ãœããã¯ããæåŠãç¶æ
ã§ãåãããã«æ©èœããŸã
é²è¡ç¶æ³ã®3çªç®ã®ãã¢-
éç¥ã¡ãœããã¯ãç¶æ
ã倿Žããã«æ©èœããŸãã éç¥ãåŒã³åºããšããã¹ãŠã®é²è¡ç¶æ³ãã³ãã©ãŒãæ©èœããã ãã§ãã
promiseïŒïŒãªã©ã®ä¿è·çãªãã®ããããŸãã ãå²ç€Œãå»¶æãããŠããªãã«æ»ããŸãã ãã³ãã©ãŒããã³ã°ïŒå®äºã倱æãé²è¡ïŒãããããšã¯ã§ããŸãããç¶æ
ã倿Žããããšã¯ã§ããŸããã ããã$ .getãè¿ããã®ã§ãã ãããŠåœç¶ã®ããšã§ãããªããajaxãªã¯ãšã¹ãã®ç¶æ
ãæåã§å€æŽããå¿
èŠãããã®ã§ããïŒ
ã³ãŒããçè§£ããããã«ã$ .whenãåŠçããã®ãè¯ãã§ãããã ããã¯ãé
å»¶ãªããžã§ã¯ãã®ãçµåãã§ãã æ¬¡ã®ããã«æ©èœããŸãã
var def = $.when(a, b, c ....);
$ .whenã䜿çšããå Žåãè€åãªããžã§ã¯ãã«ãã£ãŠãã³ãã©ãŒã«æž¡ãããåŒæ°ã«æ³šæããŠãã ããã 圌ã¯ããããèç©ããŸãã ã€ãŸã 颿°a.resolveïŒ1ïŒããã³b.resolveïŒ2ïŒãåŒã³åºãããå Žåãè€åãªããžã§ã¯ãã®done-listenerã¯åŒæ°ãšããŠ1ã2ãåãåããŸãã ããªãã¯
ãã€ãªãªã³ãæŒå¥ããããšãã§ããŸãã
ãããã
ããã§ããŸãã¯å°ãªããšã
ããã§ãæ®ã眮ãã«ã€ããŠèªãããšããå§ãã
ãŸã ã
éåžžã«æ¡ä»¶ä»ãã§ãç¶æ³ã¯æ¬¡ã®ããã«èª¬æããããšãã§ããŸãïŒãµãŒããŒã«ããŒã¿ãæ°åéä¿¡ããæ©èœãå®è¡ãïŒãã¡ã€ã«ããšã«1åïŒãåã»ã³ãµãŒãæ®ãïŒæ®ã眮ãïŒããããã®ã»ã³ãµãŒããã€ã³ãžã±ãŒã¿ãŒãåãåºããŸãïŒçŽæïŒã 3ãã£ã³ãã«ã®ã»ã³ãµãŒãšã€ã³ãžã±ãŒã¿ãŒããããŸãã
çµéšè±å¯ãªæ³šææ·±ãèªè
ã¯ããã§ã«ãBaïŒ ã ãããããã¯çŸ©åã®é£éã§ãïŒããããŠããã§ããããã¯100ïŒ
æ£ããã§ãããïŒJSã®ç¹æ§ãšããããã£ãšç°¡åã«ããããšãã顿ãèæ
®ã«å
¥ããŠïŒã æçè«è
ã¯ãåãjsã®ãã¿ãŒã³ããããããã«æµåããŸãã ããããç§ãã¡ã¯ãããã«è³ãåŸããŸãããä»ã®äœããç§ãã¡ã«ãšã£ãŠéèŠã§ããã¿ã¹ã¯ã®æ¡ä»¶ããèžããåžžèã«å°ãããŠãç§ãã¡ã¯èªåã§ãã¿ãŒã³ã®å®çŸã«ã»ãšãã©éããŸãããã€ãŸããããã«ã€ããŠå°ãèªãã§ã ã
1ã€ã®åé¡ã解決ããªãã£ãå Žåãåé¡ã解決ããããã®èš±å®¹å¯èœãªæ¹æ³ãèŠã€ããŸããã ç§ãã¡ã«ã¯äœãæ®ã£ãŠããŸããïŒ ãã¡ã€ã«ãèªã¿åãã¿ã¹ã¯ããããŸãã ãã©ãŠã¶ãŒã®æ©èœã«å¿ããŠãå
¥åã§éžæããããã¡ã€ã«ã®ãªããžã§ã¯ããååŸãããããã©ã«ããŒã®å
容ãèªã¿åãããšãã§ããŸãïŒå¿
èŠã«å¿ããŠååž°çã«ïŒã ãŸãã¯ãäœãã§ããŸããïŒãã©ãŠã¶ãæšæž¬ããŸãïŒ-å
¥åããã ãã§ãã ããã«åãããš-äžé£ã®ãªãŒããŒïŒäžé£ã®è·åïŒã圢æããé©åãªæ©èœãéžæããããšã§ãããå埩ããããšããèŠæãçããŸãã ããããã¹ãŠUploadsãªããžã§ã¯ãã«å
¥ããŸãã ããã¯æ¬¡ã®ããã«ãªããŸãã
Uploader = _responsibilityChain: (options, chain, name = false)-> stream = false $.each chain, (i, func)=> if stream = func(options) # Uploader # @[name] = func if name false stream readers: [entry, file, input] read: (options)->@_responsibilityChain options, @readers, 'read' senders: [xhrFile, formDataFile, formDataForm, iframe] send: (options)->@_responsibilityChain options, @senders, 'send'
ãã®ã¡ã«ããºã ã®å®è£
ã¯ãUploaderã®å¥ã®æ©èœã§å®è¡ãããŸããã ãããŠãã€ãã¬ãŒã·ã§ã³ã®ããå
åŽã§ãUploaderãªããžã§ã¯ãã«å¿
èŠãªã¡ãœããïŒèªã¿åããŸãã¯éä¿¡ïŒãšããŠæ¥è¿ãã颿°ãèšå®ããŸãã æ¬¡ã«ãèªã¿åã颿°èªäœãïŒã³ã¡ã³ããšãšãã«ãã©ã°ã€ã³ã³ãŒãããããå€ãã®ç¯å²ã§ïŒèŠãŠã¿ãŸãããã
# input = (options)-> return false unless options.input.value $.Deferred().resolve([]).promise() # - input # , Deferred 3- file = (options)-> files = $.makeArray $(options.input).prop 'files' return false unless files.length if (files[0].name == undefined && files[0].fileName) # File normalization for Safari 4 and Firefox 3: $.each files, (index, file)-> file.name = file.fileName; file.size = file.fileSize; $.Deferred().resolve(files).promise() # -reader. . , .. # Deferred. , entry = (options)-> roots = $(options.input).prop('webkitEntries') || $(options.input).prop('entries') return false unless roots && roots.length > 0 readEntries = (entries, path='')-> $.when.apply($, $.map entries, (entry)-> dfd = $.Deferred() errorHandler = (e)-> e.entry = entry if e && !e.entry # Since $.when returns immediately if one # Deferred is rejected, we use resolve instead. # This allows valid files and invalid items # to be returned together in one set: dfd.resolve [e] resolveHandler = (file)-> # Workaround for Chrome bug #149735 file.relativePath = path dfd.resolve file if entry.isFile entry._file && resolveHandler(entry._file) || entry.file resolveHandler, errorHandler else if entry.isDirectory entry.createReader().readEntries((entries)-> readEntries(entries, path + entry.name + '/' ).done((files)->dfd.resolve files ).fail(errorHandler) , errorHandler) else # Return an empy list for file system items other than files or directories: dfd.resolve([]); dfd.promise() #we do need this pipe here bc we do resolve some files scoped ).pipe -> Array.prototype.concat.apply [],arguments readEntries(roots).promise()
èŠããã«ãå颿°ã¯ç¬èªã®æ¹æ³ã§ãªãã·ã§ã³ããã®å
¥åãã¬ã€ãããé
å»¶ãã¡ã€ã«ãè¿ããŸããããã¯ãèªã¿èŸŒãŸãããã¡ã€ã«ã®ãªã¹ãã§èœã¡çããŸãã
ç±å¿ã§çµéšè±å¯ãªèªè
ã¯ãããã®ã©ããã§ããã®ãã¿ãŒã³ã§ã¯ãªãïŒããšå«ã¶ã¹ãã§ãã ãããŠåã³ãããã¯100ïŒ
æ£ããã§ãããã å
éšã®ããã°ã©ããŒã¯ãããã§äœãããããããšæããŠããŸãã äžéšã®ãªãŒããŒã®äœæ¥ã®çµæã¯ããã¹ãŠã®éä¿¡è
ã«éä¿¡ããããã«éä¿¡ããããšã¯ã§ããŸããïŒããšãã°ãå
¥åãªãŒããŒã®åŸãxhrFileéä¿¡è
ã¯éä¿¡ã§ããŸããïŒã ãŸãã圌ããšãŽããªã³ã ãã®ç¶æ³ã¯ãäžé©åãªéä¿¡è
ã®falseãè¿ãããšã§åŠçãããŸãã ããããéä¿¡è
ã®å
éšã®å
¥åããããŒã¿ãçŽæ¥èªã¿åãããšã¯æ°·ã§ã¯ãããŸãã-å¿ããªãã§ãã ããããŸã Drag'n'DropããããŸããïŒ ä»ã®ãšããããã®ãŸãŸã«ããŠãããŸããããçªç¶å¥è·¡ãèµ·ãããã³ã¡ã³ãã«è³¢æãªã¢ããã€ã¹ã衚瀺ãããŸããïŒ
ãã1ã€ã®æ³šæ-å
¥åãªãŒããŒã¯äœãããŸãã-空ã®é
åã§å»¶æãããé
å»¶ãè¿ããŸãã ããã¯åãªãããã©ã«ãå€ã§ãããUploader.readå
ã§ãã®æ©èœã転éã§ããŸãã çŸããã®ããã«æ®ããã-ãããåäžã
ããã«-èªã¿åããšéä¿¡ããªã³ã¯ãããªãã·ã§ã³ã®ããã©ã«ãå€ã远å ããå¿
èŠããããŸãã ããäžåºŠãUploaderãªããžã§ã¯ãã«é¢æ°ãæ¿å
¥ããŸãã
Uploader: #... , upload: (options)-> options = $.extend method: 'POST' name: options.input && options.input.name , options @read(options).then (files)=>$.when.apply $, @send $.extend options, files:files
ããã§ã¯ãã¹ãŠãç°¡åã§ã-å
¥åãããã¡ã€ã«ãèªã¿åããååŸããå€ããªãã·ã§ã³ã«è¿œå ããUploader.sendã«éä¿¡ããããã®çµæãªããžã§ã¯ããè¿ããŸãã sendããåä¿¡ããé
å»¶ãªããžã§ã¯ãã¯ããã€ãã€ã§ãã°ã«ãŒãåãããã¯ã©ã€ã¢ã³ãã«ã°ã«ãŒãåãããé
å»¶ãªããžã§ã¯ããæäŸããŸãã
ãã¹ãŠã®äœ¿ç𿹿³ïŒ
$('#some-file-input').change -> Uploader.upload(input: this, url: '/files/upload' ) .done -> # alert "#{arguments.length} files uploaded" .fail -> # alert "Some files were not uploaded" .progress -> # (~ 50 ), console.log arguments
ãŸãšã
ã¢ããããŒããŒå
šäœ Senders = _makeForm: (options)-> $('<form>', method: options.method, enctype:'multipart/form-data' ).append(options.input.clone()) _sendData: (options, data, file)-> xhr = new XMLHttpRequest() dfd = $.Deferred() xhr.onload = xhr.onerror = ->dfd[@status == 200 && 'resolve' || 'reject'] @response, file if xhr.upload xhr.upload.onprogress = (e)->dfd.notify e, file else options.no_progress = true xhr.open options.method, options.url + '?name=' + (options.file_name || file.name), true xhr.responseType = 'text' xhr.send data dfd.promise() iframe: (options)-> return false unless options.input && options.input.value options.no_progress = true id = 'frame' + Math.random() $form = Senders._makeForm(options).attr target: id, action: options.url $('<iframe>', name: id ).appendTo($form).on 'load', -> try response = @contents() throw new Error unless response.length && response[0].firstChild dfd.resolve response, name: options.input.value catch e dfd.reject response, name: options.input.value $form.submit() (dfd = $.Deferred()).promise() formDataForm: (options) -> return false unless options.input && options.input.value && window.FormData form = options.input.form || Senders._makeForm(options).get 0 Senders._sendData options, new FormData(form), name: options.input.value formDataFile: (options)-> return false unless options.files && options.files.length && window.FormData options.files.map (f)-> formData = new FormData() formData.append options.name, f Senders._sendData $.extend(options, file_name:f.name), formData, f xhrFile : (options)-> return false unless options.files && options.files.length && window.ProgressEvent && window.FileReader $.map options.files, (file)-> Senders._sendData options, file, file Readers = input: (options)-> return false unless options.input.value $.Deferred().resolve([]).promise() file: (options)-> files = $.makeArray $(options.input).prop 'files' return false unless files.length if (files[0].name == undefined && files[0].fileName) # File normalization for Safari 4 and Firefox 3: $.each files, (index, file)-> file.name = file.fileName; file.size = file.fileSize; $.Deferred().resolve(files).promise() entry: (options)-> roots = $(options.input).prop('webkitEntries') || $(options.input).prop('entries') return false unless roots && roots.length > 0 readEntries = (entries, path='')-> $.when.apply($, $.map entries, (entry)-> dfd = $.Deferred() errorHandler = (e)-> e.entry = entry if e && !e.entry # Since $.when returns immediately if one # Deferred is rejected, we use resolve instead. # This allows valid files and invalid items # to be returned together in one set: dfd.resolve [e] resolveHandler = (file)-> # Workaround for Chrome bug #149735 file.relativePath = path dfd.resolve file if entry.isFile entry._file && resolveHandler(entry._file) || entry.file resolveHandler, errorHandler else if entry.isDirectory entry.createReader().readEntries((entries)-> readEntries(entries, path + entry.name + '/' ).done((files)->dfd.resolve files ).fail(errorHandler) , errorHandler) else # Return an empy list for file system items other than files or directories: dfd.resolve([]); dfd.promise() #we do need this pipe here bc we do resolve some files scoped ).pipe -> Array.prototype.concat.apply [],arguments readEntries(roots).promise() Uploader: _responsibilityChain: (options, chain, name = false)-> stream = false $.each chain, (i, func)=> if stream = func(options) # Uploader # @[name] = func if name false stream readers: [entry, file, input] read: (options)->@_responsibilityChain options, @readers, 'read' senders: [xhrFile, formDataFile, formDataForm, iframe] send: (options)->@_responsibilityChain options, @senders, 'send' upload: (options)-> options = $.extend method: 'POST' name: options.input && options.input.name , options @read(options).then (files)=>$.when.apply $, @send $.extend options, files:files
å
¥å[type = file]ã®è¡šç€ºã«é¢ããåé¡ã®è§£æ±ºçãšããŠããã®ãããªããªãã¯ãææ¡ããŸã-äœçœ®ã䜿çšããŠå
¥åèªäœãé衚瀺ã«ããŸãïŒã³ã³ããã®ç«¯ãã¯ããã«è¶
ããŠãã©ãã«ãå®ååããŸãã
å°ãããç°¡åã«æ¡åŒµå¯èœãªãã¡ã€ã«ã¢ããããŒããŒããããŸãã æ°ããã¢ããããŒãã¡ã«ããºã ã衚瀺ãããããéä¿¡è
ãšããŒã«ã®ãœãŒãæžã¿ãªã¹ãã«ç°¡åã«è¿œå ããŸãã 颿°éãçµã¶ããŒã¿ã®åœ¢åŒã¯åºå®ãããŠããã$ .Deferredã§ãã ãããïŒ
-åæããŠã³ããŒãæ°ã«å¶éã¯ãããŸãã
-ããŠã³ããŒããã£ã³ã»ã«ã¡ã«ããºã ãªã
-ã¯ã©ã€ã¢ã³ãåŽã§ã®äžå¿«ãªã€ãã³ã-ã€ãã³ãããã¡ã€ã«ãã¢ããããŒããããŸããããããã¡ã€ã«ãšã©ãŒãããããŸãã é²è¡ç¶æ³ã€ãã³ãã«ã¯ãããŠã³ããŒãããããã¡ã€ã«ã®æ°ã確èªããçµã¿èŸŒã¿æ©èœã¯ãããŸãã
è峿·±ãå Žåã¯ãæ¬ ç¹ïŒããã³å©ç¹ïŒãåãé€ãæ¹æ³ã瀺ããŸãã ããã§ãç§ã¯ç§ã®äŒæãããŒã«ãããã·ã¥ãé£äººãåãããŠãã ããã
䜿çšãããæç®ã®ãªã¹ãïŒ
1. jQuery-File-Uploadãã©ã°ã€ã³ã³ãŒã
-github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.fileupload.js2. jQuery.Deferredããã¥ã¡ã³ã
-api.jquery.com/category/deferred-object3.æ¬ããã¶ã€ã³ãã¿ãŒã³ã
Freemanov-www.ozon.ru/context/detail/id/20216992