摘要:看完視頻初步認(rèn)識(shí)了一下,以及模塊化開發(fā)的概念,在此做一下總結(jié)。所以應(yīng)該將功能抽象成模塊。并且非常耗性能解決辦法,在滾動(dòng)條正在運(yùn)動(dòng)或者已經(jīng)到達(dá)目的地,就不應(yīng)該執(zhí)行動(dòng)畫。
前言:在慕課網(wǎng)上跟著視頻《側(cè)邊工具欄開發(fā)》做了一遍,用到了jquery操作DOM,其中,用requirejs管理模塊依賴,然后自定義了兩個(gè)模塊它們都依賴jquery,并且其中一個(gè)自定義模塊依賴另一個(gè),所以要暴露出接口。看完視頻初步認(rèn)識(shí)了一下requirejs,以及模塊化開發(fā)的概念,在此做一下總結(jié)。感謝慕課網(wǎng)上的老師。
使用模塊化開發(fā)的好處:
有效的防止命名沖突
聲明不同的js文件之間的依賴
可以讓我們寫出模塊化的代碼,便于復(fù)用
1.需求與目標(biāo)這個(gè)視頻《側(cè)邊工具欄開發(fā)》的需求很簡單,就是做一個(gè)側(cè)邊工具條,
固定定位在頁面的某個(gè)位置,
在沒有把頁面向下滾動(dòng)時(shí),顯示三個(gè)按鈕,
當(dāng)頁面向下滾動(dòng)一定距離之后,第四個(gè)按鈕出現(xiàn)。
點(diǎn)擊這個(gè)按鈕,頁面會(huì)回到頂部。
鼠標(biāo)hover到每個(gè)按鈕上都有一些相應(yīng)的動(dòng)畫(CSS3完成這里不寫)
2.HTML結(jié)構(gòu)一些說明:
為了讓頁面顯示滾動(dòng)條,需要在這個(gè)上述代碼下面加很多行
標(biāo)簽以便撐開頁面顯示滾動(dòng)條。CSS部分視頻中老師講了三種方法,并且用到了SASS,感興趣的同學(xué)可以去看一下,這里不再贅述。
3.requirejs入門 (1)項(xiàng)目目錄結(jié)構(gòu)其中jquery-3.1.0.js和require.js是在各自官網(wǎng)下載的資源文件。main.js是自定義的入口文件。
在未引入模塊化編寫代碼以前引入js文件是在標(biāo)簽之前寫多個(gè)標(biāo)簽,根據(jù)js文件加載的順序,添加js文件。現(xiàn)在根據(jù)requirejs的異步加載的特性,可以設(shè)定一個(gè)主入口文件,只用一個(gè)實(shí)現(xiàn)其余js文件的加載。
首先是引入requirejs:在HTML文件的標(biāo)簽的之前添加script標(biāo)簽,
然后引入requirejs文件,然后用data-main這個(gè)屬性來引入入口文件。(當(dāng)用requirejs引用文件時(shí),可以省略js文件的js后綴名,所以此處引入的就是項(xiàng)目目錄中的main.js)
如下:
(3)requirejs的常用方法
requirejs.config(為模塊指定別名,方便模塊的引入),在入口文件中定義
如這個(gè)demo要引入多次jquery-3.1.0.js,但是這個(gè)名字很長所以可以在入口文件main.js中為它定義一個(gè)別名,如下:
//為jquery模塊定義別名 requirejs.config({ paths:{ jquery:"jquery-3.1.0.js" } });
requirejs()方法(將寫好的模塊進(jìn)行引入)
requirejs()接收兩個(gè)參數(shù),第一個(gè)參數(shù)是一個(gè)數(shù)組,寫入要引入的模塊的名字。第二個(gè)參數(shù)是一個(gè)回調(diào)函數(shù),需要傳遞一個(gè)參數(shù),來代替前面所引入的模塊。如:引入jquery模塊
requirejs(["jquery"],function($){ //寫一段代碼驗(yàn)證jquery是否被正確引入 //將body背景顏色變?yōu)榧t色 $("body").css("background-color","red"); });
define()(利用它定義編寫模塊,然后在相應(yīng)的地方進(jìn)行引入。)
define()接收三個(gè)參數(shù),第一個(gè)參數(shù)是為本模塊命名的值,可以不寫,第二個(gè)參數(shù)表示需要引入的模塊,第三個(gè)參數(shù)是各依賴項(xiàng)成功加載后所運(yùn)行的函數(shù),傳入的參數(shù)與各個(gè)依賴項(xiàng)形成對(duì)應(yīng)的關(guān)系。
define( moduleName, //可選,如果此參數(shù)不寫,則默認(rèn)使用本模塊所在文件的文件名 dependencies, //一個(gè)數(shù)組,此數(shù)組包含著此文件所需的各個(gè)依賴項(xiàng)目,這個(gè)數(shù)組中各項(xiàng)對(duì)應(yīng)的是所依賴文件相對(duì)于requirejs庫所形成的相對(duì)路徑文件名。 function(parameters){ //各依賴項(xiàng)成功加載后所運(yùn)行的函數(shù) //傳入的參數(shù)與dependencies數(shù)組中的各個(gè)依賴項(xiàng)形成對(duì)應(yīng)關(guān)系 } );(4)demo的基本功能實(shí)現(xiàn)
現(xiàn)在先對(duì)demo中的基本功能進(jìn)行實(shí)現(xiàn):
目前的目錄結(jié)構(gòu)如下:
首先在HTML中初始化requirejs:在標(biāo)簽之前:
在入口文件main.js中實(shí)現(xiàn)基本功能
//1.首先為jquery模塊定義別名 requirejs.config({ paths: { jquery: "jquery-3.1.0" } }); //2.然后用requirejs()方法引入jquery模塊實(shí)現(xiàn)demo中需求 requirejs(["jquery"],function($){ //為id值為backTop的第四個(gè)按鈕添加點(diǎn)擊回到頂部事件,當(dāng)點(diǎn)擊時(shí)執(zhí)行move函數(shù)回到頂部 $("#backTop").on("click",move); //監(jiān)聽一下windows對(duì)象的滾動(dòng)事件, //每次滾動(dòng)都執(zhí)行函數(shù)checkPosition確定一下位置,是否到達(dá)設(shè)定的臨界點(diǎn),以顯示和隱藏第四個(gè)按鈕 $(window).on("scroll",function(){ checkPosition($(window).height()); }); //解決bug:在刷新頁面時(shí)也出現(xiàn)第四個(gè)按鈕,即頁面加載時(shí)就檢查一下滾動(dòng)位置 checkPosition($(window).height()); //------------------------------分割線------------------------------------------ //move函數(shù)的具體實(shí)現(xiàn),加動(dòng)畫效果 function move(){ $("html, body").animate({ scrollTop:0 },800); } //go函數(shù)可以立即移動(dòng)到頂部 function go(){ $("html, body").scrollTop(0); } //checkPosition函數(shù)的具體實(shí)現(xiàn) function checkPosition(pos){ if($(window).scrollTop() > pos){ $("#backTop").fadeIn(); }else{ $("#backTop").fadeOut(); } } });
分割線以上是執(zhí)行的代碼,分割線以下是寫的被調(diào)用的函數(shù)。
(5)將功能抽象成模塊上述代碼雖然實(shí)現(xiàn)了功能,但是存在以下問題:
move和go函數(shù)都是到達(dá)頂部的功能,實(shí)現(xiàn)的功能很相似,作用如果想在其它地方使用這個(gè)功能,就要再進(jìn)行代碼的復(fù)制,不方便功能的復(fù)用。所以應(yīng)該將功能抽象成模塊。
實(shí)現(xiàn)功能的功能單一:兩個(gè)函數(shù)都是到達(dá)頂部,這樣即便抽象成模塊也會(huì)受到很大的限制,所以可以進(jìn)一步將問題抽象成移動(dòng)滾動(dòng)條到指定位置。
第一步:創(chuàng)建一個(gè)新模塊,用scrollto.js表示,目前這個(gè)demo的目錄結(jié)構(gòu)如圖:
第二步:將功能抽象成模塊,寫入scrollto.js中
//1.先定義這個(gè)模塊,因?yàn)橐玫絡(luò)query,所以還要引入jquery define(["jquery"],function($){ //定義構(gòu)造函數(shù) function ScrollTo(opts){ this.opts = $.extend({},ScrollTo.DEFAULTS,opts); //實(shí)現(xiàn)傳參覆蓋 this.$el = $("html, body"); } //原型添加方法 ScrollTo.prototype.move = function (){ var opts = this.opts; this.$el.animate({ scrollTop:opts.dest },opts.speed); }; ScrollTo.prototype.go = function(){ this.$el.scrollTop(opts.dest); }; //定義默認(rèn)的參數(shù) ScrollTo.DEFAULTS = { dest:0, speed:800 }; //定義接口 return { ScrollTo:ScrollTo }; });
代碼詳解:
傳遞的參數(shù)為一個(gè)對(duì)象,用opts表示
用戶沒有傳遞參數(shù)時(shí),使用默認(rèn)的參數(shù),默認(rèn)參數(shù)直接寫在ScrollTo構(gòu)造函數(shù)上,相當(dāng)于形成一個(gè)靜態(tài)屬性,然后通過jquery的extend()方法進(jìn)行原型的擴(kuò)展
實(shí)現(xiàn)用戶傳遞參數(shù)用之,不傳遞參數(shù)用默認(rèn)值。jquery的extend()方法
在原型上添加move和go方法
第三步:在入口文件main.js中引入這個(gè)scrollto.js的模塊
requirejs(["jquery","scrollto"], function($,scrollto){ //為了使用scrollto模塊,需要實(shí)例化一下 var scroll = new scrollto.ScrollTo({ dest:0, speed:2000 }); //點(diǎn)擊回到頂部按鈕回到指定位置功能 $("#backTop").on("click", $.proxy(scroll.move, scroll)); });
上述代碼中有一點(diǎn)需要注意:
在第6行中,如果添加點(diǎn)擊按鈕回到指定位置事件時(shí),這么寫:
$("#backTop").on("click", scroll.move);
此時(shí)瀏覽器控制臺(tái)會(huì)報(bào)錯(cuò):Uncaught TypeError: Cannot read property "ScrollTo" of undefined
分析原因是因?yàn)?,在main.js中調(diào)用scrollto.js模塊中在ScrollTo.prototype.move原型方法move時(shí),main.js中this指的是ScrollTo的實(shí)例,即scrollto,而在語句$("#backTop").on("click", scroll.move);中,這個(gè)this指代的是id為backTop的這個(gè)按鈕。
解決辦法:用jquery提供的方法,直接將this指向scroll對(duì)象。
$("#backTop").on("click", $.proxy(scroll.move, scroll))
第四步:一個(gè)bug
這時(shí)基本功能雖然實(shí)現(xiàn)了,點(diǎn)擊底部那個(gè)按鈕,傳入設(shè)定的返回位置和返回的速度,頁面可以再次返回頂部指定位置,但是目前還存在一個(gè)bug:在點(diǎn)擊底部按鈕回到頂部指定位置時(shí),假如連續(xù)多次點(diǎn)擊這個(gè)按鈕,則頁面回到頂部后就無法再次向下滾動(dòng)頁面。
bug分析:
假如執(zhí)行的函數(shù)如上面第三步中代碼,速度設(shè)置成較慢的速度2000,那么在返回頂部指定位置時(shí)可以多次點(diǎn)擊這個(gè)按鈕,
這樣每次點(diǎn)擊按鈕事件都要調(diào)用move方法執(zhí)行里面的動(dòng)畫,點(diǎn)擊多少次,這個(gè)動(dòng)畫就要執(zhí)行多少次。
因此在頁面返回頂部后,再次滾動(dòng)頁面向下會(huì)立即執(zhí)行返回頂部動(dòng)畫,所以在執(zhí)行完點(diǎn)擊次數(shù)的動(dòng)畫之前,用戶都無法向下滾動(dòng)。(并且非常耗性能)
解決辦法,在滾動(dòng)條正在運(yùn)動(dòng)或者已經(jīng)到達(dá)目的地,就不應(yīng)該執(zhí)行動(dòng)畫。添加判斷。
所以scrollto.js的代碼可以改成如下:
define(["jquery"],function($){ //定義構(gòu)造函數(shù) function ScrollTo(opts){ this.opts = $.extend({},ScrollTo.DEFAULTS,opts); //實(shí)現(xiàn)傳參覆蓋 this.$el = $("html, body"); } //原型添加方法 ScrollTo.prototype.move = function (){ var opts = this.opts; if ($(window).scrollTop() != opts.dest){ //判斷是否到達(dá)指定位置 if(!this.$el.is(":animated")){ //判斷是否在運(yùn)動(dòng) this.$el.animate({ scrollTop:opts.dest },opts.speed); } } }; ScrollTo.prototype.go = function(){ var dest = this.opts.dest; if($(window).scrollTop() != dest){ this.$el.scrollTop(dest); } }; //定義默認(rèn)的參數(shù) ScrollTo.DEFAULTS = { dest:0, speed:800 }; //定義接口 return { ScrollTo:ScrollTo }; });(6)將返回頂部整體抽象成模塊
我們把返回的功能函數(shù)move和go都抽象在了scrollto.js模塊中,現(xiàn)在還可以直接把整個(gè)返回頂部的功能(包括滾動(dòng)一定距離后隱藏的按鈕出現(xiàn),和點(diǎn)擊按鈕之后回到頂部指定位置)
然后在入口文件中只需要引入這個(gè)模塊(取名叫backtop.js),這個(gè)back.js需要依賴上面定義的scrollto.js模塊。
所以目前的項(xiàng)目目錄如下圖:
第一步:現(xiàn)在來寫backtop.js模塊
define(["jquery", "scrollto"], function($, scrollto){ //執(zhí)行函數(shù)部分 function BackTop(el, opts){ this.opts = $.extend({}, BackTop.DEFAULTS, opts); this.$el = $(el); //el是節(jié)點(diǎn) this.scroll = new scrollto.ScrollTo({ dest: 0, speed: this.opts.speed }); this._checkPosition(); //加載時(shí)就檢查位置,解決bug if(this.opts.mode == "move"){ //是move才執(zhí)行move函數(shù),其他執(zhí)行g(shù)o this.$el.on("click", $.proxy(this._move, this)); }else{ this.$el.on("click", $.proxy(this._go, this)); } $(window).on("scroll", $.proxy(this._checkPOsition, this)); } //定義默認(rèn)屬性部分 BackTop.DEFAULTS = { mode: "move", pos: $(window).height(), speed: 800 }; //定義功能函數(shù)部分 BackTop.prototype._move = function(){ this.scroll.move(); }; BackTop.prototype._go = function(){ this.scroll.go(); }; BackTop.prototype._checkPosition = function(){ if($(window).scrollTop() > this.opts.pos){ this.$el.fadeIn(); }else{ this.$el.fadeOut(); } }; //暴露模塊接口,返回整個(gè)對(duì)象 return{ BackTop: BackTop }; });
第二步:scrollto.js保持不變
第三步:寫main.js入口文件
//定義別名 requirejs.config({ paths: { jquery: "jquery-3.1.0" } }); //調(diào)用backtop.js模塊 requirejs(["jquery", "backtop"], function($, backtop){ //實(shí)例化BackTop new backtop.BackTop($("#backtop"),{ mode: "move", pos:100, speed: 2000 }); });4.總結(jié)
這個(gè)demo中的模塊化是這樣一種思想:
首先把功能函數(shù)放在一個(gè)模塊中(move和go)
把整個(gè)實(shí)現(xiàn)功能也抽象成一個(gè)模塊,依賴上一個(gè)功能函數(shù)模塊
最后只需要在入口文件中實(shí)例化一下這個(gè)最外層的模塊,即可完成一系列功能的調(diào)用。
每個(gè)模塊都用面向?qū)ο蟮乃枷?,定義模塊并且暴露接口
默認(rèn)值的用法可以讓調(diào)用者拿起就用,可以不用考慮傳參數(shù)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/86384.html
摘要:特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯(cuò)誤的地方,還請(qǐng)斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會(huì)及時(shí)更新,平時(shí)業(yè)務(wù)工作時(shí)也會(huì)不定期更...
摘要:目前,通行的模塊規(guī)范主要有兩種和。所有依賴某些模塊的語句均放置在回調(diào)函數(shù)中。首先采用了模塊化的概念。然后通過參數(shù)一,參數(shù)二參數(shù)一是數(shù)組,傳入我們需要引用的模塊名,第二個(gè)參數(shù)是個(gè)回調(diào)函數(shù),回調(diào)函數(shù)傳入一個(gè)變量,代替剛才所引入的模塊。 什么是模塊化開發(fā)? 前端開發(fā)中,起初只要在script標(biāo)簽中嵌入幾十上百行代碼就能實(shí)現(xiàn)一些基本的交互效果,后來js得到重視,應(yīng)用也廣泛起來了,jQuery,...
摘要:介紹一款模塊加載工具的入門,并且重點(diǎn)介紹其優(yōu)化工具。發(fā)布目錄項(xiàng)目源代碼工具目錄,例如構(gòu)建工具等。另外,前端代碼發(fā)布前都會(huì)進(jìn)行壓縮,使文件足夠小。原來是因?yàn)槔锪耍詢?yōu)化工具把也合并進(jìn)來了。而優(yōu)化工具要用好,要多嘗試他們的配置選項(xiàng)。 前端變化太快,如今RequireJS已經(jīng)無法吸引眼球了。介紹一款模塊加載工具:RequireJS的入門,并且重點(diǎn)介紹其優(yōu)化工具。 一、RequireJS簡介...
摘要:首先,作為入門的話,的用戶手冊(cè)是個(gè)很不錯(cuò)的選擇,里面基本覆蓋了使用的各方面。所以下面主要是我學(xué)習(xí)的一些筆記,姑且當(dāng)作是一篇入門吧。下面我們正式進(jìn)入正題。這也是最常用的一個(gè)用法之一。有兩個(gè)方式進(jìn)行配置。 首先,作為入門的話,Babel的用戶手冊(cè)是個(gè)很不錯(cuò)的選擇,里面基本覆蓋了Babel使用的各方面。所以下面主要是我學(xué)習(xí)Babel的一些筆記,姑且當(dāng)作是一篇入門吧。 Babel是什么 按照B...
摘要:應(yīng)用日益復(fù)雜,模塊化已經(jīng)成為一個(gè)迫切需求。異步模塊加載機(jī)制。引用的資源列表太長,懶得回調(diào)函數(shù)中寫一一對(duì)應(yīng)的相關(guān)參數(shù)假定這里引用的資源有數(shù)十個(gè),回調(diào)函數(shù)的參數(shù)必定非常多這就是傳說中的 簡述 緣起 模塊通常是指編程語言所提供的代碼組織機(jī)制,利用此機(jī)制可將程序拆解為獨(dú)立且通用的代碼單元。 模塊化主要是解決代碼分割、作用域隔離、模塊之間的依賴管理以及發(fā)布到生產(chǎn)環(huán)境時(shí)的自動(dòng)化打包與處理等多個(gè)方面...
閱讀 2340·2023-04-25 14:17
閱讀 1532·2021-11-23 10:02
閱讀 2177·2021-11-23 09:51
閱讀 890·2021-10-14 09:49
閱讀 3392·2021-10-11 10:57
閱讀 2930·2021-09-24 09:47
閱讀 3058·2021-08-24 10:00
閱讀 2307·2019-08-29 18:46