自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

jQuery === 面條式代碼?

開(kāi)發(fā) 開(kāi)發(fā)工具
自從React/Vue等框架流行之后,jQuery被打上了面條式代碼的標(biāo)簽,甚至成了“過(guò)街老鼠”,好像誰(shuí)還在用jQuery,誰(shuí)就還活在舊時(shí)代,很多人都爭(zhēng)先恐后地?fù)肀驴蚣?,各大博客網(wǎng)站有很大一部分的博客都在介紹新的框架,爭(zhēng)當(dāng)時(shí)代的“弄潮兒”。

jQuery

自從React/Vue等框架流行之后,jQuery被打上了面條式代碼的標(biāo)簽,甚至成了“過(guò)街老鼠”,好像誰(shuí)還在用jQuery,誰(shuí)就還活在舊時(shí)代,很多人都爭(zhēng)先恐后地?fù)肀驴蚣?,各大博客網(wǎng)站有很大一部分的博客都在介紹新的框架,爭(zhēng)當(dāng)時(shí)代的“弄潮兒”。新框架帶來(lái)的新的理念,新的開(kāi)發(fā)方式不可否認(rèn)帶來(lái)了生產(chǎn)效率,但是jQuery等就應(yīng)該被打上“舊時(shí)代”面條式代碼的標(biāo)簽么?

我們從一篇文章說(shuō)起:《React.js 的介紹 – 針對(duì)了解 jQuery 的工程師(譯)》,英文原文是這個(gè)《React.js Introduction For People Who Know Just Enough jQuery To Get By》, 這篇文章我好久前就看過(guò),現(xiàn)在再把它翻出來(lái),里面對(duì)比了下jQuery和React分別實(shí)現(xiàn)一個(gè)發(fā)推的功能,作者用jQuery寫(xiě)著寫(xiě)著代碼就亂套了,而用React不管需求多復(fù)雜,代碼條理依舊很清晰。

我們一步步按照原文作者的思路來(lái)拆解。

(1)輸入個(gè)數(shù)為0時(shí),發(fā)送按鈕不可點(diǎn)擊

如下圖所示,當(dāng)輸入框沒(méi)有內(nèi)容時(shí),發(fā)推按鈕置灰不可點(diǎn),有內(nèi)容點(diǎn)才能點(diǎn)。


作者寫(xiě)的代碼是這樣的:

  1. // 初始化狀態(tài) 
  2. $("button").prop("disabled"true); 
  3.   
  4. // 文本框的值發(fā)生變化時(shí) 
  5. $("textarea").on("input"function() { 
  6.   // 只要超過(guò)一個(gè)字符,就 
  7.   if ($(this).val().length > 0) { 
  8.     // 按鈕可以點(diǎn)擊 
  9.     $("button").prop("disabled"false); 
  10.   } else { 
  11.     //否則,按鈕不能點(diǎn)擊 
  12.     $("button").prop("disabled"true); 
  13.   } 
  14. }); 

這個(gè)代碼本身寫(xiě)得很累贅,首先,既然一開(kāi)始那個(gè)button是disabled的,那就直接在html上寫(xiě)個(gè)disabled屬性就行了:

  1. <form class="tweet-box"
  2.     <textarea name="textMsg"></textarea> 
  3.     <input disabled type="submit" name="tweet" value="Tweet"
  4. </form> 

第二個(gè)要控制按鈕的狀態(tài),其實(shí)核心只要一行代碼就行了,不需要寫(xiě)那么長(zhǎng):

  1. let form = $(".tweet-box")[0]; 
  2. $(form.textMsg).on("input"function() { 
  3.     form.tweet.disabled = this.value.length <= 0; 
  4. }).trigger("input"); 

這個(gè)代碼應(yīng)該夠簡(jiǎn)潔了吧,而且代碼在jQuery和原生之間來(lái)回切換,游刃有余。

(2)實(shí)現(xiàn)剩余字?jǐn)?shù)功能

如下圖所示:


