jQuery === 面条式代码?

2022-11-30 0 858

(点选下方社会公众号,可加速高度关注)

fed.renren.com/2017/09/03/jquery-not-noodle-code/

但如好该文征稿,请点选 → 这儿介绍详细情况

好景不长React/Vue等架构盛行后,jQuery被打上了饺子式标识符的条码,即使成了“傻子”,好似谁还在用jQuery,谁就还活在博戈达,许多人都兴高采烈地亲吻新架构,数十家网志中文网站有非常大一小部分的网志都在如是说捷伊架构,争做黄金时代的“先行者”。新架构增添的捷伊经营理念,捷伊Attichy不容否认增添了制造工作效率,但jQuery等就如果被打上“博戈达”饺子式标识符的条码么?

他们从一则该文讲起:《React.js 的如是说 – 特别针对介绍 jQuery 的技师(译)》,英语书名是那个《React.js Introduction For People Who Know Just Enough jQuery To Get By》, 这篇该文我很久前就看完,那时再把它挑出来,里头对照了下jQuery和React依次同时实现两个罗亚尼的机能,译者用jQuery写着写着标识符就述补了,而用React无论市场需求多繁杂,标识符章法依然很明晰。

我们一点一点依照书名译者的路子来回收。

(1)输出特征值为0时,推送按键不容点选

如下表所示图右图,当快捷方式没文本时,罗亚尼按键置灰不容点,有文本点就可以点。

jQuery === 面条式代码?

译者写的标识符是这种的:

// 调用状况

$(“button”).prop(“disabled”,true);

// 文本框的值发生变化时

$(“textarea”).on(“input”,function(){

// 只要超过两个字符,就

if($(this).val().length > 0){

// 按键可以点选

$(“button”).prop(“disabled”,false);

}else{

//否则,按键不能点选

$(“button”).prop(“disabled”,true);

}

});

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

<form class=“tweet-box”>

<textareaname=“textMsg”></textarea>

<input disabledtype=“submit”name=“tweet”value=“Tweet”>

</form>

第二个要控制按键的状况,其实核心只要一行标识符就行了,不需要写那么长:

let form = $(“.tweet-box”)[0];

$(form.textMsg).on(“input”,function(){

form.tweet.disabled = this.value.length <= 0;

}).trigger(“input”);

那个标识符如果够简洁了吧,而且标识符在jQuery和原生之间来回切换,游刃有余。

(2)同时实现剩余字数机能

如下表所示图右图:

jQuery === 面条式代码?

那个也好同时实现:

let form = $(“.tweet-box”)[0],

$leftWordCount = $(“#left-word-count”);

$(form.textMsg).on(“input”,function(){

// 已有字数

let wordsCount = this.value.length;

$leftWordCount.text(140wordsCount);

form.tweet.disabled = wordsCount <= 0;

});

(3)添加图片按键

如下表所示图右图,左下角多了两个选择照片的按键:

jQuery === 面条式代码?

如果用户选择了照片,那么可输出字数将会减少23个字符,并且Add Photo文案要变成Photo Added。他们先来看下译者是怎么同时实现的,如下表所示标识符:

if($(this).hasClass(“is-on”)){

$(this)

.removeClass(“is-on”)

.text(“Add Photo”);

$(“span”).text(140$(“textarea”).val().length);

}else{

$(this)

.addClass(“is-on”)

.text(“✓ Photo Added”);

$(“span”).text(14023$(“textarea”).val().length);

}

如果标识符像译者这种写的话确实是比较乱,而且比较饺子式。但他们可以优雅地同时实现。首先,选择照片一般会写两个input[type=file]的隐藏快捷方式盖在上传图标下面:

<div class=“upload-container”>

<img src=“upload-icon.png”alt>

<span id=“add-photo”>Add Photo</span>

<input type=“file”name=“photoUpload”>

</div>

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

$(form.photoUpload).on(“change”,function(){

// 如果选择了照片则添加两个photo-added的类

this.value.length?$(form).addClass(“photo-added”)

// 否则去掉

                : $(form).removeClass(“photo-added”);

});

然后就可以来同时实现文案改变的市场需求了,把上面#add-photo的span条码添加两个data属性,依次是照片添加和未添加的文案,如下表所示标识符右图:

<span id=“add-photo”data-added-text=“Photo Added”

data-notadded-text=“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);

}

