1. 程式人生 > >利用JS 事件 與 Cnavas繪圖 以及 H5 快取寫的一個手勢解鎖(一)

利用JS 事件 與 Cnavas繪圖 以及 H5 快取寫的一個手勢解鎖(一)

之前參加360前端實習生 星計劃時,遇到一個任務,就是利用H5 localStorage實現密碼的存入和獲取。當時還沒有學canvas 繪圖,感覺利用原生JS和CSS實現比較複雜;這次剛好看了JS高程的Canvas繪圖,所以正好可以理論與實踐結合一下,試著做了一下這個。當然,這只是一個初期的效果,後期還會再改善。

由於手勢繪製密碼,需要用到觸控事件的一些東西,所以我會在開頭先講一下JS的事件機制,希望大家能耐心看完!(* _ *)所以整篇部落格的目錄如下:

  1. JS事件機制
  2. Canvas繪圖原理
  3. H5快取機制

JS事件機制

  1. 事件流
    JS主要用於使用者和瀏覽器之間的互動,這種互動往往通過事件的方式來實現。而觸發頁面中的某個元素實質上也觸發了包含他的元素,這就類似於有很多同心圓,我們指向最裡面圓的圓心時,實際也指向了其他圓的圓心。而事件流就是指這些”同心圓”事件觸發的順序。
    現在主要有兩種事件流,一種是冒泡事件流(IE主打),另一種是捕獲事件流(網景公司主打)。
    為了直觀一些,我用下面的圖來表示各種事件流:
    事件冒泡流,捕獲流,DOM事件流

  2. 事件處理程式
    學過計組的應該都知道,中斷的概念,每個中斷對應一箇中斷處理程式,這一點類似於我們的JS事件,每個事件也有一個事件處理程式,不過這是要我們去自定義的。在JS中,有四種事件處理程式。

一、 HTML事件處理程式
直接看程式碼吧

<button onclick = function(){ alert("HTML事件!"); }>點選之後觸發事件</button>

不難理解,這段程式碼在button 元素上綁定了一個事件,點選滑鼠就會觸發那個事件處理程式。
但這種方式的缺點主要是JS和HTML耦合性比較高,不利於後面的維護。
二、DOM 0級事件處理程式

<button id="btn">點選之後觸發事件</button>
<script>
    document.getElmentById("btn").onclick = function(){
        alert("DOM 0級事件!");
    }
</script>

這種方式是將事件處理程式繫結在對應的DOM物件上,該方式解決了HTML程式碼與JS耦合的問題,但是需要注意,在頁面未加載出來時,去訪問id 為btn的元素是會出錯的。不過沒關係,如下程式碼就可以解決

<script>
window.onload = function
(){
document.getElmentById("btn").onclick = function(){ alert("DOM 0級事件!"); } }
</script>

三、 DOM 2級事件處理程式
這種處理程式是通過兩個api註冊事件和刪除事件的:
addEventListener(eventName, handler, ifCapture); //註冊事件
removeEventListener(eventName, handler, ifCapture); //刪除事件

注意:刪除事件的handler必須與註冊事件中傳入的引數一致

var handler = function(){
    alert("DOM 2級事件處理程式");
}
document.getElmentById("btn").addEventListener('click', handler, false);      
//false表示不進行事件捕獲
//當不需要事件處理函式時,將其刪除掉   
//document.getElmentById("btn").removeEventListener('click', handler, false);  

四、 IE事件處理程式
IE 事件處理程式是針對IE瀏覽器的,並且只支援冒泡,不支援事件捕獲。
它也提供了兩個api來註冊事件處理程式和刪除事件處理程式,與DOM 2級不同的是:事件名這裡是on+事件名,比如:點選事件就是onclick。看下面程式碼就很明白了:

var handler = function(){
    alert("IE事件處理程式");
}
document.getElmentById("btn").attachEvent('onclick', handler);
//當不需要事件處理函式時,將其刪除掉   
//document.getElmentById("btn").detachEventL('onclick', handler); 

對於上面四種事件處理程式,有一個特別需要注意的一點:
只有IE事件處理程式的作用域是全域性作用域,也就是說this 指的是window物件
其他DOM 事件處理程式的作用域就是相應元素;
我們可以做一個瀏覽器能力檢測從而使註冊事件處理程式得到好的相容性。
3. 事件物件
事件物件只在事件處理程式執行時才存在。
一、DOM 中的事件物件

相容DOM事件的瀏覽器在事件處理程式執行時都會傳入一個event物件。這個物件擁有一系列的屬性和方法:

Property/Methods Type decription
PreventDefalut Function 取消事件的預設行為
taget Element 事件的目標元素
stopPropagation Function 取消冒泡
type String 事件型別

這裡只列舉了常用的幾種屬性和方法,若要了解詳細的事件物件,可以在瀏覽器控制檯將事件物件輸出,可看到詳細的事件物件。

二、 IE中的事件物件
在IE 中的事件物件,根據指定事件處理程式的方式,IE 中的事件物件也不同。
如果採用DOM 0級方式指定事件處理程式,那麼event物件是window物件的一個屬性。

<button id="btn">點選之後觸發事件</button>
<script>
    document.getElmentById("btn").onclick = function(){
        vae e = window.event;
        console.log(e);
        alert("DOM 0級事件!");
    }
</script>

IE 中的事件物件同樣也有一系列屬性。(只有屬性)

Property Type decription
returnValue Boolean 取消事件的預設行為
srcElement Element 事件的目標元素
cancelBubble Boolean 取消冒泡
type String 事件型別

4. 事件型別
常用的事件型別有這麼幾種:
UI事件:(如load事件,unload事件, scroll事件等不一定與使用者操作有關的事件)
焦點事件:(常常與表單元素等一類需獲取焦點的元素結合使用。focus,blur事件,這兩個不支援事件冒泡的事件;因此出現了focusin,focusout事件,DOMFocusIn, DOMFocusOut事件)
滑鼠事件

eventName decription
click 滑鼠點選事件
dblclick 滑鼠雙擊事件
mousedown 滑鼠左鍵按下事件
mouseup 滑鼠左鍵擡起事件(與mousedown可構成一個click事件)

還有很多滑鼠事件,這裡不再陳列,需要注意的一點是:只要涉及到滑鼠操作,在滑鼠事件物件中都有如下屬性:
clientX, clientY (這是當前觸發事件的滑鼠位置在瀏覽器視窗(視口)中的座標)
pageX, pageY(當前觸發事件的滑鼠位置在頁面中的座標,如果頁面沒有滾動的話,與clientX, clientY是一樣的)
screenX, screenY(當前觸發事件的滑鼠位置在整個顯示屏中的座標,也就是相對於桌面左上角點的相對座標)
鍵盤事件
keydown: 按下任意鍵時觸發
keypress: 按下字元鍵時觸發
keyup: 鬆開鍵時觸發
與鍵盤事件相關的就是按下的鍵的值,也就是說keyCode 或 charCode。這也是包含在鍵盤事件物件中的。
HTML5事件
這裡介紹與本次手勢解鎖相關的觸控事件:
根據觸控的種類,觸控事件也有以下這幾個:
touchstart: 開始觸控時觸發
touchend: 在觸控結束時觸發
touchmove: 在觸發移動過程中觸發。注意:在移動裝置上觸控移動時會預設觸發滾動事件,因此利用perventDefalut()將其預設行為取消。
每個觸發事件都對應的事件物件。對於touchstart和touchmove事件,事件物件中有一個touches陣列,這裡麵包括觸控的clientX,clientY,target等屬性資訊。這些對於實現手勢解鎖是很重要的資訊。

事件對於Web效能是有很大影響的,因為註冊的事件處理程式儲存在記憶體中;並且繫結事件處理函式一般都是要先訪問DOM節點的。
那麼在JS事件處理這塊如何去優化效能呢?
兩方面:

  • 事件委託
    何為事件委託?
    如果一個元素內部很多個元素上都要繫結同一類事件處理函式,我們很容易想到每個元素都繫結一個事件處理函式就好了,但是這種情況在元素很多的時候對於效能是由很大影響的,因為你不僅要訪問每個元素,還要形成很多個事件連線,因此,我們採用事件委託的方式來繫結事件處理函式,即只給最外層元素上繫結這類事件,然後利用事件冒泡機制,當事件物件e.target為我們實際要觸發事件的元素物件時,再採取一系列操作。看下面的程式碼:
<ul id="saleType">
    <li>水果</li>
    <li>蔬菜</li>
    <li></li>
</ul>

<script>
    var ulEle = document.getElementById("saleType");
    var handler = function(e){
        if(e.target.innerText == "水果")
        {
            //賣水果的相應操作
        }
        else if(e.target.innerText == "蔬菜")
        {
            //賣蔬菜的相應處理
        }
        else if(e.target.innerText == "書")
        {
            //進行賣書的相應操作
        }
    }
    ulEle.addEventListener('click', handler, false);
