摘要:咱們?yōu)榧磳懙膸?kù)起個(gè)名字為,開始就是如下的樣子啦復(fù)制代碼處理傳進(jìn)來的參數(shù)我們需要在類的構(gòu)造函數(shù)中接收參數(shù),并覆蓋默認(rèn)參數(shù)。
前言
常見的js插件都很少使用ES6的class,一般都是通過構(gòu)造函數(shù),而且常常是手寫CMD、AMD規(guī)范來封裝一個(gè)庫(kù),比如這樣:
// 引用自:https://www.jianshu.com/p/e65...
(function(undefined) {
"use strict" var _global; var plugin = { // ... } _global = (function(){ return this || (0, eval)("this"); }()); if (typeof module !== "undefined" && module.exports) { module.exports = plugin; } else if (typeof define === "function" && define.amd) { define(function(){return plugin;}); } else { !("plugin" in _global) && (_global.plugin = plugin); }
}());
但現(xiàn)在都9102年了,是時(shí)候祭出我們的ES6大法了,可以用更優(yōu)雅的的寫法來實(shí)現(xiàn)一個(gè)庫(kù),比如這樣:
class RememberScroll {
constructor(options) { ... }
}
export default RememberScroll
復(fù)制代碼
在這篇文章,博主主要通過分享最近自己寫的一個(gè)記住頁(yè)面滾動(dòng)位置小插件,講一下如何用class語(yǔ)法配合webpack 4.x和babel 7.x封裝一個(gè)可用的庫(kù)。
項(xiàng)目地址:Github, 在線Demo:Demo
喜歡的朋友希望能點(diǎn)個(gè)Star收藏一下,非常感謝。
需求來源
相信很多同學(xué)都會(huì)遇到這樣一個(gè)需求:用戶瀏覽一個(gè)頁(yè)面并離開后,再次打開時(shí)需要重新定位到上一次離開的位置。
這個(gè)需求很常見,我們平時(shí)在手機(jī)上閱讀微信公眾號(hào)的文章頁(yè)面就有這個(gè)功能。想要做到這個(gè)需求,也比較好實(shí)現(xiàn),但博主有點(diǎn)懶,心想有沒有現(xiàn)成的庫(kù)可以直接用呢?于是去GitHub上搜了一波,發(fā)現(xiàn)并沒有很好的且符合我需求的,于是得自己實(shí)現(xiàn)一下。
為了靈活使用(只是部分頁(yè)面需要這個(gè)功能),博主在項(xiàng)目中多帶帶封裝了這個(gè)庫(kù),本來是在公司項(xiàng)目中用的,后來想想何不開源出來呢?于是有了這個(gè)分享,這也是對(duì)自己工作的一個(gè)總結(jié)。
預(yù)期效果
博主喜歡在做一件事情前先yy一下預(yù)期的效果。博主希望這個(gè)庫(kù)用起來盡量簡(jiǎn)單,最好是插入一句代碼就可以了,比如這樣:
下面就帶著這個(gè)目標(biāo),一步一步去實(shí)現(xiàn)啦。
設(shè)計(jì)方案
需要存哪些信息?
用戶瀏覽頁(yè)面的位置,主要需要存兩個(gè)字段:哪個(gè)頁(yè)面和離開時(shí)的位置,通過這兩個(gè)字段,我們才可以在用戶第二次打開網(wǎng)站的頁(yè)面時(shí),命中該頁(yè)面,并自動(dòng)跳轉(zhuǎn)到上一次離開的位置。
2.存在哪?
記住瀏覽位置,需要將用戶離開前的瀏覽位置記錄在客戶端的瀏覽器中。這些信息可以主要存放在:cookie、sessionStorage、localStorage中。
存放在cookie,大小4K,空間雖有限但也勉強(qiáng)可以。但cookie是每次請(qǐng)求服務(wù)器時(shí)都會(huì)攜帶上的,無形中增加了帶寬和服務(wù)器壓力,所以總體來說是不太合適的。
存放在sessionStorage中,由于僅在當(dāng)前會(huì)話下有效,用戶離開頁(yè)面sessionStorage就會(huì)被清除,所以不能滿足我們的需求。
存放在localStorage,瀏覽器可永久保存,大小一般限制5M,滿足我們需求。
綜上,最后我們應(yīng)該選擇localStorage。
需注意的問題
一個(gè)站點(diǎn)可能有很多頁(yè)面,如何標(biāo)識(shí)是哪個(gè)頁(yè)面呢?
一般來說可以用頁(yè)面的url作為頁(yè)面的唯一標(biāo)識(shí),比如:www.xx.com/article/${id},不同的id對(duì)應(yīng)不同的頁(yè)面。
但博主考慮到現(xiàn)在很多站點(diǎn)都是用spa了,而且常見在url后面會(huì)帶有#xxx的哈希值,如www.xx.com/article/${id}#tag1和www.xx.com/article/${id}#tag2這種情況,這可能表示的是同一個(gè)頁(yè)面的不同錨點(diǎn),所以用url作為頁(yè)面的唯一標(biāo)識(shí)不太可靠。
因此,博主決定將這個(gè)頁(yè)面唯一標(biāo)識(shí)作為一個(gè)參數(shù)來讓使用者來決定,姑且命名為pageKey,讓使用者保證是全站唯一的即可。
如果用戶訪問我們的站點(diǎn)中很多很多的頁(yè)面,由于localStorage是永久保存的,如何避免localStorage不斷累積占用過大?
我們的需求可能僅僅是想近期記住即可,即只需要記住用戶的瀏覽位置幾天,可能會(huì)更希望我們存的數(shù)據(jù)能夠自動(dòng)過期。
但localStorage自身是沒有自動(dòng)過期機(jī)制的,一般只能在存數(shù)據(jù)的時(shí)候同時(shí)存一下時(shí)間戳,然后在使用時(shí)判斷是否過期。如果只能是在使用時(shí)才判斷是否清除,而新訪問頁(yè)面時(shí)又會(huì)生成新的記錄,localStorage中始終都會(huì)存在至少一條記錄的,也就是說無法真正實(shí)現(xiàn)自動(dòng)過期。這里不禁就覺得有點(diǎn)多余了,既然都是會(huì)一直保留記錄在localStorage中,那干脆就不判斷了,咱換一個(gè)思路:只記錄有限的最新頁(yè)面數(shù)量。
舉個(gè)例子:
咱們網(wǎng)站有個(gè)文章頁(yè):www.xx.com/articles/${id},每個(gè)的id表示不同的文章,咱們只記錄用戶最新訪問的5篇文章,即維護(hù)一個(gè)長(zhǎng)度為5的隊(duì)列。
比如當(dāng)前網(wǎng)站有id從1到100篇文章,用戶分別訪問第1,2,3,4,5篇文章時(shí),這5篇文章都會(huì)記錄離開的位置,而當(dāng)用戶打開第六篇文章時(shí),第六條記錄入隊(duì)的同時(shí)第一條記錄出隊(duì),此時(shí)localStorage中記錄的是2,3,4,5,6這幾篇文章的位置,這就保證了localStorage永遠(yuǎn)不會(huì)累積存儲(chǔ)數(shù)據(jù)且舊記錄會(huì)隨著不斷訪問新頁(yè)面自動(dòng)“過期”。
為了更靈活一點(diǎn),博主決定給這個(gè)插件添加一個(gè)maxLength的參數(shù),表示當(dāng)前站點(diǎn)下記錄的最新的頁(yè)面最大數(shù)量,默認(rèn)值設(shè)為5,如果有小伙伴的需求是記錄更多的頁(yè)面,可以通過這個(gè)參數(shù)來設(shè)置。
實(shí)現(xiàn)思路
我們需要時(shí)刻監(jiān)聽用戶瀏覽頁(yè)面時(shí)的滾動(dòng)條的位置,可以通過window.onscroll事件,獲得當(dāng)前的滾動(dòng)條位置:scrollTop。
將scrollTop和頁(yè)面唯一標(biāo)識(shí)pageKey存進(jìn)localStorage中。
用戶再次打開之前訪問過的頁(yè)面,在頁(yè)面初始化時(shí),讀取localStorage中的數(shù)據(jù),判斷頁(yè)面的pageKey是否一致,若一致則將頁(yè)面的滾動(dòng)條位置自動(dòng)滾動(dòng)到相應(yīng)的scrollTop值。
是不是很簡(jiǎn)單?不過實(shí)現(xiàn)的過程中需要注意一下細(xì)節(jié),比如做一下防抖處理。
實(shí)現(xiàn)步驟
逼逼了這么久,是時(shí)候開始擼代碼了。
1.封裝localStorage工具方法
工欲善其事,必先利其器。為更好服務(wù)接下來的工作,咱們先簡(jiǎn)單封裝一下調(diào)用localStorage的幾個(gè)方法,主要是get,set,remove:
// storage.js
const Storage = {
isSupport () {
if (window.localStorage) { return true } else { console.error("Your browser cannot support localStorage!") return false }
},
get (key) {
if (!this.isSupport) { return } const data = window.localStorage.getItem(key) return data ? JSON.parse(data) : undefined
},
remove (key) {
if (!this.isSupport) { return } window.localStorage.removeItem(key)
},
set (key, data) {
if (!this.isSupport) { return } const newData = JSON.stringify(data) window.localStorage.setItem(key, newData)
}
}
export default Storage
復(fù)制代碼
class大法
class即類,本質(zhì)上雖然是一個(gè)function,但使用class定義一個(gè)類會(huì)更直觀。咱們?yōu)榧磳懙膸?kù)起個(gè)名字為RememberScroll,開始就是如下的樣子啦:
import Storage from "./storage"
class RememberScroll {
constructor() { }
}
復(fù)制代碼
1.處理傳進(jìn)來的參數(shù)
我們需要在類的構(gòu)造函數(shù)constructor中接收參數(shù),并覆蓋默認(rèn)參數(shù)。
還記得上面咱們預(yù)期的用法嗎?即new RememberScroll({pageKey: "myPage", maxLength: 10})。
constructor (options) {
let defaultOptions = { pageKey: "_page1", // 當(dāng)前頁(yè)面的唯一標(biāo)識(shí) maxLength: 5 } this.options = Object.assign({}, defaultOptions, options)
}
復(fù)制代碼
如果沒有傳參數(shù),就會(huì)使用默認(rèn)的參數(shù),如果傳了參數(shù),就使用傳進(jìn)來的參數(shù)。this.options就是最終處理后的參數(shù)啦。
2.頁(yè)面初始化
當(dāng)頁(yè)面初始化時(shí),咱們需要做三件事情:
從loaclStorage取出緩存列表
將滾動(dòng)條滾動(dòng)到記錄的位置(若有記錄的話);
注冊(cè)window.onscroll事件監(jiān)聽用戶滾動(dòng)行為; 因此,需要在構(gòu)造函數(shù)中就執(zhí)行initScroll和addScrollEvent這兩個(gè)方法:
import Storage from "./utils/storage"
class RememberScroll {
constructor (options) {
// ... this.storageKey = "_rememberScroll" this.list = Storage.get(this.storageKey) || [] this.initScroll() this.addScrollEvent()
}
initScroll () {
// ...
}
addScrollEvent () {
// ...
}
}
復(fù)制代碼
這里咱們將localStorage中的鍵名命名為_rememberScroll,應(yīng)該能夠盡量避免和平常站點(diǎn)使用localStorage的鍵名沖突。
3.監(jiān)聽滾動(dòng)事件:addScrollEvent()的實(shí)現(xiàn)
addScrollEvent () {
window.onscroll = () => { // 獲取最新的位置,只記錄垂直方向的位置 const scrollTop = document.documentElement.scrollTop || document.body.scrollTop // 構(gòu)造當(dāng)前頁(yè)面的數(shù)據(jù)對(duì)象 const data = { pageKey: this.options.pageKey, y: scrollTop } let index = this.list.findIndex(item => item.pageKey === data.pageKey) if (index >= 0) { // 之前緩存過該頁(yè)面,則替換掉之前的記錄 this.list.splice(index, 1, data) } else { // 如果已經(jīng)超出長(zhǎng)度了,則清除一條最早的記錄 if (this.list.length >= this.options.maxLength) { this.list.shift() } this.list.push(data) } // 更新localStorage里面的記錄 Storage.set(this.storageKey, this.list) }
}
復(fù)制代碼
ps:這里最好需要做一下防抖處理
4.初始化滾動(dòng)條位置: initScroll()的實(shí)現(xiàn)
initScroll () {
// 先判斷是否有記錄 if (this.list.length) { // 當(dāng)前頁(yè)面pageKey是否一致 let currentPage = this.list.find(item => item.pageKey === this.options.pageKey) if (currentPage) { setTimeout(() => { // 一致,則滾動(dòng)到對(duì)應(yīng)的y值 window.scrollTo(0, currentPage.y) }, 0) }
}
復(fù)制代碼
細(xì)心的同學(xué)可能會(huì)發(fā)現(xiàn),這里用了setTimeout,而不是直接調(diào)用window.scrollTo。這是因?yàn)椴┲髟谶@里遇到坑了,這里涉及到頁(yè)面加載執(zhí)行順序的問題。
在執(zhí)行window.scrollTo前,頁(yè)面必須是已經(jīng)加載完成了的,滾動(dòng)條要已存在才可以滾動(dòng)對(duì)吧。如果頁(yè)面加載時(shí)直接執(zhí)行,當(dāng)時(shí)的scroll高度可能為0,window.scrollTo執(zhí)行就會(huì)無效。如果頁(yè)面的數(shù)據(jù)是異步獲取的,也會(huì)導(dǎo)致window.scrollTo無效。因此用setTimeout會(huì)是比較穩(wěn)的一個(gè)辦法。
5.將模塊export出去
最后我們需要將模塊export出去,整體代碼大概是這個(gè)樣子:
import Storage from "./utils/storage"
class RememberScroll {
constructor (options) {
let defaultOptions = { pageKey: "_page1", // 當(dāng)前頁(yè)面的唯一標(biāo)識(shí) maxLength: 5 } this.storageKey = "_rememberScroll" // 參數(shù) this.options = Object.assign({}, defaultOptions, options) // 緩存列表 this.list = Storage.get(this.storageKey) || [] this.initScroll() this.addScrollEvent()
}
initScroll () {
// ...
}
addScrollEvent () {
// ...
}
}
export default RememberScroll
復(fù)制代碼
這樣就基本完成整個(gè)插件的功能啦,是不是很簡(jiǎn)單哈哈。篇幅原因就不貼具體代碼了,可以直接到GitHub上看:remember-scroll
打包
接下來應(yīng)該是本文的重點(diǎn)了,首先要清楚為什么要打包?
將項(xiàng)目中所用到的js文件合并,只對(duì)外輸出一個(gè)js文件。
使項(xiàng)目同時(shí)支持AMD,CMD、瀏覽器
復(fù)制代碼
這里有個(gè)坑需要注意一下,如果沒有加上libraryExport: "default",由于我們代碼中是export default RememberScroll,打包出來的代碼會(huì)類似:
{
"default": { initScroll () {} }
}
復(fù)制代碼
而我們期望的是這樣:
{
initScroll () {}
}
復(fù)制代碼
即我們希望的是直接輸出default中的內(nèi)容,而不是隔著一層default。所以這里還要加上libraryExport: "default",打包時(shí)只輸出default的內(nèi)容。
PS: webpack英文文檔看得有點(diǎn)懵逼,這個(gè)坑讓博主折騰了很久才爬起來,所以特別講下。剛興趣的同學(xué)可以看下文檔:output.libraryExport。
到這里,已經(jīng)實(shí)現(xiàn)了我們的第二個(gè)小目標(biāo):支持umd規(guī)范。
使用babel-loader
上面我們打包出來的js,其實(shí)已經(jīng)可以正常運(yùn)行在支持es6語(yǔ)法的瀏覽器中了,比如chrome。但想要運(yùn)行在IE10,IE11中,還得讓神器Babel幫我們一把。
PS: 雖然很多人說不考慮兼容IE了,但作為一個(gè)通用性的庫(kù),古董級(jí)的IE7,8,9可以不兼容,但較新版本的IE10,11還是需要兼容一下的。
Babel是一個(gè)JavaScript轉(zhuǎn)譯器,相信大家都聽過。由于JavaScript在不斷的發(fā)展,但是瀏覽器的發(fā)展速度跟不上,新的語(yǔ)法和特性不能馬上被瀏覽器支持,因此需要一個(gè)能將新語(yǔ)法新特性轉(zhuǎn)為現(xiàn)代瀏覽器能理解的語(yǔ)法的轉(zhuǎn)譯器,而Babel就是充當(dāng)了轉(zhuǎn)譯器的角色。
PS:以前博主一直以為(相信很多剛接觸Babel的同學(xué)也是這樣),只要使用了Babel,就可以放心無痛使用ES6的語(yǔ)法了,然而事情并不是這樣。Babel編譯并不會(huì)做polyfill,Babel為了保證正確的語(yǔ)義,只能轉(zhuǎn)換語(yǔ)法而不會(huì)增加或修改原有的屬性和方法。要想無痛使用ES6,還需要配合polyfill。不太理解的同學(xué),在這里推薦大家看下這篇文章:21 分鐘精通前端 Polyfill 方案,寫得非常通俗易懂。
總的來說,就是Babel需要配合polyfill來使用。
Babel更新比較頻繁,網(wǎng)上搜出來的很多配置教程是舊版本的,可能并不適用最新的Babel 7.x,所以我們這里折騰一下最新的webpack4配置Babel方案:babel-loader。 1.安裝babel-loader,@babel/core、@babel/preset-env。
npm install -D babel-loader @babel/core @babel/preset-env core-js
復(fù)制代碼
core-js是JavaScript模塊化標(biāo)準(zhǔn)庫(kù),在@babel/preset-env按需打包時(shí)會(huì)使用core-js中的函數(shù),因此這里也是要安裝的,不然打包的時(shí)候會(huì)報(bào)錯(cuò)。
2.修改webpack.config.js配置,添加rules
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"), filename: "remember-scroll.js", library: "RememberScroll", libraryTarget: "umd", libraryExport: "default"
},
module: {
rules: [ { test: /.m?js$/, exclude: /(node_modules|bower_components)/, use: { loader: "babel-loader" } } ]
}
};
復(fù)制代碼
表示.js的代碼使用babel-loader打包。
3.在根目錄新建babel.config.js,參考Babel官網(wǎng)
const presets = [
[
"@babel/env", { targets: { browsers: [ "last 1 version", "> 1%", "maintained node versions", "not dead" ] }, useBuiltIns: "usage", },
],
];
復(fù)制代碼
browsers配置的是目標(biāo)瀏覽器,即我們想要兼容到哪些瀏覽器,比如我們想兼容到IE10,就可以寫上IE10,然后webpack會(huì)在打包時(shí)自動(dòng)為我們的庫(kù)添加polyfill兼容到IE10。
博主這里用的是推薦的參數(shù),來自:npm browserslist,這樣就能兼容到大多數(shù)瀏覽器啦。
配置好后,npm run dev打包即可。 此時(shí),我們已經(jīng)實(shí)現(xiàn)了第三個(gè)小目標(biāo):兼容低版本瀏覽器。
生產(chǎn)環(huán)境打包
npm run dev打包出來的js會(huì)比較大,一般還需要壓縮一下,而我們可以使用webpack的production模式,就會(huì)自動(dòng)為我們壓縮js,輸出一個(gè)生產(chǎn)環(huán)境可用的包。在package.json再添加一條build命令:
"scripts": {
"test": "echo "Error: no test specified" && exit 1", "build": "webpack --mode=production -o dist/remember-scroll.min.js --colors", "dev": "webpack --mode=development --colors"
},
復(fù)制代碼
這里同時(shí)指定了輸出的文件名為:remember-scroll.min.js,一般生產(chǎn)環(huán)境就是使用這個(gè)文件啦。
發(fā)布到npm
經(jīng)過上面的步驟,我們已經(jīng)寫完這個(gè)庫(kù),有需求的同學(xué)可以將庫(kù)發(fā)布到npm,讓更多的人可以方便用到你這個(gè)庫(kù)。
在發(fā)布到npm前,需要修改一下package.json,完善下描述作者之類的信息,最重要的是要添加main入口文件:
{
"main": "dist/remember-scroll.min.js",
}
復(fù)制代碼
這樣別人使用你的庫(kù)時(shí),可以直接通過import RememberScroll from "remember-scroll"來使用remember-scroll.min.js。
發(fā)布步驟:
先到www.npmjs.com/注冊(cè)一個(gè)賬號(hào),然后驗(yàn)證郵箱。
然后在命令行中輸入:npm adduser,輸入賬號(hào)密碼郵箱登錄。
運(yùn)行npm publish上傳包,幾分鐘后就可以在npm搜到你的包了。
至此,基本就完成一個(gè)插件的開發(fā)發(fā)布過程啦。
不過一個(gè)優(yōu)秀的開源項(xiàng)目,還應(yīng)該要有詳細(xì)的說明文檔,使用示例等等,大家可以參考下博主這個(gè)項(xiàng)目的README.md, 中文README.md。
最后
文章寫了好幾天了,可謂嘔心瀝血,雖然比較啰嗦,但應(yīng)該比較清楚地交代了如何運(yùn)用ES6語(yǔ)法從零寫一個(gè)記住用戶離開位置的js插件,也很詳細(xì)地講解了如何用最新的webpack打包我們的庫(kù),希望能讓大家都有所收獲,也希望大家能到GitHub上點(diǎn)個(gè)Star鼓勵(lì)一下啦。
remember-scroll這個(gè)插件其實(shí)幾個(gè)月前就已經(jīng)發(fā)布到npm了,一直比較忙(懶)沒寫章分享。雖然功能簡(jiǎn)單但很有誠(chéng)意,能兼容到IE9。
使用起來也非常方便簡(jiǎn)單,可直接通過script標(biāo)簽cdn引入,也可以在vue中import RememberScroll from "remember-scroll"使用。文檔中有詳細(xì)的使用示例:
script標(biāo)簽使用方式
vue中使用方式
vue異步獲取數(shù)據(jù)時(shí)使用方式
項(xiàng)目地址Github,在線Demo。
歡迎大家評(píng)論交流,也歡迎PR,同時(shí)希望大家能點(diǎn)個(gè)Star鼓勵(lì)一下啦。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/102713.html
摘要:咱們?yōu)榧磳懙膸?kù)起個(gè)名字為,開始就是如下的樣子啦處理傳進(jìn)來的參數(shù)我們需要在類的構(gòu)造函數(shù)中接收參數(shù),并覆蓋默認(rèn)參數(shù)。 前言 常見的js插件都很少使用ES6的class,一般都是通過構(gòu)造函數(shù),而且常常是手寫CMD、AMD規(guī)范來封裝一個(gè)庫(kù),比如這樣: // 引用自:https://www.jianshu.com/p/e65c246beac1 ;(function(undefined) { ...
摘要:咱們?yōu)榧磳懙膸?kù)起個(gè)名字為,開始就是如下的樣子啦復(fù)制代碼處理傳進(jìn)來的參數(shù)我們需要在類的構(gòu)造函數(shù)中接收參數(shù),并覆蓋默認(rèn)參數(shù)。 前言常見的js插件都很少使用ES6的class,一般都是通過構(gòu)造函數(shù),而且常常是手寫CMD、AMD規(guī)范來封裝一個(gè)庫(kù),比如這樣: // 引用自:https://www.jianshu.com/p/e65... (function(undefined) { use s...
摘要:咱們?yōu)榧磳懙膸?kù)起個(gè)名字為,開始就是如下的樣子啦復(fù)制代碼處理傳進(jìn)來的參數(shù)我們需要在類的構(gòu)造函數(shù)中接收參數(shù),并覆蓋默認(rèn)參數(shù)。 前言常見的js插件都很少使用ES6的class,一般都是通過構(gòu)造函數(shù),而且常常是手寫CMD、AMD規(guī)范來封裝一個(gè)庫(kù),比如這樣: // 引用自:https://www.jianshu.com/p/e65... (function(undefined) { use s...
摘要:歡迎體驗(yàn)提墨瞳漫畫這里踩的坑主要是組件的重用。這樣可以防止圖和圖片大小不一樣引起的頁(yè)面跳動(dòng)繼而導(dǎo)致的加載圖片時(shí)機(jī)錯(cuò)誤??缬驎r(shí),會(huì)先發(fā)送一個(gè)空的請(qǐng)求來查看接口是不是支持跨域,再發(fā)送一次真實(shí)請(qǐng)求。 前言 博主也是vuejs萌新,公司僅我一個(gè)前端,收到做h5的需求后,馬上想到要用下vuejs,于是說服領(lǐng)導(dǎo),開始慢慢鉆研,現(xiàn)在記錄一下踩到的坑。這些坑主要是在一些組件的使用上,其它的只要好好看官...
摘要:一事件的綁定與解綁的簡(jiǎn)單綁定事件新版本使用為指定的元素添加一個(gè)或多個(gè)事件處理程序,并規(guī)定當(dāng)這個(gè)事件發(fā)生時(shí)運(yùn)行的函數(shù)。將整個(gè)文件放至項(xiàng)目的任意目錄不要移動(dòng)其文件結(jié)構(gòu),它們具有完整的依賴體系。 一、事件的綁定與解綁 1.1 jQuery的簡(jiǎn)單綁定 1.1.1 on(events,fn)事件(新版本使用) 為指定的元素添加一個(gè)或多個(gè)事件處理程序,并規(guī)定當(dāng)這個(gè)事件發(fā)生時(shí)運(yùn)行的函數(shù)。on()方法...
閱讀 3484·2021-11-19 09:40
閱讀 1503·2021-10-13 09:41
閱讀 2678·2021-09-29 09:35
閱讀 2723·2021-09-23 11:21
閱讀 1716·2021-09-09 11:56
閱讀 845·2019-08-30 15:53
閱讀 853·2019-08-30 15:52
閱讀 606·2019-08-30 12:47