자 바스 크 립 트 를 이용 하여 사용자 정의 이벤트 메커니즘 을 실현 하 다
이벤트 메커니즘 은 우리 의 웹 개발 에 매우 큰 편 의 를 제공 하여 우리 가 임의의 시간 에 어떤 조작 을 할 때 어떤 조작 을 하고 어떤 코드 를 실행 할 지 지정 할 수 있 게 한다.
이 벤트 를 클릭 하면 사용자 가 클릭 할 때 촉발 합 니 다.keydown,keyup 이벤트,키보드 누 르 기,키보드 팝 업 시 촉발;업로드 컨트롤 중 파일 가입 전 이벤트,업로드 완료 후 이벤트 도 있 습 니 다.
적당 한 시기 에 해당 하 는 사건 이 발생 하기 때문에 우 리 는 이러한 사건 에 해당 하 는 처리 함 수 를 지정 할 수 있 고 원래 의 절차 에 다양한 맞 춤 형 조작 과 처 리 를 삽입 하여 전체 절 차 를 더욱 풍부 하 게 할 수 있다.
예 를 들 어 click,blur,focus 등 사건 은 원래 dom 에서 직접 제공 하 는 네 이 티 브 사건 이 고 우리 가 사용 하 는 다른 컨트롤 들 이 사용 하 는 여러 가지 사건 은 네 이 티 브 dom 에 만 있 는 것 이 아 닙 니 다.예 를 들 어 업로드 컨트롤 에 업로드 시작 과 완료 사건 이 있 는데 이런 사건 들 은 어떻게 이 루어 집 니까?
자신 이 개발 한 컨트롤 에 비슷 한 사건 체 제 를 넣 으 려 면 어떻게 해 야 할 까?끝까지 알 아 보 자.
이벤트 기능
실현 되 기 전에 우 리 는 먼저 사건 체제 에 있어 야 할 기본 적 인 기능 을 분석 해 야 한다.
쉽게 말 하면 사건 은 다음 과 같은 몇 가지 기능 을 제공 해 야 한다.
사건 의 한 특징 을 살 펴 보 자.사건 은 반드시 어떤 대상 에 속 할 것 이다.예 를 들 어 focus 와 blur 이 벤트 는 초점 을 얻 을 수 있 는 dom 요소 이 고 input 이 벤트 는 입력 상자 이 며 업로드 시작 과 업로드 에 성공 하면 업로드 에 성공 합 니 다.
즉,사건 은 독립 적 으로 존재 하 는 것 이 아니 라 운반 체 가 필요 하 다 는 것 이다.그렇다면 우 리 는 어떻게 사건 에 운반 체 를 가지 게 합 니까?간단 한 실현 방안 은 사건 을 하나의 기본 유형 으로 하고 사건 이 필요 한 곳 에서 이 사건 류 를 계승 하면 된다 는 것 이다.
저 희 는 바 인 딩 이벤트,트리거 이벤트,바 인 딩 취소 사건 을 각각 on,fire,off 라 고 명명 합 니 다.그러면 저 희 는 이 사건 종 류 를 간단하게 쓸 수 있 습 니 다.
function CustomEvent() {
this._events = {};
}
CustomEvent.prototype = {
constructor: CustomEvent,
//
on: function () {
},
//
fire: function () {
},
//
off: function () {
}
};
이벤트 바 인 딩먼저 이벤트 의 바 인 딩 을 실현 합 니 다.이벤트 바 인 딩 은 이벤트 의 유형 과 이벤트 의 처리 함 수 를 지정 해 야 합 니 다.
그럼 그 외 에 또 무엇이 필요 할 까요?저 희 는 사용자 정의 이벤트 입 니 다.네 이 티 브 이벤트 처럼 거품 단계 의 트리거 인지 포획 단계 의 트리거 인지 지정 할 필요 가 없습니다.jQuery 처럼 그 요소 의 트리거 를 추가 로 지정 할 필요 도 없습니다.
이벤트 함수 에서 this 는 일반적으로 현재 인 스 턴 스 입 니 다.이것 은 어떤 상황 에서 적용 되 지 않 을 수 있 습 니 다.이벤트 처리 함수 가 실 행 될 때의 컨 텍스트 환경 을 다시 지정 해 야 합 니 다.
따라서 이벤트 바 인 딩 을 확정 할 때 세 가지 매개 변 수 는 이벤트 유형,이벤트 처리 함수,이벤트 처리 함수 실행 컨 텍스트 입 니 다.
그러면 이벤트 바 인 딩 은 무엇 을 해 야 합 니까?사실은 간단 합 니 다.이벤트 바 인 딩 은 해당 하 는 이벤트 이름과 이벤트 처리 함수 만 기록 하면 됩 니 다.
나의 실현 은 다음 과 같다.
{
/**
*
*
* @param {String} type
* @param {Function} fn
* @param {Object} scope
* @returns
*/
on: function (type, fn, scope) {
if (type + '' !== type) {
console && console.error && console.error('the first argument type is requird as string');
return this;
}
if (typeof fn != 'function') {
console && console.error && console.error('the second argument fn is requird as function');
return this;
}
type = type.toLowerCase();
if (!this._events[type]) {
this._events[type] = [];
}
this._events[type].push(scope ? [fn, scope] : [fn]);
return this;
}
}
하나의 이벤트 가 여러 번 연결 되 어 있 기 때문에 실행 할 때 순서대로 실 행 됩 니 다.모든 이벤트 형식의 처리 함수 저장 소 는 배열 을 사용 합 니 다.이벤트 트리거
이벤트 트리거 의 기본 기능 은 사용자 가 연 결 된 이 벤트 를 실행 하 는 것 입 니 다.따라서 이벤트 트리거 시 지정 한 실행 함수 가 있 는 지 확인 하고 있 으 면 호출 하면 됩 니 다.
또한 이벤트 트리거 는 실제 적 으로 사용자 가 지정 한 처리 함수 가 실행 되 는 과정 이 고 많은 맞 춤 형 작업 을 할 수 있 는 것 도 사용자 가 지정 한 이벤트 처리 함수 에서 이 루어 지기 때문에 이 함수 만 실행 하 는 것 으로 는 부족 합 니 다.또한 현재 함수 에 필요 한 정 보 를 제공 해 야 합 니 다.예 를 들 어 클릭 이벤트 에 현재 클릭 된 요소 가 있 고 키보드 이벤트 에 현재 키 의 키 코드 가 있 으 며 업로드 시작 과 업로드 완료 에 현재 파일 이 있 는 정 보 를 제공 해 야 합 니 다.
따라서 이벤트 가 실 행 될 때 이벤트 처리 함수 의 실제 인삼 에는 현재 이벤트 의 기본 정보 가 포함 되 어야 합 니 다.
그 밖 에 사용자 가 이벤트 처리 함수 에서 의 작업 을 통 해 다음 정 보 를 조정 해 야 할 수도 있 습 니 다.예 를 들 어 keydwon 이벤트 에서 사용 자 는 이 키 의 입력 을 금지 할 수 있 습 니 다.파일 이 업로드 되 기 전에 사용 자 는 이벤트 에서 이 파일 의 업 로드 를 취소 하거나 파일 정 보 를 수정 할 수 있 습 니 다.따라서 이벤트 트리거 함 수 는 사용자 가 수정 한 이벤트 대상 으로 돌아 가 야 합 니 다.
나의 실현 은 다음 과 같다.
{
/**
*
*
* @param {String} type
* @param {Object} data ,
* event = {
//
type: type,
// ,
origin: this,
// this
scope :this/scope
// fire
}
* @returns
*/
fire: function (type, data) {
type = type.toLowerCase();
var eventArr = this._events[type];
var fn,
// event = {
// //
// type: type,
// //
// origin: this,
// // scope this ,
// //
// data: data,
// //
// cancel: false
// };
//
event = $.extend({
//
type: type,
//
origin: this,
// scope this ,
//
// data: data,
//
cancel: false
}, data);
if (!eventArr) {
return event;
}
for (var i = 0, l = eventArr.length; i < l; ++i) {
fn = eventArr[i][0];
event.scope = eventArr[i][1] || this;
fn.call(event.scope, event);
}
return event;
}
}
위 에서 이 루어 진 이벤트 처리 함수 의 실제 인삼 에는 다음 과 같은 정보 가 포함 되 어 있 습 니 다.Object.assign(target, ...sources)
은 ES6 의 한 방법 으로 모든 속성 값 을 하나 이상 의 소스 대상 에서 목표 대상 으로 복사 하고 목표 대상 으로 되 돌아 가 는 역할 을 합 니 다.잘 알려 진$.extend(target,..sources)
방법 과 유사 합 니 다.이벤트 취소
이벤트 취소 에 필요 한 것 은 이미 연 결 된 이벤트 처리 함 수 를 제거 하면 됩 니 다.
다음 과 같이 구현:
{
/**
*
*
* @param {String} type
* @param {Function} fn ,
* @returns
*/
off: function (type, fn) {
type = type.toLowerCase();
var eventArr = this._events[type];
if (!eventArr || !eventArr.length) return this;
if (!fn) {
this._events[type] = eventArr = [];
} else {
for (var i = 0; i < eventArr.length; ++i) {
if (fn === eventArr[i][0]) {
eventArr.splice(i, 1);
// 1、 break
// , !
--i;
}
}
}
return this;
}
}
이 곳 은 원생 과 유사 한 이벤트 의 귀속 취 소 를 실현 합 니 다.이벤트 처리 함 수 를 지정 하면 지정 한 이벤트 의 지정 처리 함 수 를 제거 하고 이벤트 처리 함 수 를 생략 하면 현재 이벤트 형식의 모든 이벤트 처리 함 수 를 제거 합 니 다.단 한 번 의 이벤트
jQuery 에는 하나의 원 방법 이 있 습 니 다.바 인 딩 된 이 벤트 는 한 번 만 실 행 됩 니 다.이 방법 은 특정한 상황 에서 매우 유용 합 니 다.사용자 가 수 동 으로 바 인 딩 을 취소 할 필요 가 없습니다.
이곳 의 실현 도 매우 간단 합 니 다.이 사건 을 촉발 할 때 만 귀속 을 취소 하면 됩 니 다.
다음 과 같이 구현:
{
/**
*
*
* @param {String} type
* @param {Function} fn
* @param {Object} scope
* @returns
*/
one: function (type, fn, scope) {
var that = this;
function nfn() {
//
that.off(type, nfn);
//
fn.apply(scope || that, arguments);
}
this.on(type, nfn, scope);
return this;
}
}
원 리 는 사용자 가 지정 한 함 수 를 직접 연결 하지 않 고 새로운 함 수 를 만 들 고 바 인 딩 하 는 것 입 니 다.이 함수 가 실 행 될 때 바 인 딩 을 취소 하고 사용자 가 지정 한 처리 함 수 를 실행 합 니 다.기본 모형
여기까지 완전한 이벤트 메커니즘 이 완성 되 었 습 니 다.전체 코드 는 다음 과 같 습 니 다.
function CustomEvent() {
this._events = {};
}
CustomEvent.prototype = {
constructor: CustomEvent,
/**
*
*
* @param {String} type
* @param {Function} fn
* @param {Object} scope
* @returns
*/
on: function (type, fn, scope) {
if (type + '' !== type) {
console && console.error && console.error('the first argument type is requird as string');
return this;
}
if (typeof fn != 'function') {
console && console.error && console.error('the second argument fn is requird as function');
return this;
}
type = type.toLowerCase();
if (!this._events[type]) {
this._events[type] = [];
}
this._events[type].push(scope ? [fn, scope] : [fn]);
return this;
},
/**
*
*
* @param {String} type
* @param {Anything} data ,
* event = {
//
type: type,
// ,
origin: this,
// this
scope :this/scope
// fire
}
* @returns
*/
fire: function (type, data) {
type = type.toLowerCase();
var eventArr = this._events[type];
var fn, scope,
event = Object.assign({
//
type: type,
//
origin: this,
// scope this ,
//
cancel: false
}, data);
if (!eventArr) return event;
for (var i = 0, l = eventArr.length; i < l; ++i) {
fn = eventArr[i][0];
scope = eventArr[i][1];
if (scope) {
event.scope = scope;
fn.call(scope, event);
} else {
event.scope = this;
fn(event);
}
}
return event;
},
/**
*
*
* @param {String} type
* @param {Function} fn ,
* @returns
*/
off: function (type, fn) {
type = type.toLowerCase();
var eventArr = this._events[type];
if (!eventArr || !eventArr.length) return this;
if (!fn) {
this._events[type] = eventArr = [];
} else {
for (var i = 0; i < eventArr.length; ++i) {
if (fn === eventArr[i][0]) {
eventArr.splice(i, 1);
// 1、 break
// , !
--i;
}
}
}
return this;
},
/**
*
*
* @param {String} type
* @param {Function} fn
* @param {Object} scope
* @returns
*/
one: function (type, fn, scope) {
var that = this;
function nfn() {
//
that.off(type, nfn);
//
fn.apply(scope || that, arguments);
}
this.on(type, nfn, scope);
return this;
}
};
자신의 컨트롤 에 사용 하기위 에 서 는 이미 사건 체 제 를 실현 하 였 는데,우 리 는 어떻게 자신의 사건 에서 사용 합 니까?
예 를 들 어 제 가 달력 컨트롤 을 썼 는데 이벤트 메커니즘 을 사용 해 야 합 니 다.
function Calendar() {
//
this._event = {};
//
}
Calendar.prototype = {
constructor:Calendar,
on:function () {},
off:function () {},
fire:function () {},
one:function () {},
// 。。。
}
상기 위조 코드 는 컨트롤 을 on,off,fire,one 등 방법 으로 계승 하면 된다 는 뜻 이다.하지만 사건 의 저장 대상 을 확보 해 야 합 니 다이 벤트 는 인 스 턴 스 를 직접 불 러 와 야 합 니 다.이 점 은 계승 할 때 자바 스 크 립 트 에서 계승 을 실현 하 는 방안 이 너무 많 습 니 다.위 에 달력 컨트롤 Calendar 에 이벤트 메커니즘 을 추가 하면 Calendar 에서 사용 할 수 있 습 니 다.
달력 개발 시 달력 의 셀 렌 더 링 을 할 때 cellRender 이 벤트 를 촉발 합 니 다.
//
var renderEvent = this.fire('cellRender', {
//
date: date.format('YYYY-MM-DD'),
// iso
isoWeekday: day,
// dom
el: this.el,
//
tdEl: td,
//
dateText: text.innerText,
// class
dateCls: text.className,
// html
extraHtml: '',
isHeader: false
});
이벤트 에서 저 희 는 현재 렌 더 링 된 날짜,텍스트 class 등 정 보 를 사용자 에 게 제공 합 니 다.그러면 사용 자 는 이 사건 을 연결 하고 이 사건 에서 자신의 개성 아 화 처 리 를 할 수 있 습 니 다.렌 더 링 을 할 때 주말 이면'가짜'표 지 를 삽입 하고 날 짜 를 빨간색 으로 표시 합 니 다.
var calendar = new Calendar();
calendar.on('cellRender', function (e) {
if(e.isoWeekday > 5 ) {
e.extraHtml = '<span> </span>';
e.dateCls += ' red';
}
});
컨트롤 에서 이벤트 체 제 를 사용 하면 개발 을 간소화 하고 절 차 를 통제 하기 쉬 우 며 실제 사용 할 때 매우 풍부 한 맞 춤 형 조작 을 제공 할 수 있 으 니 빨리 사용 하 세 요.총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Thymeleaf 의 일반 양식 제출 과 AJAX 제출텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.