這個(gè)也好實(shí)現(xiàn):

  1. let form = $(".tweet-box")[0], 
  2.     $leftWordCount = $("#left-word-count"); 
  3.   
  4. $(form.textMsg).on("input"function() { 
  5.     // 已有字?jǐn)?shù) 
  6.     let wordsCount = this.value.length; 
  7.     $leftWordCount.text(140 - wordsCount); 
  8.     form.tweet.disabled = wordsCount <= 0;  
  9. }); 

(3)添加圖片按鈕

如下圖所示,左下角多了一個(gè)選擇照片的按鈕:


如果用戶(hù)選擇了照片,那么可輸入字?jǐn)?shù)將會(huì)減少23個(gè)字符,并且Add Photo文案要變成Photo Added。我們先來(lái)看下作者是怎么實(shí)現(xiàn)的,如下代碼:

  1. if ($(this).hasClass("is-on")) { 
  2.   $(this) 
  3.     .removeClass("is-on"
  4.     .text("Add Photo"); 
  5.   $("span").text(140 - $("textarea").val().length); 
  6. else { 
  7.   $(this) 
  8.     .addClass("is-on"
  9.     .text("✓ Photo Added"); 
  10.   $("span").text(140 - 23 - $("textarea").val().length); 

如果代碼像作者這樣寫(xiě)的話確實(shí)是比較亂,而且比較面條式。但是我們可以?xún)?yōu)雅地實(shí)現(xiàn)。首先,選擇照片一般會(huì)寫(xiě)一個(gè)input[type=file]的隱藏輸入框蓋在上傳圖標(biāo)下面:

  1. <div class="upload-container"> 
  2.     <img src="upload-icon.png" alt> 
  3.     <span id="add-photo">Add Photo</span> 
  4.     <input type="file" name="photoUpload"> 
  5. </div> 

然后監(jiān)聽(tīng)它的change事件,在change事件里面給form套一個(gè)類(lèi):

  1. $(form.photoUpload).on("change"function() { 
  2.     // 如果選擇了照片則添加一個(gè)photo-added的類(lèi) 
  3.     this.value.length ? $(form).addClass("photo-added"
  4.                 // 否則去掉 
  5.                 : $(form).removeClass("photo-added"); 
  6.              
  7. }); 

然后就可以來(lái)實(shí)現(xiàn)文案改變的需求了,把上面#add-photo的span標(biāo)簽添加兩個(gè)data屬性,分別是照片添加和未添加的文案,如下代碼所示:

  1. <span id="add-photo" data-added-text="Photo Added"  
  2.       data-notadded-text="Add Photo"></span> 

通過(guò)form的類(lèi)結(jié)合before/after偽類(lèi)控制html上的文案,如下代碼所示:

  1. #add-photo:before { 
  2.     content: attr(data-empty-text); 
  3.   
  4. form.photo-added #add-photo:before { 
  5.     content: attr("data-added-text); 

這樣就可以了,我們算是用了一個(gè)比較優(yōu)雅的方式實(shí)現(xiàn)了一個(gè)文案變化的功能,其中CSS的attr可以兼容到IE9,并且這里html/css/js相配合,共同完成這個(gè)變化的功能,這應(yīng)該也挺好玩的。

剩下一個(gè)要減掉23字符的需求,只需要在減掉的時(shí)候判斷一下:

  1. $(form.textMsg).on("input"function() { 
  2.     // 已有字?jǐn)?shù) 
  3.     let wordsCount = this.value.length; 
  4.     form.tweet.disabled = wordsCount <= 0; 
  5.     $leftWordCount.text(140 - wordsCount -  
  6.             //如果已經(jīng)添加了圖片再減掉23個(gè)字符 
  7.             ($(form).hasClass("photo-added") ? 23 : 0)); 
  8. }); 

然后在選擇圖片之后trigger一下,讓文字發(fā)生變化,如下代碼倒數(shù)第二行:

  1. /* 
  2.  * @trigger 會(huì)觸發(fā)文字輸入框的input事件以更新剩余字?jǐn)?shù) 
  3.  */ 
  4. $(form.photoUpload).on("change"function() { 
  5.     // 如果選擇了照片則添加一個(gè)photo-added的類(lèi) 
  6.     this.value.length ? $(form).addClass("photo-added") :  
  7.                 // 否則去掉 
  8.                 $(form).removeClass("photo-added"); 
  9.     $(form.textMsg).trigger("input"); 
  10. }); 

這里又使用了事件的機(jī)制,用reac應(yīng)該基本上都是用狀態(tài)state控制了。

再來(lái)看***一個(gè)功能。

(4)沒(méi)有文字但是有照片發(fā)推按鈕要可點(diǎn)

上面是只要沒(méi)有文字,那么發(fā)推按鈕不可點(diǎn),現(xiàn)在要求有圖片就可點(diǎn)。這個(gè)也好辦,因?yàn)槿绻袌D片的話,form已經(jīng)有了一個(gè)類(lèi),所以只要再加一個(gè)判斷就可以了:

  1. $(form.textMsg).on("input"function() { 
  2.     // 已有字?jǐn)?shù) 
  3.     let wordsCount = this.value.length; 
  4.     form.tweet.disabled = wordsCount <= 0  
  5.             //disabled再添加一個(gè)與判斷 
  6.             && !$(form).hasClass("photo-added"); 
  7.     $leftWordCount.text(140 - wordsCount -  
  8.             //如果已經(jīng)添加了圖片再減掉23個(gè)字符 
  9.             ($(form).hasClass("photo-added") ? 23 : 0)); 
  10. }); 

***看一下,匯總的JS代碼,加上空行和注釋總共只有23行:

  1. let form = $(".tweet-box")[0], 
  2.     $leftWordCount = $("#left-word-count"); 
  3.   
  4. $(form.textMsg).on("input"function() { 
  5.     // 已有字?jǐn)?shù) 
  6.     let wordsCount = this.value.length; 
  7.     form.tweet.disabled = wordsCount <= 0  
  8.             //disabled再添加一個(gè)與判斷 
  9.             && !$(form).hasClass("photo-added"); 
  10.     $leftWordCount.text(140 - wordsCount -  
  11.             //如果已經(jīng)添加了圖片再減掉23個(gè)字符 
  12.             ($(form).hasClass("photo-added") ? 23 : 0)); 
  13. }); 
  14.   
  15. /* 
  16.  * @trigger 會(huì)觸發(fā)文字輸入框的input事件以更新剩余字?jǐn)?shù) 
  17.  */ 
  18. $(form.photoUpload).on("change"function() { 
  19.     // 如果選擇了照片則添加一個(gè)photo-added的類(lèi) 
  20.     this.value.length ? $(form).addClass("photo-added") :  
  21.             // 否則去掉 
  22.             $(form).removeClass("photo-added"); 
  23.     $(form.textMsg).trigger("input"); 
  24. }); 

html大概有10行,還有6行核心CSS,不過(guò)這兩個(gè)比較易讀。再來(lái)看一下React的完整版本,作者的實(shí)現(xiàn):

  1. var TweetBox = React.createClass({ 
  2.   getInitialState: function() { 
  3.     return { 
  4.       text: ""
  5.       photoAdded: false 
  6.     }; 
  7.   }, 
  8.   handleChange: function(event) { 
  9.     this.setState({ text: event.target.value }); 
  10.   }, 
  11.   togglePhoto: function(event) { 
  12.     this.setState({ photoAdded: !this.state.photoAdded }); 
  13.   }, 
  14.   remainingCharacters: function() { 
  15.     if (this.state.photoAdded) { 
  16.       return 140 - 23 - this.state.text.length; 
  17.     } else { 
  18.       return 140 - this.state.text.length; 
  19.     } 
  20.   }, 
  21.   render: function() { 
  22.     return ( 
  23.       <div className="well clearfix"
  24.         <textarea className="form-control" 
  25.                   onChange={this.handleChange}></textarea> 
  26.         <br/> 
  27.         <span>{ this.remainingCharacters() }</span> 
  28.         <button className="btn btn-primary pull-right" 
  29.           disabled={this.state.text.length === 0 && !this.state.photoAdded}>Tweet</button> 
  30.         <button className="btn btn-default pull-right" 
  31.           onClick={this.togglePhoto}> 
  32.           {this.state.photoAdded ? "✓ Photo Added" : "Add Photo" } 
  33.         </button> 
  34.       </div> 
  35.     ); 
  36.   } 
  37. }); 
  38.   
  39. React.render( 
  40.   <TweetBox />, 
  41.   document.body 
  42. ); 

React的套路是監(jiān)聽(tīng)事件然后改變state,在jsx的模板里,使用這些state展示,而jQuery的套路是監(jiān)聽(tīng)事件,然后自己去控制DOM展示。React幫你操作DOM,jQuery要自己去操作DOM,前者提供了便利但同時(shí)也失去了靈活性,后者增加了靈活性但同時(shí)增加了復(fù)雜度。

使用jQuery不少人容易寫(xiě)出面條式的代碼,但是寫(xiě)代碼的風(fēng)格我覺(jué)得和框架沒(méi)關(guān)系,關(guān)鍵還在于你的編碼素質(zhì),就像你用了React寫(xiě)class,你就可以說(shuō)你就是面向?qū)ο罅?不見(jiàn)得,我在《JS與面向?qū)ο蟆愤@篇文章提到,寫(xiě)class并不代表你就是面向?qū)ο?,面向?qū)ο笫且环N思想而不是你代碼的組織形式。一旦你離開(kāi)了React的框架,是不是又要回到面條式代碼的風(fēng)格了?如果是的話那就說(shuō)明你并沒(méi)有沒(méi)有掌握面向?qū)ο蟮乃枷?。不過(guò),React等框架能夠方便地組件化,這點(diǎn)是不可否認(rèn)的。