这样就可以了,他们算是用了两个比较优雅的方式同时实现了两个文案变化的机能,其中CSS的attr可以兼容到IE9,并且这儿html/css/js相配合,共同完成那个变化的机能,这如果也挺好玩的。

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

$(form.textMsg).on(“input”,function(){

// 已有字数

let wordsCount = this.value.length;

form.tweet.disabled = wordsCount <= 0;

$leftWordCount.text(140wordsCount

//如果已经添加了图片再减掉23个字符

($(form).hasClass(“photo-added”)?23 : 0));

});

然后在选择图片后trigger一下,让文字发生变化,如下表所示标识符倒数第二行:

/*

* @trigger 会触发文字快捷方式的input事件以更新剩余字数

*/

$(form.photoUpload).on(“change”,function(){

// 如果选择了照片则添加两个photo-added的类

this.value.length?$(form).addClass(“photo-added”) :

// 否则去掉

$(form).removeClass(“photo-added”);

$(form.textMsg).trigger(“input”);

});

这儿又使用了事件的机制,用reac如果基本上都是用状况state控制了。

再来看最后两个机能。

(4)没文字但有照片罗亚尼按键要可点

上面是只要没文字,那么罗亚尼按键不容点,那时要求有图片就可点。那个也好办,因为如果有图片的话,form已经有了两个类,所以只要再加两个判断就可以了:

$(form.textMsg).on(“input”,function(){

// 已有字数

let wordsCount = this.value.length;

form.tweet.disabled = wordsCount <= 0

//disabled再添加两个与判断

            && !$(form).hasClass(“photo-added”);

$leftWordCount.text(140wordsCount

//如果已经添加了图片再减掉23个字符

($(form).hasClass(“photo-added”)?23 : 0));

});

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

let form = $(“.tweet-box”)[0],

$leftWordCount = $(“#left-word-count”);

$(form.textMsg).on(“input”,function(){

// 已有字数

let wordsCount = this.value.length;

form.tweet.disabled = wordsCount <= 0

//disabled再添加两个与判断

            && !$(form).hasClass(“photo-added”);

$leftWordCount.text(140wordsCount

//如果已经添加了图片再减掉23个字符

($(form).hasClass(“photo-added”)?23 : 0));

});

/*

* @trigger 会触发文字快捷方式的input事件以更新剩余字数

*/

$(form.photoUpload).on(“change”,function(){

// 如果选择了照片则添加两个photo-added的类

this.value.length?$(form).addClass(“photo-added”) :

// 否则去掉

$(form).removeClass(“photo-added”);

$(form.textMsg).trigger(“input”);

});

html大概有10行,还有6行核心CSS,不过这两个比较易读。再来看一下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){

return14023this.state.text.length;

}else{

return140this.state.text.length;

}

},

render: function(){

return(

      <div className=“well clearfix”>

        <textarea className=“form-control”

onChange={this.handleChange}></textarea>

        <br/>

<span>{ this.remainingCharacters() }</span>

        <button className=“btn btn-primary pull-right”

disabled={this.state.text.length === 0 && !this.state.photoAdded}>Tweet</button>

        <button className=“btn btn-default pull-right”

onClick={this.togglePhoto}>

{this.state.photoAdded?“✓ Photo Added” : “Add Photo”}

        </button>

      </div>

);

}

});

React.render(

  <TweetBox/>,

document.body

);

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

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

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

觉得本文对你有帮助?请分享给更多人

高度关注「前端大全」,提升前端技能

jQuery === 面条式代码?

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务