当前位置: 首页 > 科技观察

jQuery===意大利面条代码?

时间:2023-03-12 17:20:29 科技观察

自从React/Vue等框架流行之后,jQuery就被贴上了面条代码的标签,甚至成了“过街老鼠”。拥抱新框架,各大博客网站上有很大一部分博客都在引入新框架,力争成为时代的“潮流”。新框架带来的新思想、新开发方式无疑带来了生产力,但jQuery等是否应该被贴上“老年”面条代码的标签呢?先说一篇文章:《React.js 的介绍 – 针对了解 jQuery 的工程师(译)》,英文原文是这篇《React.js Introduction For People Who Know Just Enough jQuery To Get By》,很久以前看过这篇文章,现在重看,比较了jQuery和React实现的推特功能,作者在jQuery里写的代码是乱七八糟的,但是有了React,再复杂的需求,代码还是很清晰的。下面按照原作者的思路一步步拆解吧。(1)当输入个数为0时,发送按钮无法点击,如下图。当输入框没有内容时,发送按钮是灰色的,不能点击,只有有内容才能点击。作者写的代码是这样的://初始化状态$("button").prop("disabled",true);//当文本框的值发生变化时$("textarea").on("input",function(){//只要不止一个字符,if($(this).val().length>0){//可以点击按钮$("button").prop("disabled",false);}else{//否则按钮无法点击$("button").prop("disabled",true);}});这段代码本身写起来就很麻烦,首先,既然一开始按钮是disabled的,那么直接在html上写一个disabled属性就可以了:二是控制按钮的状态。其实核心只需要一行代码,不需要这么长:letform=$(".tweet-box")[0];$(form.textMsg).on("input",function(){form.tweet.disabled=this.value.length<=0;}).trigger("输入");这段代码应该足够简单,代码在jQuery和native之间来回切换,很轻松。(2)如下图实现剩余字数统计功能:这个也很容易实现:letform=$(".tweet-box")[0],$leftWordCount=$("#left-word-count");$(form.textMsg).on("input",function(){//字数letwordsCount=this.value.length;$leftWordCount.text(140-wordsCount);form.tweet.disabled=wordsCount<=0;});(3)添加图片的按钮如下图所示,左下角有一个选择照片的按钮:如果用户选择了照片,则字符数可输入的内容将减少23个字符,添加照片的文本将更改为已添加照片。我们先看看作者是如何实现的,代码如下:if($(this).hasClass("is-on")){$(this).removeClass("is-on").text("AddPhoto");$("span").text(140-$("textarea").val().length);}else{$(this).addClass("is-on").text("?PhotoAdded");$("span").text(140-23-$("textarea").val().length);}如果代码像作者那样写,真的是乱七八糟,更像面条。但是我们可以优雅地做到这一点。首先,选择照片时,上传图标下方会写一个input[type=file]的隐藏输入框:AddPhoto