還有一個(gè)需要注意的是,框架會(huì)幫你屏蔽掉很多原生的細(xì)節(jié),讓你專(zhuān)心于業(yè)務(wù)邏輯,但往往也讓你喪失了原生的能力不管是html還是js,而這才是最重要的功底。例如說(shuō)對(duì)于事件,由于所有的事件都是直接綁在目標(biāo)元素,然后通過(guò)state或者其它第三方的框架進(jìn)行傳遞,這樣其實(shí)就沒(méi)什么事件的概念了。所以需要警惕使用了框架但是喪失了基本的前端能力,再如ajax分頁(yè)改變url,或者說(shuō)單頁(yè)面路由的實(shí)現(xiàn)方式,還有前后退的控制,基本上能夠完整回答地比較少。很多人都會(huì)用框架做頁(yè)面,但是不懂JS.

原文鏈接:https://fed.renren.com/2017/09/03/jquery-not-noodle-code/ 

【本文是51CTO專(zhuān)欄作者“人人網(wǎng)FED”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)51CTO聯(lián)系原作者獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來(lái)源: 51CTO專(zhuān)欄
相關(guān)推薦

2020-02-19 08:00:00

微服務(wù)架構(gòu)分布式代碼

2017-02-08 10:56:32

光纖產(chǎn)能技術(shù)

2017-10-11 16:19:36

jquery留言框設(shè)計(jì)

2014-09-04 09:48:32

jQuery響應(yīng)式

2020-12-17 07:59:46

聲明式代碼命令式代碼代碼

2011-11-02 17:17:06

jQuery

2012-06-13 10:17:40

jQuery

2013-07-29 14:28:43

JQueryJQuery實(shí)現(xiàn)分頁(yè)分頁(yè)程序代碼

2012-04-26 13:12:09

jQuery代碼優(yōu)化

2012-10-11 09:09:26

jQueryJSWeb

2012-04-24 14:06:37

jQuery代碼

2012-05-07 09:53:10

jQuery

2014-04-22 11:01:56

jQuery代碼

2022-05-28 11:00:57

安全編碼安全代碼應(yīng)用安全

2020-09-04 06:27:22

編碼命令式聲明式代碼

2015-11-05 09:07:12

代碼傻瓜式

2024-10-22 09:39:51

2011-10-31 13:31:03

jQuery

2011-11-23 09:21:43

jQuery

2009-07-21 17:16:34

Scala函數(shù)式指令式
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)