JS 학습 20 (고급 기술)
46593 단어 관찰자 모드불활성 불 러 오기함수 절 류왜곡 방지 대상
함 수 는 본질 적 으로 매우 간단 하고 과정 적 이지 만 JS 의 타고 난 동적 특성 때문에 사용 방식 이 매우 복잡 할 수 있다.
안전 한 유형 검사
JS 에 서 는 유형 검 측 이 있 지만 브 라 우 저 구현 등 으로 신뢰 할 수 없습니다.예 를 들 어 type: of 는 Safari 에서 정규 표현 식 에 대해 서도 function 을 되 돌려 줍 니 다.instanceof 는 여러 개의 전역 작용 역 이 존재 할 때 도 같은 종류의 서로 다른 작용 역 에서 함 수 를 구성 하 는 실례 를 서로 다른 실례 로 식별한다.
var isArray = value instanceof Array;
이 표현 식 이 true 로 돌아 가 려 면 value 는 배열 이 어야 하고 Array 구조 함수 와 같은 전역 역할 영역 에 있어 야 합 니 다. value 가 다른 전역 역할 영역 에서 정의 하 는 배열 이 라면 이 표현 식 은 false 로 돌아 갑 니 다.어떤 대상 이 원생 인지 개발 자가 정의 한 대상 인지 검사 할 때 도 문제 가 있 을 수 있다.브 라 우 저가 원래 JSON 을 지원 하기 시 작 했 기 때문에 일부 개발 자 들 은 제3자 라 이브 러 리 로 JSON 을 실현 하고 있 습 니 다. 이 라 이브 러 리 에는 전체적인 JSON 대상 이 있 을 것 입 니 다. 이렇게 해서 JSON 대상 이 원래 의 것 인지 아 닌 지 확인 하려 면 번 거 로 울 것 입 니 다.이 문 제 를 해결 하 는 방법 은 Object 의 toString 방법 을 사용 하 는 것 입 니 다. 이 방법 은 [object Native Constructor Name] 형식의 문자열 을 되 돌려 줍 니 다.
function isArray(value){
return Object.prototype.toString.call(value) == "[object Array]";
}
function isFunction(value){
return Object.prototype.toString.call(value) == "[object Function]";
}
function isRegExp(value){
return Object.prototype.toString.call(value) == "[object RegExp]";
}
그러나 주의해 야 할 것 은 IE 에서 COM 형식 으로 이 루어 진 모든 함수 에 대해 isFunction () 은 false 로 되 돌아 갑 니 다.JSON 이 원생 인지 에 대한 질문 은 다음 과 같다.
var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON) == "[object JSON]";
역할 영역 안전 구조 함수
전에 우리 가 말 한 구조 함 수 는 이렇게 사용 되 었 다.
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
}
var person = new Person("Nicholas", 29, "Software Engineer");
여기 서 new 연산 자 를 사 용 했 기 때문에 this 는 새로 만 든 Person 대상 에 연결 되 어 있 습 니 다. new 연산 자 를 사용 하지 않 고 Person () 을 직접 호출 하면 this 는 window 에 연결 되 어 있 습 니 다. 이것 은 분명 안 됩 니 다.
function Person(name, age, job){
if (this instanceof Person){
this.name = name;
this.age = age;
this.job = job;
} else {
return new Person(name, age, job);
}
}
var person1 = Person("Nicholas", 29, "Software Engineer");
alert(window.name); //""
alert(person1.name); //"Nicholas"
var person2 = new Person("Shelby", 34, "Ergonomist");
alert(person2.name); //"Shelby"
그러나 이러한 역할 영역 안전 한 구조 함 수 를 사용 한 후에 구조 함 수 를 바탕 으로 훔 친 계승 을 사용 하면 문제 가 생 길 수 있다.
function Polygon(sides){
if (this instanceof Polygon) {
this.sides = sides;
this.getArea = function(){
return 0;
};
} else {
return new Polygon(sides);
}
}
function Rectangle(width, height){
// , this Rectangle , side
Polygon.call(this, 2);
this.width = width;
this.height = height;
this.getArea = function(){
return this.width * this.height;
};
}
var rect = new Rectangle(5, 10);
alert(rect.sides); //undefined
해결 방법 은 Rectangle 도 Polygon 의 인 스 턴 스 였 으 면 좋 겠 어 요.
Rectangle.prototype = new Polygon();
var rect = new Rectangle(5, 10);
alert(rect.sides); //2
불활성 불 러 오기 함수
브 라 우 저의 차이 로 인해 브 라 우 저의 능력 을 판단 하 는 함수 가 대량으로 사용 되 어야 합 니 다. 그러나 이러한 판단 은 일반적으로 매번 실행 할 필요 가 없습니다. 한 번 실행 한 후에 브 라 우 저의 능력 이 확정 되 고 앞 으로 는 판단 하지 않 아 도 됩 니 다.예 를 들 면:
function createXHR(){
if (typeof XMLHttpRequest != "undefined"){
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined"){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"],
i,len;
for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex){
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR object available.");
}
}
XHR 대상 을 만 드 는 함수 입 니 다. 대상 을 만 들 때마다 브 라 우 저 능력 을 판단 하 는 것 은 불필요 합 니 다.타성 불 러 오 는 방법 은 두 가지 가 있 습 니 다. 첫 번 째 는 함수 가 처음 호출 되 었 을 때 상황 에 따라 서로 다른 새로운 함수 로 이 함 수 를 덮어 쓰 는 것 입 니 다. 나중에 호출 하면 더 이상 판단 하지 않 고 이 실행 하 는 작업 을 직접 수행 하 는 것 입 니 다.
function createXHR(){
if (typeof XMLHttpRequest != "undefined"){
createXHR = function(){
return new XMLHttpRequest();
};
} else if (typeof ActiveXObject != "undefined"){
createXHR = function(){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"],
i, len;
for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex){
//skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
};
} else {
createXHR = function(){
throw new Error("No XHR object available.");
};
}
return createXHR();
}
createXHR();
alert(createXHR);
두 번 째 사고방식 은 똑 같 습 니 다. 함 수 를 설명 할 때 새 함 수 를 지정 할 뿐 첫 번 째 호출 할 때 지정 하지 않 습 니 다.두 가지 방법 은 사실 본질 적 으로 같은 것 이 니, 네가 어떻게 쓰 려 고 하 는 지 봐 라.
var createXHR = (function(){
if (typeof XMLHttpRequest != "undefined"){
return function(){
return new XMLHttpRequest();
};
} else if (typeof ActiveXObject != "undefined"){
return function(){
if (typeof arguments.callee.activeXString != "string"){
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"],
i, len;
for (i=0,len=versions.length; i < len; i++){
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex){
//skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
};
} else {
return function(){
throw new Error("No XHR object available.");
};
}
})();
alert(createXHR);
함수 바 인 딩
함수 바 인 딩 이 해결 하 는 문 제 는 함수 호출 시 함수 의 this 대상 이 우리 가 원 하지 않 는 대상 으로 바 뀌 는 문제 입 니 다.이런 상황 은 이벤트 처리 함 수 를 지정 할 때 자주 나타난다.예 를 들 어:
var handler = {
message: "Event handled",
handleClick: function(event){
alert(this);
alert(this.message);
}
};
var btn = document.getElementById("myButton");
EventUtil.addHandler(btn, "click", handler.handleClick); //[object HTMLButtonElement] undefined
handler.handleClick(); // [object Object] Event handled
이 곳 의 this 는 단추 요소 로 바 뀌 었 습 니 다.해결 방법 은 진정한 함 수 를 하나의 패키지 에 끼 워 서 함수 의 환경 을 보존 하 는 것 이다.
var handler = {
message: "Event handled",
handleClick: function(event){
alert(this); // [object Object]
alert(this.message); // Event handled
} };
var btn = document.getElementById("myButton");
EventUtil.addHandler(btn, "click", function(event){
alert(this); //[object HTMLButtonElement]
handler.handleClick(event);
});
보 실 수 있 습 니 다. 닫 힌 this 는 button 으로 바 뀌 었 습 니 다. 이 닫 힌 보호 로 인해 우리 의 처리 함수 환경 이 저장 되 었 습 니 다.매번 수 동 으로 패 키 지 를 만 들 지 않 기 위해 서 도구 함수 bid 를 만 들 수 있 습 니 다.
function bind(fn, context){
alert(arguments[0]); //fn
return function(){
alert(arguments[0]); //event
return fn.apply(context, arguments);
};
}
이것 은 하나의 함 수 를 apply 를 특정한 환경 에서 호출 하 는 것 입 니 다. arguments 대상 을 주의 하 십시오. 마지막 으로 return 과거의 익명 함수 (패키지 닫 기) 의 arguments 를 사용 해 야 합 니 다. 그러면 사건 이 사건 처리 함수 에 전달 하 는 매개 변 수 는 우리 의 편지 에 들 어 갈 수 있 습 니 다.
var handler = {
message: "Event handled",
handleClick: function(event){
alert(this); // [object Object]
alert(this.message); // Event handled
} };
var btn = document.getElementById("myButton");
EventUtil.addHandler(btn, "click", bind(handler.handleClick, handler));
ES5 에 서 는 모든 함수 에 원생 bind () 방법 을 정의 합 니 다.그냥 쓰 면 돼.
EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler));
특정한 함수 지침 을 값 으로 전달 하 는 동시에 이 함 수 는 특정한 환경 에서 실행 되 어야 하 며 바 인 딩 함수 의 효과 가 나타 납 니 다.
함수 코 리 화
이것 은 하나 이상 의 매개 변 수 를 설정 한 함 수 를 만 드 는 데 사 용 됩 니 다. 하나의 예 로 기본 사상 을 보 세 요.
function add(num1, num2){
return num1 + num2;
}
function curriedAdd(num2){
return add(5, num2);
}
alert(add(2, 3)); //5
alert(curriedAdd(3)); //8
코 리 화 함 수 를 만 드 는 일반적인 방법:
function curry(fn){
var args = Array.prototype.slice.call(arguments, 1);
return function(){
var innerArgs = Array.prototype.slice.call(arguments);
var finalArgs = args.concat(innerArgs);
return fn.apply(null, finalArgs);
};
}
이 함수 의 주요 작업 은 외부 함수 와 내부 함수 의 인 자 를 모두 되 돌아 오 는 함수 에 전달 하 는 것 입 니 다.
function add(a,b) { alert(a); alert(b); alert(a+b); } var curriedAdd = curry(add, 5);
curriedAdd(3); //8
curriedAdd = curry(add, 3);
curriedAdd(5); //8
curriedAdd = curry(add, 5,3);
curriedAdd(); //8
이 를 bind 함수 에 이용 하여 이벤트 처리 함수 에 여러 개의 인 자 를 전달 할 수 있 습 니 다.
function bind(fn, context){
var args = Array.prototype.slice.call(arguments, 2);
return function(){
var innerArgs = Array.prototype.slice.call(arguments);
var finalArgs = args.concat(innerArgs);
return fn.apply(context, finalArgs);
};
}
var handler = {
message: "Event handled",
handleClick: function(name, event){
alert(this.message + ":"+ name + ":"+ event.type);
}
};
var btn = document.getElementById("myButton");
EventUtil.addHandler(btn, "click", bind(handler.handleClick, handler, "myButton"));
여기 서 주의해 야 할 것 은 매개 변수의 순서 입 니 다. 예 를 들 어 여기 name 과 event 가 바 뀌 면 안 됩 니 다.ES5 의 bind 도 코 리 화 되 어 직접 사용 하면 된다.
EventUtil.addHandler(btn, "click", handler.handleClick.bind(handler, "myButton"));
왜곡 방지 대상
JS 공유 의 본질은 임의의 대상 을 임의로 수정 할 수 있 게 한다.이러 면 때때로 매우 불편 하 다.ES5 는 대상 을 설정 하 는 몇 가지 방법 을 추가 했다.일단 대상 을 변경 방지 로 설정 하면 취소 할 수 없습니다.
확장 불가 대상
새로운 속성 과 방법 을 추가 할 수 없습니다
var person = { name: "Nicholas" };
Object.preventExtensions(person);
person.age = 29;
alert(person.age); //undefined
alert(Object.isExtensible(person)); //false
person.name = "hahah";
alert(person.name); //hahah
밀봉 대상
속성 을 추가 하거나 삭제 할 수 없습니다. 기 존 구성원 의 [Configurable] 이 false 로 설정 되 었 습 니 다.
var person = { name: "Nicholas" };
Object.seal(person);
person.age = 29;
alert(person.age); //undefined
delete person.name;
alert(person.name); //"Nicholas"
alert(Object.isExtensible(person)); //false
alert(Object.isSealed(person)); //true
얼 어 붙 은 대상
확장 할 수 없고 밀봉 할 수 없 으 며 대상 데이터 속성의 [Writable] 은 false 로 설 정 됩 니 다.[Set] 이 정의 되 어 있 으 면, 접근 기 속성 은 여전히 쓸 수 있 습 니 다.
var person = { name: "Nicholas" };
Object.freeze(person);
person.age = 29; alert(person.age); //undefined
delete person.name; alert(person.name); //"Nicholas"
person.name = "Greg"; alert(person.name); //"Nicholas"
alert(Object.isExtensible(person));//false
alert(Object.isSealed(person));//true
alert(Object.isFrozen(person));//true
고급 타이머
setTimeout () 과 setInterval () 은 실 용적 인 기능 이지 만 주의해 야 할 것 이 있 습 니 다.JS 는 단일 라인 으로 타이머 가 사실상 막 힐 가능성 이 높다 는 것 을 의미한다.우리 가 이 두 함수 에서 설정 한 시간 은 코드 를 실행 대기 열 에 추가 하 는 것 을 대표 하 는 이벤트 입 니 다. 만약 에 가입 할 때 마침 JS 가 비어 있 으 면 이 코드 는 바로 실 행 됩 니 다. 즉, 이 시간 에 제시간에 실 행 됩 니 다.반면 JS 가 비어 있 지 않 거나 대기 열 에 다른 우선 순위 가 높 은 코드 가 있다 면 타이머 가 지연 되 는 것 을 의미 합 니 다.
중복 타이머
setInterval 을 사용 하여 타 이 머 를 만 드 는 목적 은 코드 규칙 을 대기 열 에 삽입 하 는 것 입 니 다.이 방식 의 문 제 는 마지막 코드 가 실행 되 지 않 았 을 때 코드 가 다시 대기 열 에 추 가 될 수 있다 는 점 이다.JS 엔진 은 이 문 제 를 해결 합 니 다. 코드 를 대기 열 에 추가 할 때 대기 열 에 코드 인 스 턴 스 가 있 는 지 확인 합 니 다. 있 으 면 추가 하지 않 습 니 다. 이 는 타이머 코드 가 가입 대기 열 에 있 는 최소 간격 이 정 해진 간격 임 을 확인 합 니 다.그러나 어떤 특수 한 상황 에서 도 두 가지 문제 가 발생 할 수 있 습 니 다. 어떤 간격 은 JS 의 처리 가 건 너 뛰 었 기 때문에 코드 간 의 간격 이 예상 보다 작 습 니 다.그래서 가능 한 한 setTimeout () 시 뮬 레이 션 간격 으로 호출 합 니 다.
setTimeout(function(){
setTimeout(arguments.callee, interval);
}, interval);
Yielding Processes
만약 당신 의 페이지 에서 대량의 순환 처 리 를 하려 고 한다 면, 매번 순환 할 때마다 대량의 시간 을 소모 할 것 이 며, 그러면 사용자 의 조작 을 막 을 것 입 니 다.이때 블록 을 나 누 어 데 이 터 를 처리 하 는 것 이 좋 은 방법 이다.이 예 는 100 ms 마다 배열 요 소 를 취하 여 페이지 에 추가 합 니 다.
function chunk(array, process, context){
setTimeout(function(){
var item = array.shift();
process.call(context, item);
if (array.length > 0){
setTimeout(arguments.callee, 100);
}
}, 100);
}
var data = [12,123,1234,453,436,23,23,5,4123,45,346,5634,2234,345,342];
function printValue(item){
var div = document.getElementById("myDiv");
div.innerHTML += item + "<br>";
}
chunk(data, printValue);
함수 절 류
이것 은 어떤 조작 이 끊임없이 촉발 되 는 것 을 피하 기 위해 서 이다. 예 를 들 어 DOM 조작 과 관련 되 고 대량의 DOM 조작 은 자원 을 매우 소모 한다.함수 절 류 의 기본 사상 은 매번 호출 은 실제 호출 된 setTimeout 작업 을 설정 하 는 것 입 니 다. 호출 할 때마다 현재 setTimeout 을 제거 하고 새로운 것 을 설정 합 니 다.짧 은 시간 안에 대량으로 호출 되면 setTimeout 내 작업 을 수행 하지 않 고 새로운 setTimeout 을 설정 합 니 다.setTimeout 시간 이 될 때 까지 충분 한 시간 을 사용 하지 않 아야 내부 의 진정한 작업 이 실 행 됩 니 다.이것 은 onresize 사건 에 특히 유용 합 니 다.
function throttle(method, context) {
clearTimeout(method.tId);
method.tId= setTimeout(function(){
method.call(context);
}, 100);
}
function reDiv(){
var div = document.getElementById("myDiv");
div.innerHTML += "qqqqqq" + "<br>";
}
window.onresize = function(){
throttle(reDiv);
};
이렇게 하면 창 크기 를 100 ms 조정 하 는 것 을 멈 춘 후에 야 reDiv 작업 을 수행 할 수 있 습 니 다.
사용자 정의 이벤트
사건 과 같은 상호작용 은 바로 관찰자 모델 이다. 이런 모델 은 두 가지 대상 으로 구성 된다. 주체 와 관찰자 이다.주 체 는 사건 을 발표 하고 관찰 자 는 이 사건 들 을 구독 함으로써 이 주 체 를 관찰한다.사용자 정의 이 벤트 를 만 드 는 것 은 실제 적 으로 이 벤트 를 관리 하 는 대상 을 만 들 고 그 안에 각종 이벤트 형식의 처리 함 수 를 저장 합 니 다. 이 벤트 를 촉발 할 때 이벤트 형식 을 제시 하면 이 대상 은 해당 이벤트 처리 프로그램 을 찾 아 실 행 됩 니 다.다음은 이벤트 관리 대상 의 대체 형식 입 니 다.
function EventTarget(){
this.handlers = {};
}
EventTarget.prototype = {
constructor: EventTarget,
addHandler: function(type, handler){
if (typeof this.handlers[type] == "undefined"){
this.handlers[type] = [];
}
this.handlers[type].push(handler);
},
fire: function(event){
if (!event.target){
event.target = this;
}
if (this.handlers[event.type] instanceof Array){
var handlers = this.handlers[event.type];
for (var i=0, len=handlers.length; i < len; i++){
handlers[i](event);
}
}
},
removeHandler: function(type, handler){
if (this.handlers[type] instanceof Array){
var handlers = this.handlers[type];
for (var i=0, len=handlers.length; i < len; i++){
if (handlers[i] === handler){
break;
}
}
handlers.splice(i, 1);
}
}
};
이벤트 처리 프로그램 을 추가 할 때 addHandler 는 이벤트 형식 에 따라 처리 함 수 를 handlers 속성 에 대응 하 는 배열 에 저장 합 니 다 (없 으 면 새로 만 듭 니 다).이 벤트 를 촉발 할 때 fire 를 사용 하여 최소한 type 속성 이 있 는 대상 에 게 전 달 됩 니 다.사용 시 이렇게:
function handleMessage(event){
alert("Message received: " + event.message);
}
var target = new EventTarget();
target.addHandler("message", handleMessage);
target.fire({ type: "message", message: "Hello world!"});
target.removeHandler("message", handleMessage);
target.fire({ type: "message", message: "Hello world!"});
사용자 정의 이 벤트 는 항상 결합 대상 간 의 상호작용 을 해제 하 는 데 사 용 됩 니 다. 이 벤트 를 사용 하면 대상 과 대상 간 의 인용 이 필요 하지 않 고 이벤트 처리 와 이벤트 트리거 를 격 리 시 킵 니 다.
드래그 앤 드 롭
원본 마우스 이벤트 사용 하기
하나의 예 를 만 들 고 모듈 모드 를 사용 하여 드래그 하 는 플러그 인 을 만 들 고 모든 이벤트 처리 프로그램 을 추가 하고 제거 하 는 두 가지 방법 을 되 돌려 줍 니 다.
var DragDrop = function(){
var dragging = null;
var diffX = 0;
var diffY = 0;
function handleEvent(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(event.type){
case "mousedown":
if (target.className.indexOf("draggable") > -1){
dragging = target;
diffX = event.clientX - target.offsetLeft;
diffY = event.clientY - target.offsetTop;
}
break;
case "mousemove":
if (dragging !== null){
dragging.style.left = (event.clientX - diffX) + "px";
dragging.style.top = (event.clientY - diffY) + "px";
}
break;
case "mouseup":
dragging = null;
break;
}
};
return {
enable: function(){
EventUtil.addHandler(document, "mousedown", handleEvent);
EventUtil.addHandler(document, "mousemove", handleEvent);
EventUtil.addHandler(document, "mouseup", handleEvent);
},
disable: function(){
EventUtil.removeHandler(document, "mousedown", handleEvent);
EventUtil.removeHandler(document, "mousemove", handleEvent);
EventUtil.removeHandler(document, "mouseup", handleEvent);
}
}
}();
DragDrop.enable();
이렇게 보면 드래그 의 기능 은 실현 되 었 지만 문제 가 있다.예 를 들 어 이것 은 제 가 쓴 플러그 인 입 니 다. 사용 하 는 사람 이 드래그 를 시작 할 때 뭔 가 를 하려 면 그 는 기 존의 소스 코드 에서 수정 해 야 합 니 다.그 는 실행 할 코드 와 함 수 를 모두 case "mousedown" 에 추가 해 야 한다.만약 이 플러그 인 을 내 가 암호 화 했다 면, 이 시간 에 뭔 가 를 하려 면 더욱 번 거 로 울 것 이다.이런 방법 은 분명히 결코 과학적 이지 않다.이때 사용자 정의 이 벤트 를 사용 하면 이 문 제 를 잘 해결 할 수 있다.
사용자 정의 이벤트 추가
여기에서 dragdrop 변 수 를 새로 정의 합 니 다. 이것 은 EventTarget 형식의 대상 입 니 다. 그 위 에 이벤트 처리 함수 나 트리거 이 벤트 를 추가 할 수 있 습 니 다.드래그 가 시 작 될 때, 과정 이 끝 날 때, 사용자 정의 이벤트 가 발생 합 니 다. 이 노드 에서 무엇 을 하고 싶 은 지 이벤트 처리 함 수 를 직접 추가 하면 됩 니 다.
var DragDrop = function(){
// dragdrop EventTarget ,
var dragdrop = new EventTarget(),
dragging = null,
diffX = 0,
diffY = 0;
function handleEvent(event){
event = EventUtil.getEvent(event);
var target = EventUtil.getTarget(event);
switch(event.type){
case "mousedown":
if (target.className.indexOf("draggable") > -1){
dragging = target;
diffX = event.clientX - target.offsetLeft;
diffY = event.clientY - target.offsetTop;
//
dragdrop.fire({type:"dragstart", target: dragging,
x: event.clientX, y: event.clientY});
}
break;
case "mousemove":
if (dragging !== null){
dragging.style.left = (event.clientX - diffX) + "px";
dragging.style.top = (event.clientY - diffY) + "px";
dragdrop.fire({type:"drag", target: dragging,
x: event.clientX, y: event.clientY});
}
break;
case "mouseup":
dragdrop.fire({type:"dragend", target: dragging,
x: event.clientX, y: event.clientY});
dragging = null;
break;
}
};
dragdrop.enable = function(){
EventUtil.addHandler(document, "mousedown", handleEvent);
EventUtil.addHandler(document, "mousemove", handleEvent);
EventUtil.addHandler(document, "mouseup", handleEvent);
};
dragdrop.disable = function(){
EventUtil.removeHandler(document, "mousedown", handleEvent);
EventUtil.removeHandler(document, "mousemove", handleEvent);
EventUtil.removeHandler(document, "mouseup", handleEvent);
};
return dragdrop;
}();
DragDrop.addHandler("dragstart", function(event){
var status = document.getElementById("myDiv");
status.innerHTML = "Started dragging " + event.target.id;
});
DragDrop.addHandler("drag", function(event){
var status = document.getElementById("myDiv");
status.innerHTML += "<br/> Dragged " + event.target.id + " to (" + event.x +
"," + event.y + ")";
});
DragDrop.addHandler("dragend", function(event){
var status = document.getElementById("myDiv");
status.innerHTML += "<br/> Dropped " + event.target.id + " at (" + event.x +
"," + event.y + ")";
});
DragDrop.enable();
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Java 관찰자 모드 쉽게 파악정의: 객체 간에 일대다 관계가 있을 때 관찰자 모드(Observer Pattern)를 사용합니다.예를 들어 대상이 수정되면 의존 대상을 자동으로 알려준다. 특징: 1. 관찰자와 피관찰자는 추상적인 결합이다. 2. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.