</script>
  • 移除事件處理函式
    每次繫結事件處理函式,就會有一個事件連線,,每有一個事件連線,意味著這個函式就有一個引用,但有些情況會造成事件連線還在,但是用不到這個事件連線了,導致函式永遠被引用而不能得到垃圾回收。所以,在確定不會再用的情況下,可以手動來移除事件處理函式。
<div id="container">
    <input id="btn" type="button" value="Button" />
</div>
<input id="btnChange" type="button" value="替換內容" />

<script>
window.onload = function(){
    var btn = document.getElementById('btn');
    btn.onclick = function(){
        alert("按鈕被點選!");
    }
    var btnC = document.getElementById('btnChange');
    btnC.onclick = function(){
        //在此之前,應該先將id為btn的按鈕繫結的事件移除
        btn.onclick = null;
        document.getElementById("container").innerHTML = "<sapn>內容替換掉了</sapn>";
    }   
}
</script>

本次就先總結這麼多吧,下一節我會介紹canvas的原理以及與手勢解鎖實踐的關聯。

相關推薦

利用JS 事件 Cnavas繪圖 以及 H5 快取一個手勢

之前參加360前端實習生 星計劃時,遇到一個任務,就是利用H5 localStorage實現密碼的存入和獲取。當時還沒有學canvas 繪圖,感覺利用原生JS和CSS實現比較複雜;這次剛好看了JS高程的Canvas繪圖,所以正好可以理論與實踐結合一下,試著做了一

NIO原理剖析Netty初步----淺談高性能服務器開發

返回 創建 基於 register 訪問 io操作 nbsp info class 除特別註明外,本站所有文章均為原創,轉載請註明地址 在博主不長的工作經歷中,NIO用的並不多,由於使用原生的Java NIO編程的復雜性,大多數時候我們會選擇Netty,m

利用愛奇藝開放平臺實現視頻托管回調播放——獲取授權

con new 在線 resp 麻煩 簡介 回調 其他人 擔心 背景:   題庫軟件的教學視頻需要實現在線播放,由於技術水平和服務器配置的限制,如果把視頻放在自己服務器上會出現各種問題。訪問人數少的時候還可以勉強應付,臨近考試時,服務器壓力增大,視頻訪問延遲太大,有時根本無

Smobiler資料準備環境搭建——C# 或.NET Smobiler例項開發手機app

目錄 一、 前言 二、 關於"選擇" 三、 資料準備 1、 Smobiler介紹 2、 三款開源軟體原始碼下載 3、 控制元件使用例項 四、 環境搭建到實現HelloWorld 1、 安裝VS2015及以上 2、 安裝Designer 3、 實現Hello

關於H5的一些雜思細想

作為一名前端程式媛,雖然整天和程式碼打交道,但是還是有一顆小清新的內心,雖然有時候加起班來不是人,但是空閒的時候還是會整理一下思緒,順便整理一下自己,兩個多月的加班,一直沒有更新,今天就把自己最近做的一些h5的東西的想法整理一下,也好慰藉一下我這兩個多月的不辭辛苦,好了,上面純屬作為女孩子的自我嘮叨,切入正題

【以太坊開發】利用Oraclize開發一個投注合約:原理介紹

智慧合約的作用很多,但是很多資料還是要基於網際網路,那麼如何在合約中獲取網際網路中的資料?Oraclize就是為了這個目的而誕生的。 本篇介紹如何利用Oraclize開發一個投注智慧合約,開始coding之前,這一節講述一下理論。 工作原理: 智慧合約通過對Oraclize釋出一個合約之間的呼叫請求來獲

【以太坊開發】利用Oraclize開發一個投註合約:原理介紹

tween 協議 簡單方法 type callback 使用 抓取 獲取 num 智能合約的作用很多,但是很多數據還是要基於互聯網,那麽如何在合約中獲取互聯網中的數據?Oraclize就是為了這個目的而誕生的。 本篇介紹如何利用Oraclize開發一個投註智能合約,開始co

