MyException - 我的异常网
当前位置:我的异常网» jQuery » jQuery === 面条式代码

jQuery === 面条式代码

www.MyException.Cn  网友分享于:2013-09-19  浏览:0次
jQuery === 面条式代码?



  自从React/Vue等框架流行之后,jQuery被打上了面条式代码的标签,甚至成了“过街老鼠”,好像谁还在用jQuery,谁就还活在旧时代,很多人都争先恐后地拥抱新框架,各大博客网站有很大一部分的博客都在介绍新的框架,争当时代的“弄潮儿”。新框架带来的新的理念,新的开发方式不可否认带来了生产效率,但是jQuery等就应该被打上“旧时代”面条式代码的标签么?

  我们从一篇文章说起:《React.js 的介绍 – 针对了解 jQuery 的工程师(译)》,英文原文是这个《React.js Introduction For People Who Know Just Enough jQuery To Get By》, 这篇文章我好久前就看过,现在再把它翻出来,里面对比了下jQuery和React分别实现一个发推的功能,作者用jQuery写着写着代码就乱套了,而用React不管需求多复杂,代码条理依旧很清晰。

  我们一步步按照原文作者的思路来拆解。

  (1)输入个数为0时,发送按钮不可点击

  如下图所示,当输入框没有内容时,发推按钮置灰不可点,有内容点才能点。

 

  作者写的代码是这样的:

  1. // 初始化状态
  2. $("button").prop("disabled", true);
  3. // 文本框的值发生变化时
  4. $("textarea").on("input", function() {
  5. // 只要超过一个字符,就
  6. if ($(this).val().length > 0) {
  7. // 按钮可以点击
  8. $("button").prop("disabled", false);
  9. } else {
  10. //否则,按钮不能点击
  11. $("button").prop("disabled", true);
  12. }
  13. });

  这个代码本身写得很累赘,首先,既然一开始那个button是disabled的,那就直接在html上写个disabled属性就行了:

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

  第二个要控制按钮的状态,其实核心只要一行代码就行了,不需要写那么长:

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

  这个代码应该够简洁了吧,而且代码在jQuery和原生之间来回切换,游刃有余。

  (2)实现剩余字数功能

  如下图所示:

 

  这个也好实现:

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

  (3)添加图片按钮

  如下图所示,左下角多了一个选择照片的按钮:

 

  如果用户选择了照片,那么可输入字数将会减少23个字符,并且Add Photo文案要变成Photo Added。我们先来看下作者是怎么实现的,如下代码:

  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);
  11. }

  如果代码像作者这样写的话确实是比较乱,而且比较面条式。但是我们可以优雅地实现。首先,选择照片一般会写一个input[type=file]的隐藏输入框盖在上传图标下面:

  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>

  然后监听它的change事件,在change事件里面给form套一个类:

  1. $(form.photoUpload).on("change", function() {
  2. // 如果选择了照片则添加一个photo-added的类
  3. this.value.length ? $(form).addClass("photo-added")
  4. // 否则去掉
  5. : $(form).removeClass("photo-added");
  6. });

  然后就可以来实现文案改变的需求了,把上面#add-photo的span标签添加两个data属性,分别是照片添加和未添加的文案,如下代码所示:

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

  通过form的类结合before/after伪类控制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);
  6. }

  这样就可以了,我们算是用了一个比较优雅的方式实现了一个文案变化的功能,其中CSS的attr可以兼容到IE9,并且这里html/css/js相配合,共同完成这个变化的功能,这应该也挺好玩的。

  剩下一个要减掉23字符的需求,只需要在减掉的时候判断一下:

  1. $(form.textMsg).on("input", function() {
  2. // 已有字数
  3. let wordsCount = this.value.length;
  4. form.tweet.disabled = wordsCount <= 0;
  5. $leftWordCount.text(140 - wordsCount -
  6. //如果已经添加了图片再减掉23个字符
  7. ($(form).hasClass("photo-added") ? 23 : 0));
  8. });

  然后在选择图片之后trigger一下,让文字发生变化,如下代码倒数第二行:

  1. /*
  2. * @trigger 会触发文字输入框的input事件以更新剩余字数
  3. */
  4. $(form.photoUpload).on("change", function() {
  5. // 如果选择了照片则添加一个photo-added的类
  6. this.value.length ? $(form).addClass("photo-added") :
  7. // 否则去掉
  8. $(form).removeClass("photo-added");
  9. $(form.textMsg).trigger("input");
  10. });

  这里又使用了事件的机制,用reac应该基本上都是用状态state控制了。

  再来看最后一个功能。

  (4)没有文字但是有照片发推按钮要可点

  上面是只要没有文字,那么发推按钮不可点,现在要求有图片就可点。这个也好办,因为如果有图片的话,form已经有了一个类,所以只要再加一个判断就可以了:

  1. $(form.textMsg).on("input", function() {
  2. // 已有字数
  3. let wordsCount = this.value.length;
  4. form.tweet.disabled = wordsCount <= 0
  5. //disabled再添加一个与判断
  6. && !$(form).hasClass("photo-added");
  7. $leftWordCount.text(140 - wordsCount -
  8. //如果已经添加了图片再减掉23个字符
  9. ($(form).hasClass("photo-added") ? 23 : 0));
  10. });

  最后看一下,汇总的JS代码,加上空行和注释总共只有23行:

  1. let form = $(".tweet-box")[0],
  2. $leftWordCount = $("#left-word-count");
  3. $(form.textMsg).on("input", function() {
  4. // 已有字数
  5. let wordsCount = this.value.length;
  6. form.tweet.disabled = wordsCount <= 0
  7. //disabled再添加一个与判断
  8. && !$(form).hasClass("photo-added");
  9. $leftWordCount.text(140 - wordsCount -
  10. //如果已经添加了图片再减掉23个字符
  11. ($(form).hasClass("photo-added") ? 23 : 0));
  12. });
  13. /*
  14. * @trigger 会触发文字输入框的input事件以更新剩余字数
  15. */
  16. $(form.photoUpload).on("change", function() {
  17. // 如果选择了照片则添加一个photo-added的类
  18. this.value.length ? $(form).addClass("photo-added") :
  19. // 否则去掉
  20. $(form).removeClass("photo-added");
  21. $(form.textMsg).trigger("input");
  22. });

  html大概有10行,还有6行核心CSS,不过这两个比较易读。再来看一下React的完整版本,作者的实现:

  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. React.render(
  39. <TweetBox />,
  40. document.body
  41. );

  React的套路是监听事件然后改变state,在jsx的模板里,使用这些state展示,而jQuery的套路是监听事件,然后自己去控制DOM展示。React帮你操作DOM,jQuery要自己去操作DOM,前者提供了便利但同时也失去了灵活性,后者增加了灵活性但同时增加了复杂度。

  使用jQuery不少人容易写出面条式的代码,但是写代码的风格我觉得和框架没关系,关键还在于你的编码素质,就像你用了React写class,你就可以说你就是面向对象了?不见得,我在《JS与面向对象》这篇文章提到,写class并不代表你就是面向对象,面向对象是一种思想而不是你代码的组织形式。一旦你离开了React的框架,是不是又要回到面条式代码的风格了?如果是的话那就说明你并没有没有掌握面向对象的思想。不过,React等框架能够方便地组件化,这点是不可否认的。

  还有一个需要注意的是,框架会帮你屏蔽掉很多原生的细节,让你专心于业务逻辑,但往往也让你丧失了原生的能力不管是html还是js,而这才是最重要的功底。例如说对于事件,由于所有的事件都是直接绑在目标元素,然后通过state或者其它第三方的框架进行传递,这样其实就没什么事件的概念了。所以需要警惕使用了框架但是丧失了基本的前端能力,再如ajax分页改变url,或者说单页面路由的实现方式,还有前后退的控制,基本上能够完整回答地比较少。很多人都会用框架做页面,但是不懂JS.

 

文章评论

Java程序员必看电影
Java程序员必看电影
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
 程序员的样子
程序员的样子
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
总结2014中国互联网十大段子
总结2014中国互联网十大段子
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
10个调试和排错的小建议
10个调试和排错的小建议
中美印日四国程序员比较
中美印日四国程序员比较
程序员应该关注的一些事儿
程序员应该关注的一些事儿
漫画:程序员的工作
漫画:程序员的工作
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
我的丈夫是个程序员
我的丈夫是个程序员
程序员和编码员之间的区别
程序员和编码员之间的区别
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
为什么程序员都是夜猫子
为什么程序员都是夜猫子
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
鲜为人知的编程真相
鲜为人知的编程真相
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
老程序员的下场
老程序员的下场
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
我是如何打败拖延症的
我是如何打败拖延症的
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
如何成为一名黑客
如何成为一名黑客
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
代码女神横空出世
代码女神横空出世
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序员必看的十大电影
程序员必看的十大电影
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
程序员的鄙视链
程序员的鄙视链
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
旅行,写作,编程
旅行,写作,编程
那些争议最大的编程观点
那些争议最大的编程观点
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有