/**
* @파일 dom.js
* @모듈 돔
*/
'글로벌/문서'에서 문서 가져오기;
'글로벌/창'에서 창 가져오기;
'../fullscreen-api'에서 fs 가져오기;
'./log.js'에서 로그 가져오기;
'./obj'에서 {isObject} 가져오기;
import computedStyle from './computed-style';
* './browser'에서 브라우저로 가져오기;
/**
* 값이 공백이 아닌 문자가 포함된 문자열인지 감지합니다.
*
* @사적인
* @param {문자열} 문자열
* 확인할 문자열
*
* @return {부울}
* 문자열이 비어 있지 않으면 `true`, 그렇지 않으면 `false`입니다.
*
*/
함수 isNonBlankString(str) {
// str.trim을 사용하여 공백 문자를 제거합니다.
// 공백이 아닌 문자의 앞이나 뒤에서. 일명
// 공백이 아닌 문자를 포함하는 모든 문자열은
// 여전히 `trim` 이후에 포함되지만 공백만 문자열입니다.
// 길이가 0이 되어 이 검사에 실패합니다.
반환 typeof str === '문자열' && 부울(str.trim());
}
/**
* 전달된 문자열에 공백이 있으면 오류가 발생합니다. 이것은 다음에 의해 사용됩니다
* classList API와 상대적으로 일치하는 클래스 메소드.
*
* @사적인
* @param {문자열} 문자열
* 공백을 확인할 문자열입니다.
*
* @throws {오류}
* 문자열에 공백이 있으면 오류가 발생합니다.
*/
함수 throwIfWhitespace(str) {
// str.indexOf가 성능 측면에서 더 빠르기 때문에 regex 대신 str.indexOf를 사용합니다.
if (str.indexOf(' ') > = 0) {
throw new Error('클래스에 잘못된 공백 문자가 있습니다.');
}
}
/**
* 요소 className 내에서 className을 일치시키기 위한 정규식을 생성합니다.
*
* @사적인
* @param {문자열} 클래스 이름
* RegExp를 생성할 className입니다.
*
* @return {정규 표현식}
* 요소에서 특정 `className`을 확인할 RegExp
* 클래스명.
*/
함수 classRegExp(클래스 이름) {
return new RegExp('(^|\\s)' + className + '($|\\s)');
}
/**
* 현재 DOM 인터페이스가 실제처럼 보이는지 여부(즉, 시뮬레이션되지 않음).
*
* @return {부울}
* DOM이 진짜로 보이면 `true`, 그렇지 않으면 `false`가 됩니다.
*/
내보내기 기능 isReal() {
// 문서와 창 모두 `global` 덕분에 정의되지 않습니다.
반환 문서 === window.document;
}
/**
* 덕 타이핑을 통해 값이 DOM 요소인지 여부를 결정합니다.
*
* @param {혼합} 값
* 확인할 값입니다.
*
* @return {부울}
* 값이 DOM 요소이면 `true`, 그렇지 않으면 `false`입니다.
*/
내보내기 함수 isEl(value) {
isObject(값) 반환 && 값.노드타입 === 1;
}
/**
* 현재 DOM이 iframe에 포함되어 있는지 확인합니다.
*
* @return {부울}
* DOM이 iframe에 포함된 경우 `true`, `false`
* 그렇지 않으면.
*/
내보내기 기능 isInFrame() {
// 시도할 때 Safari에서 오류가 발생하므로 여기에서 try/catch가 필요합니다.
// `parent` 또는 `self`를 가져오기 위해
{
return window.parent !== window.self;
} 잡기 (x) {
true를 반환합니다.
}
}
/**
* 주어진 메서드를 사용하여 DOM을 쿼리하는 함수를 만듭니다.
*
* @사적인
* @param {문자열} 메서드
* 쿼리를 만드는 방법입니다.
*
* @return {함수}
* 쿼리 방식
*/
함수 createQuery(메서드) {
반환 함수(선택자, 컨텍스트) {
if (!isNonBlankString(선택자)) {
return 문서[방법](null);
}
if (isNonBlankString(context)) {
컨텍스트 = document.querySelector(컨텍스트);
}
const ctx = isEl(컨텍스트) ? 컨텍스트: 문서;
ctx[메서드] 반환 && ctx[방법](선택자);
};
}
/**
* 요소를 생성하고 속성, 속성을 적용하고 내용을 삽입합니다.
*
* @param {string} [tagName='div']
* 생성할 태그의 이름.
*
* @param {객체} [속성={}]
* 적용할 요소 속성.
*
* @param {객체} [속성={}]
* 적용할 요소 속성.
*
* @param {module:dom~ContentDescriptor} 콘텐츠
* 콘텐츠 설명자 개체입니다.
*
* @return {요소}
* 생성된 요소입니다.
*/
내보내기 기능 createEl(tagName = 'div', 속성 = {}, 속성 = {}, 콘텐츠) {
const el = document.createElement(태그 이름);
Object.getOwnPropertyNames(properties).forEach(function(propName) {
const val = 속성[propName];
// #2176 참조
// 우리는 원래 속성과 속성을 모두 허용했습니다.
// 같은 객체이지만 잘 작동하지 않습니다.
if (propName.indexOf('aria-') !== -1 || propName === '역할' || propName === '유형') {
log.warn('createEl()의 두 번째 인수에 속성 설정\n' +
'가 폐기되었습니다. 대신 세 번째 인수를 사용하세요.\n' +
`createEl(유형, 속성, 속성). ${propName}을(를) ${val}(으)로 설정하려고 합니다.`);
el.setAttribute(propName, val);
// textContent는 모든 곳에서 지원되지 않으므로 처리합니다.
// 방법입니다.
} 그렇지 않으면 (propName === 'textContent') {
textContent(el, val);
} else if (el[propName] !== val || propName === 'tabIndex') {
el[propName] = 값;
}
});
Object.getOwnPropertyNames(attributes).forEach(function(attrName) {
el.setAttribute(attrName, 속성[attrName]);
});
if (내용) {
appendContent(엘, 콘텐츠);
}
반환 엘;
}
/**
* 요소에 텍스트를 삽입하여 기존 내용을 완전히 바꿉니다.
*
* @param {요소} 엘
* 텍스트 콘텐츠를 추가할 요소
*
* @param {문자열} 텍스트
* 추가할 텍스트 내용입니다.
*
* @return {요소}
* 텍스트 콘텐츠가 추가된 요소입니다.
*/
내보내기 기능 textContent(el, text) {
if (typeof el.textContent === '정의되지 않음') {
el.innerText = 텍스트;
} else {
el.textContent = 텍스트;
}
반환 엘;
}
/**
* 요소를 다른 요소의 첫 번째 자식 노드로 삽입
*
* @param {요소} 자식
* 삽입할 요소
*
* @param {요소} 부모
* 자식을 삽입할 요소
*/
내보내기 기능 prependTo(자식, 부모) {
경우 (부모.첫 번째 자식) {
parent.insertBefore(자식, 부모.firstChild);
} else {
parent.appendChild(자식);
}
}
/**
* 요소에 클래스 이름이 있는지 확인하십시오.
*
* @param {요소} 요소
* 확인할 요소
*
* @param {string} classToCheck
* 확인할 클래스 이름
*
* @return {부울}
* 요소에 클래스가 있으면 `true`, 그렇지 않으면 `false`가 됩니다.
*
* @throws {오류}
* `classToCheck`에 공백이 있으면 오류가 발생합니다.
*/
내보내기 기능 hasClass(요소, classToCheck) {
throwIfWhitespace(classToCheck);
if (요소.클래스리스트) {
return element.classList.contains(classToCheck);
}
return classRegExp(classToCheck).test(element.className);
}
/**
* 요소에 클래스 이름을 추가합니다.
*
* @param {요소} 요소
* 클래스 이름을 추가할 요소.
*
* @param {문자열} classToAdd
* 추가할 클래스 이름.
*
* @return {요소}
* 클래스 이름이 추가된 DOM 요소.
*/
내보내기 기능 addClass(요소, classToAdd) {
if (요소.클래스리스트) {
element.classList.add(classToAdd);
// `hasElClass`가 수행하므로 여기서 `throwIfWhitespace`를 수행할 필요가 없습니다.
// classList가 지원되지 않는 경우.
} 그렇지 않으면 (!hasClass(요소, classToAdd)) {
element.className = (element.className + ' ' + classToAdd).trim();
}
반환 요소;
}
/**
* 요소에서 클래스 이름을 제거합니다.
*
* @param {요소} 요소
* 클래스 이름을 제거할 요소.
*
* @param {string} classToRemove
* 제거할 클래스 이름
*
* @return {요소}
* 클래스 이름이 제거된 DOM 요소.
*/
내보내기 기능 removeClass(요소, classToRemove) {
// 플레이어가 처리되는 경우 보호
경우 (! 요소) {
log.warn("removeClass가 존재하지 않는 요소로 호출되었습니다.");
null을 반환합니다.
}
if (요소.클래스리스트) {
element.classList.remove(classToRemove);
} else {
throwIfWhitespace(classToRemove);
element.className = element.className.split(/\s+/).filter(function(c) {
c 반환 !== classToRemove;
}).가입하다(' ');
}
반환 요소;
}
/**
* toggleClass에 대한 콜백 정의입니다.
*
* @callback 모듈:dom~PredicateCallback
* @param {요소} 요소
* 컴포넌트의 DOM 요소.
*
* @param {문자열} classToToggle
* 토글하려는 `className`
*
* @return {부울|정의되지 않음}
* `true`가 반환되면 `classToToggle`이
* `요소`. `false`인 경우 `classToToggle`이 다음에서 제거됩니다.
* '요소'. `undefined`인 경우 콜백이 무시됩니다.
*/
/**
* 옵션에 따라 요소에 클래스 이름을 추가하거나 요소에서 제거합니다.
* 조건 또는 클래스 이름의 유무.
*
* @param {요소} 요소
* 클래스 이름을 켜는 요소입니다.
*
* @param {문자열} 클래스투토글
* 토글되어야 하는 클래스.
*
* @param {부울|모듈:dom~PredicateCallback} [술어]
* {@link module:dom~PredicateCallback}에 대한 반환 값 참조
*
* @return {요소}
* 토글된 클래스가 있는 요소.
*/
내보내기 기능 toggleClass(요소, classToToggle, 술어) {
// 이것은 IE11이 지원하지 않기 때문에 내부적으로 `classList`를 사용할 수 없습니다.
// `classList.toggle()` 메서드의 두 번째 매개변수! 어떤 것이 좋기 때문에
// 'classList'는 추가/제거 기능에서 사용됩니다.
const has = hasClass(element, classToToggle);
if (술어 유형 === '함수') {
술어 = 술어(요소, classToToggle);
}
if (술어 유형 !== '부울') {
술어 = !has;
}
// 필요한 클래스 연산이 클래스의 현재 상태와 일치하는 경우
// 요소, 조치가 필요하지 않습니다.
if (술어 ===가) {
반품;
}
if (술어) {
addClass(요소, classToggle);
} else {
removeClass(요소, classToggle);
}
반환 요소;
}
/**
* HTML 요소에 속성을 적용합니다.
*
* @param {요소} 엘
* 속성을 추가할 요소.
*
* @param {객체} [속성]
* 적용할 속성입니다.
*/
내보내기 기능 setAttributes(el, 속성) {
Object.getOwnPropertyNames(attributes).forEach(function(attrName) {
const attrValue = 속성[attrName];
if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) {
el.removeAttribute(attrName);
} else {
el.setAttribute(attrName, (attrValue === true ? '' : attrValue));
}
});
}
/**
* HTML 태그에 정의된 대로 요소의 속성 값을 가져옵니다.
*
* 속성은 속성과 동일하지 않습니다. 태그에 정의되어 있습니다.
* 또는 setAttribute 사용.
*
* @param {요소} 태그
* 태그 속성을 가져올 요소.
*
* @return {객체}
* 요소의 모든 속성. 부울 속성은 'true'이거나
* `false`, 나머지는 문자열입니다.
*/
내보내기 기능 getAttributes(태그) {
const 개체 = {};
// 알려진 부울 속성
// 일치하는 부울 속성을 확인할 수 있지만 모든 브라우저가 그런 것은 아닙니다.
// 모든 태그가 이러한 속성에 대해 아는 것은 아니므로 여전히 수동으로 확인해야 합니다.
const knownBooleans = ',' + 'autoplay,controls,playsinline,loop,muted,default,defaultMuted' + ',';
만약 (태그 && 태그.속성 && 태그.속성.길이 > 0) {
const attrs = tag.attributes;
for (let i = attrs.length - 1; i > = 0; 나--) {
const attrName = attrs[i].name;
let attrVal = attrs[i].value;
// 알려진 부울을 확인합니다.
// 일치하는 요소 속성은 typeof에 대한 값을 반환합니다.
if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) {
// 포함된 부울 속성의 값은 일반적으로 비어 있습니다.
// 문자열('')은 거짓 값만 확인하면 거짓이 됩니다.
// 또한 autoplay='false'와 같은 잘못된 코드를 지원하는 것을 원하지 않습니다.
attrVal = (attrVal !== null) ? 허위 사실;
}
obj[attrName] = attrVal;
}
}
객체 반환;
}
/**
* 요소의 속성 값을 가져옵니다.
*
* @param {요소} 엘
* DOM 요소.
*
* @param {문자열} 속성
* 값을 가져올 속성입니다.
*
* @return {문자열}
* 속성 값입니다.
*/
내보내기 기능 getAttribute(el, attribute) {
return el.getAttribute(속성);
}
/**
* 요소의 속성 값을 설정합니다.
*
* @param {요소} 엘
* DOM 요소.
*
* @param {문자열} 속성
* 설정할 속성.
*
* @param {문자열} 값
* 속성을 설정할 값.
*/
내보내기 기능 setAttribute(el, 속성, 값) {
el.setAttribute(속성, 값);
}
/**
* 요소의 속성을 제거합니다.
*
* @param {요소} 엘
* DOM 요소.
*
* @param {문자열} 속성
* 제거할 속성입니다.
*/
내보내기 기능 removeAttribute(el, attribute) {
el.removeAttribute(속성);
}
/**
* 텍스트를 선택하는 기능을 차단하려고 시도합니다.
*/
수출 기능 blockTextSelection() {
document.body.focus();
document.onselectstart = 함수() {
거짓을 반환합니다.
};
}
/**
* 텍스트 선택 차단을 끕니다.
*/
내보내기 기능 unblockTextSelection() {
document.onselectstart = 함수() {
true를 반환합니다.
};
}
/**
* 기본 `getBoundingClientRect` 함수와 동일하지만 다음을 보장합니다.
* 이 방법은 전혀 지원되지 않습니다(지원한다고 주장하는 모든 브라우저에 있음)
* 계속하기 전에 해당 요소가 DOM에 있는지 확인합니다.
*
* 이 래퍼 함수는 일부에서 제공하지 않는 속성도 shim합니다.
* 이전 브라우저(즉, IE8).
*
* 또한 일부 브라우저는 속성 추가를 지원하지 않습니다.
* `ClientRect`/`DOMRect` 개체; 그래서 우리는 그것을 표준으로 얕게 복사합니다.
* 속성(널리 지원되지 않는 `x` 및 `y` 제외). 도움이 됩니다.
* 키를 열거할 수 없는 구현을 피하십시오.
*
* @param {요소} 엘
* `ClientRect`를 계산하려는 요소.
*
* @return {객체|정의되지 않음}
* 항상 일반 객체를 반환하거나 그렇지 않은 경우 `정의되지 않음`을 반환합니다.
*/
내보내기 기능 getBoundingClientRect(el) {
만약 (엘 && el.getBoundingClientRect && el.parentNode) {
const rect = el.getBoundingClientRect();
const 결과 = {};
['하단', '높이', '왼쪽', '오른쪽', '상단', '너비'].forEach(k => {
if (rect[k] !== 정의되지 않음) {
결과[k] = rect[k];
}
});
if (!결과.높이) {
result.height = parseFloat(computedStyle(el, '높이'));
}
if (!결과.폭) {
result.width = parseFloat(computedStyle(el, 'width'));
}
반환 결과;
}
}
/**
* 페이지에서 DOM 요소의 위치를 나타냅니다.
*
* @typedef {객체} 모듈:dom~Position
*
* @property {숫자} 남음
* 왼쪽 픽셀.
*
* @property {숫자} 상단
* 상단부터 픽셀.
*/
/**
* DOM에서 요소의 위치를 가져옵니다.
*
* John Resig의 `getBoundingClientRect` 기법을 사용합니다.
*
* @see http://ejohn.org/blog/getboundingclientrect-is-awesome/
*
* @param {요소} 엘
* 오프셋을 가져올 요소.
*
* @return {module:dom~Position}
* 전달된 요소의 위치입니다.
*/
내보내기 기능 findPosition(el) {
if (!엘 || (엘 && !el.offsetParent)) {
반환 {
왼쪽: 0,
맨 위: 0,
폭: 0,
높이: 0
};
}
const 너비 = el.offsetWidth;
const 높이 = el.offsetHeight;
왼쪽으로 = 0;
상단 = 0;
동안 (el.offsetParent && 엘 !== 문서[fs.fullscreenElement]) {
왼쪽 += el.offsetLeft;
상단 += el.offsetTop;
el = el.offsetParent;
}
반환 {
왼쪽,
맨 위,
너비,
신장
};
}
/**
* DOM 요소 또는 마우스 포인터의 x 및 y 좌표를 나타냅니다.
*
* @typedef {객체} 모듈:dom~Coordinates
*
* @property {숫자} x
* x 좌표(픽셀 단위)
*
* @property {번호} y
* 픽셀 단위의 y 좌표
*/
/**
* 요소 내에서 포인터 위치를 가져옵니다.
*
* 좌표의 기준은 요소의 왼쪽 하단입니다.
*
* @param {요소} 엘
* 포인터 위치를 가져올 요소.
*
* @param {EventTarget~Event} 이벤트
* 이벤트 객체.
*
* @return {module:dom~Coordinates}
* 마우스 위치에 해당하는 좌표 객체.
*
*/
내보내기 기능 getPointerPosition(el, event) {
번역된 const = {
엑스: 0,
와이: 0
};
경우 (브라우저.IS_IOS) {
let item = 엘;
동안 (항목 && item.nodeName.toLowerCase() !== 'html') {
const transform = computedStyle(item, 'transform');
if (/^matrix/.test(transform)) {
const values = transform.slice(7, -1).split(/,\s/).map(Number);
translate.x += values[4];
translate.y += values[5];
} 그렇지 않으면 (/^matrix3d/.test(변환)) {
const values = transform.slice(9, -1).split(/,\s/).map(Number);
translate.x += values[12];
translate.y += values[13];
}
item = item.parentNode;
}
}
상수 위치 = {};
const boxTarget = findPosition(event.target);
const box = findPosition(el);
const boxW = box.width;
const boxH = 상자 높이;
let offsetY = event.offsetY - (box.top - boxTarget.top);
let offsetX = event.offsetX - (box.left - boxTarget.left);
if (event.changedTouches) {
offsetX = event.changedTouches[0].pageX - box.left;
offsetY = event.changedTouches[0].pageY + box.top;
경우 (브라우저.IS_IOS) {
offsetX -= translate.x;
offsetY -= translate.y;
}
}
position.y = (1 - Math.max(0, Math.min(1, offsetY / boxH)));
position.x = Math.max(0, Math.min(1, offsetX / boxW));
반환 위치;
}
/**
* 덕 타이핑을 통해 값이 텍스트 노드인지 여부를 결정합니다.
*
* @param {혼합} 값
* 이 값이 텍스트 노드인지 확인하십시오.
*
* @return {부울}
* 값이 텍스트 노드이면 `true`, 그렇지 않으면 `false`입니다.
*/
내보내기 기능 isTextNode(value) {
isObject(값) 반환 && 값.노드타입 === 3;
}
/**
* 요소의 내용을 비웁니다.
*
* @param {요소} 엘
* 자식을 비울 요소
*
* @return {요소}
* 자식이 없는 요소
*/
내보내기 기능 emptyEl(el) {
동안 (el.firstChild) {
el.removeChild(el.firstChild);
}
반환 엘;
}
/**
* DOM에 삽입할 내용을 기술하는 혼합된 값입니다.
* 어떤 방법을 통해. 다음과 같은 유형일 수 있습니다.
*
* 유형 | 설명
* -----------|-------------
* `문자열` | 값은 텍스트 노드로 정규화됩니다.
* `요소` | 값은 있는 그대로 수락됩니다.
* `텍스트노드` | 값은 있는 그대로 수락됩니다.
* `배열` | 문자열, 요소, 텍스트 노드 또는 함수의 1차원 배열입니다. 이러한 함수는 문자열, 요소 또는 텍스트 노드를 반환해야 합니다(배열과 같은 다른 반환 값은 무시됨).
* `함수` | 문자열, 요소, 텍스트 노드 또는 배열(위에 설명된 다른 가능한 값)을 반환할 것으로 예상되는 함수입니다. 즉, 콘텐츠 설명자는 함수 배열을 반환하는 함수일 수 있지만 이러한 두 번째 수준 함수는 문자열, 요소 또는 텍스트 노드를 반환해야 합니다.
*
* @typedef {string|요소|TextNode|배열|함수} module:dom~ContentDescriptor
*/
/**
* 최종적으로 DOM에 삽입하기 위해 콘텐츠를 정규화합니다.
*
* 이것은 광범위한 콘텐츠 정의 방법을 허용하지만 보호하는 데 도움이 됩니다.
* 단순히 `innerHTML`에 작성하는 함정에 빠지지 않도록 합니다.
* XSS 문제가 되십시오.
*
* 요소의 내용은 여러 유형으로 전달될 수 있으며
* 조합의 동작은 다음과 같습니다.
*
* @param {module:dom~ContentDescriptor} 콘텐츠
* 콘텐츠 설명자 값입니다.
*
* @return {배열}
* 전달된 모든 콘텐츠는 다음의 배열로 정규화됩니다.
* 요소 또는 텍스트 노드.
*/
내보내기 기능 normalizeContent(content) {
// 먼저 콘텐츠가 함수인 경우 호출합니다. 배열을 생성하는 경우,
// 정규화 전에 발생해야 합니다.
if (콘텐츠 유형 === '함수') {
내용 = 내용();
}
// 다음으로 배열로 정규화하여 하나 이상의 항목을 정규화할 수 있습니다.
// 필터링되어 반환됩니다.
return (Array.isArray(내용) ? 내용 : [내용]).map(값 => {
// 먼저 새로운 값을 생성하는 함수라면 value를 호출하고,
// 이후에 어떤 종류의 노드로 정규화됩니다.
if (값 유형 === '함수') {
값 = 값();
}
if (isEl(값) || isTextNode(값)) {
반환 값;
}
if (값 유형 === '문자열' && (/\S/).테스트(값)) {
return document.createTextNode(값);
}
}).필터(값 => 값);
}
/**
* 콘텐츠를 정규화하고 요소에 추가합니다.
*
* @param {요소} 엘
* 정규화된 콘텐츠를 추가할 요소.
*
* @param {module:dom~ContentDescriptor} 콘텐츠
* 콘텐츠 설명자 값입니다.
*
* @return {요소}
* 정규화된 콘텐츠가 추가된 요소입니다.
*/
내보내기 기능 appendContent(el, content) {
normalizeContent(콘텐츠).forEach(노드 => el.appendChild(노드));
반환 엘;
}
/**
* 콘텐츠를 정규화하고 요소에 삽입합니다. 이것은 동일하다
* `appendContent()`, 요소를 먼저 비운다는 점만 제외.
*
* @param {요소} 엘
* 정규화된 콘텐츠를 삽입할 요소입니다.
*
* @param {module:dom~ContentDescriptor} 콘텐츠
* 콘텐츠 설명자 값입니다.
*
* @return {요소}
* 정규화된 콘텐츠가 삽입된 요소입니다.
*/
내보내기 기능 insertContent(el, content) {
return appendContent(emptyEl(el), content);
}
/**
* 이벤트가 단일 왼쪽 클릭인지 확인하십시오.
*
* @param {EventTarget~Event} 이벤트
* 이벤트 객체.
*
* @return {부울}
* 왼쪽 클릭이 한 번이면 'true', 그렇지 않으면 'false'가 됩니다.
*/
내보내기 기능 isSingleLeftClick(event) {
// 참고: 드래그할 수 있는 항목을 만드는 경우
// `mousedown` 및 `mousemove` 이벤트 모두에서 호출합니다.
// 그렇지 않으면 'mousedown'이 버튼에 충분해야 합니다.
if (event.button === 정의되지 않음 && event.buttons === 정의되지 않음) {
// `버튼`이 필요한 이유는 무엇입니까?
// 가운데 마우스에는 때때로 다음이 있기 때문입니다.
// e.버튼 === 0 및 e.버튼 === 4
// 또한 조합 클릭을 방지하고 싶습니다.
// 가운데 마우스를 누른 상태에서 왼쪽 클릭하면
// e.버튼 === 0, e.버튼 === 5
// `버튼`은 작동하지 않습니다.
// 좋습니다. 그러면 이 블록은 무엇을 합니까?
// 크롬 `simulate mobile devices`용입니다.
// 이것도 지원하고 싶습니다.
true를 반환합니다.
}
if (이벤트 버튼 === 0 && event.buttons === 정의되지 않음) {
// 터치 스크린, 때로는 일부 특정 장치에서 `버튼`
// 아무것도 없음(iOS의 사파리, 블랙베리...)
true를 반환합니다.
}
// 단일 왼쪽 클릭에 대한 `mouseup` 이벤트는
// `버튼` 및 `버튼` = 0
if (event.type === 'mouseup' && 이벤트 버튼 === 0 &&
이벤트 버튼 === 0) {
true를 반환합니다.
}
if (이벤트.버튼 !== 0 || 이벤트.버튼 !== 1) {
// 이것이 위의 if else 블록이 있는 이유입니다.
// 특수한 경우 잡아서 미끄러지게 할 수 있습니다.
// 위의 작업을 수행합니다. 여기에 도달하면 확실히
// is-not-left-click
거짓을 반환합니다.
}
true를 반환합니다.
}
/**
* 선택 항목 내에서 `selector`와 일치하는 단일 DOM 요소를 찾습니다.
* 다른 DOM 요소의 `context`(기본값은 `document`).
*
* @param {문자열} 선택자
* `querySelector`에 전달되는 유효한 CSS 선택기.
*
* @param {요소|문자열} [컨텍스트=문서]
* 조회할 DOM 요소. 셀렉터로도 가능
* 문자열 이 경우 첫 번째로 일치하는 요소가 사용됩니다.
* 문맥으로. 누락된 경우(또는 선택기와 일치하는 요소가 없는 경우)
* `문서`로 돌아가기.
*
* @return {요소|null}
* 찾은 요소 또는 null입니다.
*/
export const $ = createQuerie('querySelector');
/**
* 선택 항목 내에서 `selector`와 일치하는 모든 DOM 요소를 찾습니다.
* 다른 DOM 요소의 `context`(기본값은 `document`).
*
* @param {문자열} 선택자
* `querySelectorAll`에 전달되는 유효한 CSS 선택기.
*
* @param {요소|문자열} [컨텍스트=문서]
* 조회할 DOM 요소. 셀렉터로도 가능
* 문자열 이 경우 첫 번째로 일치하는 요소가 사용됩니다.
* 문맥으로. 누락된 경우(또는 선택기와 일치하는 요소가 없는 경우)
* `문서`로 돌아가기.
*
* @return {노드리스트}
* 찾은 요소의 요소 목록입니다. 없는 경우 비어 있음
* 발견되었습니다.
*
*/
export const $$ = createQuerie('querySelectorAll');