執行緒同步

   im專案中都會存在離線訊息,我們在接受到訊息後,開啟子執行緒,處理相關業務邏輯。因為業務邏輯需遵循一定的處理順序,我們將部分程式碼加上了鎖。但是在離線訊息太多時,卻出現了執行緒問題:OutOfMemoryError: pthread_create (1040KB sta

第三章 處理機排程

3.1 處理機排程的層次和排程演算法的目標 1.系統執行並不一定存在高階排程 批處理系統有作業排程,分時系統和實時系統不需要作業排程。 2.引入中級排程的主要目的是,提高記憶體利用率和系統吞吐量,根據條件將一些程序調出或再調入記憶體。 3.排程程式也是程式。 4.排程原則

H5遊戲開發之phaser學習筆記

1、Phaser.Game(width, height, renderer, parent, state, transparent, antialias, physicsConfig) width: 遊戲的寬度,也就是用來渲染遊戲的canvas的寬度,單位為px hei

H5標籤input標籤上傳檔案

之前專案做檔案上傳(本篇著重講純圖片上傳)的時候,一般都是用的flash外掛。 H5的input標籤提供了type=file的檔案上傳功能,那麼如何用這個標籤實現前後端之間的檔案上傳呢。 百度了一下,一個能用的都沒有,都有BUG,講的也很複雜,好氣喔,自己寫

SpringBoot整合Redis,以及MybatisPlus分頁、Mapper的使用

概述 這段時間接觸很多知識,也逐漸深入到專案整個流程開發,對Linux也有逐步地認識。雖然有去探索,但感覺能力還不足以寫出來跟大家分享。撰寫本文是瞭解到有些讀者反饋,對於MP(MybatisPlus縮寫)不太瞭解以及如何去使用,但更多還是筆者用完覺得非常強大,

高併發

      DRP學習中,我們對可能引起併發操作的情況使用了鎖,這次先理論上看看併發控制與鎖的一些內容吧。     併發控制     在多使用者環境中,在同一時間可能會有多個使用者更新相同的記錄,這會

easyui.utils.js 自己封裝的 使用easyui過程中方便操作和取值

注意:該easyui.utils.js  會在我自己使用過程中不斷完善,大家一起進步。 在js上新增 以下 (function($){   function  其他方法。 })(jQuery); 的目的是為了防止該js檔案中的function與瀏覽器本身的一些functi

JavaWEB--POI之EXCEL操作、優化、封裝詳系列--概述原理

鑑於現在部落格混雜臃腫,對POI技術講解得十分不不充分,讓本博主在開發優化時遭遇諸多大坑,為了讓後人更好製作企業級報表,我將在這一系列詳細解說這個以及羅列我所遇到的諸多問題。並且基於強大的POI技術寫一個輔助工具庫給大家。 本系列的所有程式碼均可以直接執行,請

Objective-C高階程式設計 iOSOS X多執行緒和記憶體管理 讀書筆記

1.2.2 記憶體管理原則: 自己生成的物件,自己所持有 非自己生成的物件,自己也能持有 不再需要自己持有的物件時釋放 非自己持有的物件無法釋放 自己生成的物件,自己所持有 //自己生成並持有物件 id obj = [[NSObject alloc] init]; //自己持有物件   

關於UI執行緒非UI執行緒互動,有關Handler機制等

在Android中,一個activity有一個主執行緒也叫UI執行緒,作用就是用來繪製UI介面,在這個執行緒裡面,你的應用和android的UI元件發生互動。所以當你需要進行某些費時操作的時候,比如訪問網路等,如果放入UI執行緒,就會阻塞介面的繪製,當介面不能繪製的時候,整

《資料結構演算法分析-C語言描述》詳-Sec2

第二章為“演算法分析”,該部分主要介紹了電腦科學中目前用於測量一個演算法的運行復雜的具體數學方法;同時給出了多個問題示例,對每個問題分別採用不同複雜度的演算法,可以直觀地瞭解到在解決實際問題時,不僅僅需要能夠得出結果的演算法,更應該給出演算法複雜度更低的演

重讀《學習JavaScript資料結構演算法-第三版》- 第6章 連結串列

定場詩 傷情最是晚涼天,憔悴廝人不堪言; 邀酒摧腸三杯醉.尋香驚夢五更寒。 釵頭鳳斜卿有淚,荼蘼花了我無緣; 小樓寂寞新雨月.也難如鉤也難圓。 前言 本章為重讀《學習JavaScript資料結構與演算法》的系列文章,該章節主要講述資料結構-連結串列,以及實現連結串列的過程和原理。 連結串列 連結串列,為什麼要

模式識別機器學習筆記專欄之貝葉斯分類決策

[toc] > 這是模式識別與機器學習筆記專欄的第一篇,我會持續更新。 在所有的生活場景中,我們無時無刻不在進行著模式識別。比如你看見迎面走來一個人,根據他的長相來辨認出他好像是你一年前某個活動小組的組長,然後你開始決策要不要和他打個招呼。或者你走進水果店,把西瓜拍了個遍來決定最後買哪一個。或者你突