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