然后监听它的change事件,在change事件中给form设置一个class:$(form.photoUpload).on("change",function(){//如果选择了照片,添加照片添加类this.value.length?$(form).addClass("photo-added")//否则删除:$(form).removeClass("photo-added");});然后就可以实现文案变化的需求了,在上面#add-photo的span标签中添加两个数据属性,分别是照片添加和未添加文案,如下代码所示:通过form类结合before/after伪类来控制html文案,如下代码所示:#add-photo:before{content:attr(data-empty-text);}form.photo-added#add-photo:before{content:attr("data-added-text);}就这样,我们实现了一个功能copywriting改的比较优雅,css的attr可以兼容IE9,这里html/css/js配合完成这个改的功能,这个应该也挺好玩的。只有一个需要减去23个字符,减去的时候只需要判断:$(form.textMsg).on("input",function(){//已经可用的字数letwordsCount=this.value.length;form.tweet.disabled=wordsCount<=0;$leftWordCount.text(140-wordsCount-//如果图片已经添加,则减去23个字符($(form).hasClass("photo-added")?23:0));});然后选择图片后触发一次更改文字,下面代码的倒数第二行:/**@trigger会触发文字输入框的input事件更新剩余的文字*/$(form.photoUpload).on("change",function(){//如果选择了照片,添加照片添加类this.value.length?$(form).addClass("photo-added")://否则,移除$(form).removeClass("添加照片");$(form.textMsg).trigger("input");});这里使用了事件机制,reac基本上应该使用state状态控制。让我们看看最后一个函数。(4)如果没有文字但有图片,推文按钮必须是可点击的。以上是只要没有文字,那么tweet按钮是无法点击的。现在要求有图片。这个也好办,因为如果有图片的话,form已经有class了,所以再加个判断就好了:$(form.textMsg).on("input",function(){//字数已经存在letwordsCount=this.value.length;form.tweet.disabled=wordsCount<=0//disabled再加一个判断&&!$(form).hasClass("photo-added");$leftWordCount.text(140-wordsCount-//如果图片已经添加,则减去23个字符($(form).hasClass("photo-added")?23:0));});***看总结的JS代码,加上空行和注释一共只有23行:letform=$(".tweet-box")[0],$leftWordCount=$("#left-word-count");$(form.textMsg).on("input",function(){//现有的字数letwordsCount=this.value.length;form.tweet.disabled=wordsCount<=0//禁用和再添加一个判断&&!$(form).hasClass("photo-added");$leftWordCount.text(140-wordsCount-//如果图片已经添加了,则减去23个字符($(form).hasClass("photo-added")?23:0));});/**@trigger会触发文本输入框的input事件更新剩余的单词*/$(form.photoUpload).on("change",function(){//如果选择了照片,添加一个照片添加类this.value.length?$(form).addClass("photo-added")://otherwiseremove$(form).removeClass("photo-added");$(form.textMsg).trigger("input");});html大概有10行,核心CSS有6行,不过这两个比较好读再来看一下React的完整版,作者的现实:varTweetBox=React.createClass({getInitialState:function(){return{text:"",photoAdded:false};},handleChange:function(event){this.setState({text:event.target.value});},togglePhoto:function(event){this.setState({photoAdded:!this.state.photoAdded});},remainingCharacters:function(){if(this.state.photoAdded){return140-23-this.state.text.length;}else{return140-this.state.text.length;}},render:function(){return(
{this.remainingCharacters()}推文{this.state.photoAdded?"?PhotoAdded":"添加照片"
);}});React.render(,document.body);React的套路是监听事件,然后改变状态。在jsx模板中,使用这些状态来显示,而jQuery的套路就是监听事件,然后自己控制DOM显示,React帮你操作DOM。jQuery必须自己操作DOM。前者提供便利的同时失去了灵活性,后者增加了灵活性却增加了复杂性。很多人用jQuery轻松写出面条式的代码,但我觉得写代码的风格和框架无关,关键在于你的代码质量,就像你用React写类一样,你可以说你是面向对象的?不一定,我在这篇文章?中提到,写一个类不代表你是面向对象的,面向对象是一种思维而不是你代码的组织形式。一旦离开了React的框架,是不是又要回到面条代码的风格?如果是,说明你还没有掌握面向对象的思想。但是不可否认的是,React这样的框架是可以很容易的组件化的。另外需要注意的是,框架会帮你屏蔽掉很多原生的细节,让你专注于业务逻辑,但往往会让你失去原生的能力,不管是html还是js,而这个是最重要的基础。比如对于事件,由于所有的事件都是直接绑定到目标元素上,然后通过state或者其他第三方框架传递的,所以其实没有事件的概念。所以需要警惕使用框架却失去了基本的前端能力,比如ajax分页改url,或者单页路由的实现,来回的控制。基本上,完整的答案比较少。很多人会用frame做页面,但是不懂JS。原文链接:https://fed.renren.com/2017/09/03/jquery-not-noodle-code/【本文为专栏作者“人人网FED”原创稿件,转载请联系原作者获取转载授权】点此查看该作者更多好文