事件是視圖層到邏輯層的通信方式,當我們點擊tap、觸摸touch、長按longpress小程序綁定了事件的組件時,就會觸發(fā)事件,執(zhí)行邏輯層中對應的事件處理函數(shù)。
小程序框架的視圖層由 WXML 與 WXSS 來編寫的,由組件來進行展示。將邏輯層的數(shù)據(jù)反應成視圖,同時將視圖層的事件發(fā)送給邏輯層。邏輯層將數(shù)據(jù)進行處理后發(fā)送給視圖層,同時接受視圖層的事件反饋。
使用開發(fā)者工具新建一個tapevent的頁面(直接在app.json的pages配置項第一行添加一個tapevent的頁面,由于是第一項,這樣就可以成為小程序的首頁呈現(xiàn)出來),然后將以下代碼輸入到tapevent.wxml文件里:
<button type="primary" bindtap="scrollToPosition">滾動到頁面指定位置</button>
<view class="pagetop" style="background-color:#333;width:100%;height:400px"></view>
<button type="primary" bindtap="scrollToTop">滾動到頁面頂部(返回頂部)</button>
<view id="pageblock" style="background-color:#333;width:100%;height:400px"></view>
這里的type="primary"
只是引入weui給button添加的樣式。而函數(shù)名scrollToPosition和scrollToTop是可以自己定義的,然后我們再來在相應的js文件里要添加和函數(shù)名scrollToPosition和scrollToTop對應的事件處理函數(shù)。
在tapevent.js的Page({})
里(也就是和 data:{}
、 onLoad: function (options) { }
等函數(shù)平級),輸入以下代碼:
scrollToTop() {
wx.pageScrollTo({
scrollTop: 0,
duration: 300
})
},
scrollToPosition() {
wx.pageScrollTo({
scrollTop: 6000,
duration: 300
})
},
當用戶點擊該button組件的時候會在該頁面對應的Page中找到相應的事件處理函數(shù)。保存編譯之后,看看是不是就有了頁面滾動的效果了?原理是scrollToTop()和scrollToPosition()這兩個函數(shù)實際上都是調用了同一個小程序的滾動API wx.pageScrollTo(),關于該API的具體參數(shù)信息,我們可以查閱技術文檔。
滾動API技術文檔:wx.pageScrollTo(Object object)
在官方文檔我們可以看到wx.pageScrollTo()的作用是將頁面滾動到目標位置,支持選擇器和滾動距離兩種方式定位
那如何滾動到指定的選擇器的位置呢?前面我們已經(jīng)給view分別添加了id和class的選擇器,只需要將之前的函數(shù)的配置信息修改為如下(注意哦,如果你是添加而不是修改,函數(shù)名會沖突的,或者你可以起其他的函數(shù)名):
scrollToTop() {
wx.pageScrollTo({
duration: 3000,
selector:".pagetop"
})
},
scrollToPosition() {
wx.pageScrollTo({
duration: 300,
selector:"#pageblock"
})
},
小任務:如果只是在組件上綁定了事件也就是只有 bindtap="scrollToPosition",但是并沒有在js文件里寫相應的事件處理函數(shù)scrollToPosition,看一下控制臺Console會報什么錯?
不要誤以為只有button組件才可以綁定事件哦,還記得我們小程序組件里看的技術文檔小程序組件嗎?在公共屬性部分,可以看到所有組件都有以下屬性bind / catch,這個屬性的類型是EventHandler,bindtap就是bind*的一個類型。也就是說小程序的所有組件都可以通過以上方法觸發(fā)事件處理函數(shù),達到滾動等效果。使用button為案例只是為了便于展示而已。
命名規(guī)范:JavaScript的項目名、函數(shù)名、變量等都應該遵循簡潔、語義化的原則。函數(shù)名推薦使用駝峰法來命名(camelCase),比如scrollToTop、pageScrollTo,也就是由小寫字母開始,后續(xù)每個單詞首字母都大寫,長得跟駱駝????的駝峰似的。
消息提示框是移動端App、H5(WebApp)、小程序經(jīng)常會使用到的一個交互界面。在tapevent.wxml輸入代碼:
<button type="primary" bindtap="toastTap">點擊彈出消息對話框</button>
在js里輸入以下代碼:
toastTap() {
wx.showToast({
title: '購買成功',
icon: 'success',
duration: 2000
})
},
消息提示技術文檔:wx.showToast(Object object)
小任務:修改title、icon和duration,以及添加image屬性,看看會有什么樣不同的表現(xiàn)形式,以及你在哪個App的何種場景下見過類似的消息提示信息?
為了讓界面顯示的更加簡潔,你可以使用快捷鍵Ctrl+/(Mac為Command+/)來將上面wxml里的代碼注釋掉,js文件里面的函數(shù)就不用注釋啦
使用開發(fā)者工具繼續(xù)在tapevent.wxml文件里添加代碼,這次我們會調用一下小程序的模態(tài)框(還是強調modalTap是你可以根據(jù)命名規(guī)范任意命名的,只需要在js里添加相應的事件處理函數(shù)就可以調用API):
<button type="primary" bindtap="modalTap">顯示模態(tài)對話框</button>
然后再在tapevent.js中輸入以下代碼:
modalTap() {
wx.showModal({
title: '學習聲明',
content: '學習小程序的開發(fā)是一件有意思的事情,我決定每天打卡學習',
showCancel: true,
confirmText: '確定',
success(res) {
if (res.confirm) {
console.log('用戶點擊了確定')
} else if (res.cancel) {
console.log('用戶點擊了取消')
}
}
})
},
保存編譯之后,點擊模擬器上的按鈕,就可以顯示出一個對話框,這個對話框我們稱之為Modal模態(tài)對話框。
模態(tài)對話框技術文檔:wx.showModal(Object object)
閱讀API的技術文檔,就要了解該API有哪些屬性,屬性代表得是什么含義,屬性是什么類型(這一點非常重要),以及它的默認值是什么,可以有哪些取值。
通過給API已有的屬性賦不同的值,API所展現(xiàn)的內(nèi)容就會有很多種變化,而具體要怎么用,則需要你根據(jù)實際的小程序開發(fā)項目來使用了。
小任務:在哪些App、小程序、H5(WebApp)你會看到模態(tài)框?這些模態(tài)框是在什么情況下出現(xiàn)的,它的作用是啥?你能模仿這些模態(tài)框寫一下配置信息嗎?
點擊模態(tài)框上面的取消、確定按鈕,留意一下開發(fā)者工具調試器Console的日志打印信息:當我們點擊取消按鈕時,會打印“用戶點擊了取消”;當我們點擊確定按鈕時,會打印“用戶點擊了確定”,而這打印的結果是由上面的這段代碼輸出的:
success(res) {
if (res.confirm) {
console.log('用戶點擊了確定')
} else if (res.cancel) {
console.log('用戶點擊了取消')
}
}
那這段代碼到底怎么理解呢?除了 console.log('用戶點擊了確定'),這個之前接觸過可以理解外,res是什么?res.confirm、res.cancel是什么,從哪里來的?我們可以使用console.log()打印一下。將上面這段代碼增加一些打印信息。
success(res) {
console.log(res)
if (res.confirm) {
console.log(res)
console.log("點擊確認之后的res.confirm是:" + res.confirm)
console.log("點擊確認之后的res.cancel是:" + res.cancel)
} else if (res.cancel) {
console.log(res)
console.log('用戶點擊了取消')
console.log("點擊取消之后的res.confirm是:" + res.confirm)
console.log("點擊取消之后的res.cancel是:" + res.cancel)
}
}
再來編譯之后點擊模態(tài)框的取消和確定按鈕,看打印出來什么結果。當點擊確認時,res.confirm的值為true,就執(zhí)行if分支里的語句;當res.cancel的值為true,就執(zhí)行res.cancel的語句。在模態(tài)對話框技術文檔:wx.showModal(Object object)也有object.success 回調函數(shù)的說明。
success、fail、complete回調函數(shù) 在技術文檔里可以看到屬性里有success和fail兩個回調函數(shù),success為接口調用成功的回調函數(shù);fail為接口調用失敗的回調函數(shù)。關于這方面的知識大家可以閱讀技術文檔小程序API,大致了解一下異步API與回調函數(shù)的參數(shù),理解異步 API 的執(zhí)行結果需要通過 Object 類型的參數(shù)中傳入的對應回調函數(shù)獲取。(不理解也沒有關系)
手機振動API分兩種,一種是長振動,一種是短振動,兩個API寫法大致相同,為了體驗效果,我們以長振動為例,在tapevent.wxml里輸入以下代碼,
<button type="primary" bindtap="vibrateLong">長振動</button>
然后再在tapevent.js里添加與之對應的事件處理函數(shù):
vibrateLong() {
wx.vibrateLong({
success(res) {
console.log(res)
},
fail(err) {
console.error(err)
},
complete() {
console.log('振動完成')
}
})
},
保存編譯之后,點擊預覽,使用手機掃描來體驗一下長振動的效果。
長振動技術文檔:wx.vibrateLong()
在長振動技術文檔里我們再次看到API里三個回調函數(shù),success、fail、complete。在模擬器上點擊按鈕時,就可以看到打印日志。console.error向控制臺的console中打印 error 日志,如果不能調用長振動,那一般是手機權限的問題了。
小任務:參考長振動的代碼以及短振動的技術文檔,寫一個短振動的案例,體驗一下兩者有什么不同。
下面我們來了解一下操作操作,在tapevent.wxml輸入以下代碼
<button type="default" bindtap="actionSheetTap">彈出操作菜單</button>
然后再在tapevent.js里添加與之對應的事件處理函數(shù):
actionSheetTap() {
wx.showActionSheet({
itemList: ['添加照片', '刪除照片', '更新照片', '查詢更多'],
success(e) {
console.log(e.tapIndex)
}
})
},
彈出菜單技術文檔:wx.showActionSheet(Object object)
保存之后在模擬器體驗,點擊按鈕就會彈出顯示添加照片、刪除照片、更新照片、查詢更多等選項的操作菜單,當然我們點擊操作菜單的選項之后是沒有反應的,點擊之后的反應還需要我們以后來寫事件處理函數(shù)才行。
當我們點擊操作菜單的不同選項時,會返回不同的數(shù)字,這取決于success回調函數(shù)里的e.tapIndex的值。在官方文檔里我們可以了解到,當用戶點擊的按鈕序號,從上到下的順序,從0開始,相當于對應著數(shù)組itemList的序號,這樣就為我們以后根據(jù)不同的菜單選項來執(zhí)行不同的操作提供了可能。
小任務:在success(e){}回調函數(shù)里,添加console.log(e)打印e以及console.log(e.errMsg)打印e的errMsg對象看看是什么結果。
頁面路由是一個非常重要的概念,打開新頁面、頁面返回、Tab頁面切換、頁面重定向等都是也能路由的不同方式。
關于頁面路由,大家可以閱讀一下頁面路由技術文檔,頁面路由我們可以簡單的理解為對頁面鏈接的管理,根據(jù)不同的url鏈接來顯示不同的內(nèi)容和頁面信息。在后面的章節(jié)我們還會具體講一下頁面路由的知識的,不必苛求一次性都搞明白。
在前面我們已經(jīng)學習過Navigator組件,在navigator組件的技術文檔里,我們可以看到open-type屬性以及合法值。在小程序API左側也可以看到5個不同的API。它們之間的對應關系如下:
頁面路由API | Navigator open-type值 | 含義 |
---|---|---|
redirectTo | redirect | 關閉當前頁面,跳轉到應用內(nèi)的某個頁面。但是不允許跳轉到 tabbar 頁面。 |
navigateTo | navigate | 保留當前頁面,跳轉到應用內(nèi)的某個頁面。但是不能跳到 tabbar 頁面。 |
navigateBack | navigateBack | 關閉當前頁面,返回上一頁面或多級頁面。 |
switchTab | switchTab | 跳轉到 tabBar 頁面,并關閉其他所有非 tabBar 頁面 |
reLaunch | reLaunch | 關閉所有頁面,打開到應用內(nèi)的某個頁面 |
也就是說Navigator組件可以做到的事情,使用JavaScript調用小程序也能路由API也可以做到。Navigator組件的內(nèi)容是寫死的,而JavaScript則可以提供動態(tài)的數(shù)據(jù)。
我們可以在之前創(chuàng)建的home.wxml里輸入以下代碼:
<button bindtap="navigateTo">保留頁面并跳轉</button>
<button bindtap="switchTab">跳轉到組件Tab頁</button>
<button bindtap="redirectTo">關閉當前頁面跳轉</button>
然后在home.js文件里添加以下代碼:
navigateTo() {
wx.navigateTo({
url: '/pages/home/imgshow/imgshow'
})
},
switchTab() {
wx.switchTab({
url: '/pages/list/list',
})
},
redirectTo() {
wx.redirectTo({
url: '/pages/home/imgshow/imgshow'
})
},
保存之后在開發(fā)者工具的模擬器點擊按鈕,就實現(xiàn)了頁面和Tab頁的切換效果。在前面我們提到bintap是小程序所有組件的公有屬性,只有bintap綁定了頁面路由切換的事件處理函數(shù),組件是不是Navigator也就不重要了,也就是鏈接跳轉不再是Navigator組件的專利。
注意這里的url的路徑,我們使用的是相對于小程序根目錄的絕對路徑。app.json的pages配置項前面沒有/是因為app.json本來就在根目錄,所以可以使用相對路徑以及這里的取值,以及API很多參數(shù)的字符串String類型的賦值,單引號和雙引號都是沒有影響的。
在home頁面里的imgshow文件夾下的imgshow.wxml(在小程序開發(fā)的第一部分建過這個頁面,如果沒有,你再創(chuàng)建也可以)輸入以下代碼:
<button bindtap="navigateBack">返回上一頁</button>
在imgshow.js里添加以下代碼
navigateBack() {
wx.navigateBack({
delta: 1
})
},
點擊保留頁面跳轉按鈕以及返回上一頁按鈕,這樣我們就可以在小程序里通過點擊組件實現(xiàn)了頁面的切換與頁面的返回。而如果是使用wx.redirectTo跳轉到新的頁面就沒法使用返回上一頁了。
wx.navigateTo 是保留當前頁面、跳轉到應用內(nèi)的某個頁面,使用 wx.navigateBack可以返回到原頁面。對于頁面不是特別多的小程序,且頁面間存在經(jīng)常切換時,推薦使用 wx.navigateTo進行跳轉, 然后返回,提高加載速度。
更多建議: