/**
* @파일 슬라이더.js
*/
'../component.js'에서 컴포넌트 가져오기;
import * as Dom from '../utils/dom.js';
'../utils/obj'에서 {assign} 가져오기;
'../utils/browser.js'에서 {IS_CHROME} 가져오기;
'../utils/clamp.js'에서 클램프 가져오기;
'키코드'에서 키코드 가져오기;
/**
* 슬라이더의 기본 기능. 수직 또는 수평일 수 있습니다.
* 예를 들어 동영상의 볼륨 막대 또는 검색 막대는 슬라이더입니다.
*
* @extends 컴포넌트
*/
슬라이더 클래스 확장 구성 요소 {
/**
* 이 클래스의 인스턴스 생성
*
* @param {플레이어} 플레이어
* 이 클래스가 연결되어야 하는 `Player`.
*
* @param {객체} [옵션]
* 플레이어 옵션의 키/값 저장소.
*/
생성자(플레이어, 옵션) {
super(플레이어, 옵션);
this.handleMouseDown_ = (e) => this.handleMouseDown(e);
this.handleMouseUp_ = (e) => this.handleMouseUp(e);
this.handleKeyDown_ = (e) => this.handleKeyDown(e);
this.handleClick_ = (e) => this.handleClick(e);
this.handleMouseMove_ = (e) => this.handleMouseMove(e);
this.update_ = (e) => this.update(e);
// Slider 클래스가 찾고 있는 자식과 일치하도록 속성 이름을 bar로 설정합니다.
this.bar = this.getChild(this.options_.barName);
// 슬라이더 종류에 따라 슬라이더에 수평 또는 수직 클래스를 설정합니다.
this.vertical(!!this.options_.vertical);
this.enable();
}
/**
* 현재 이 슬라이더에 컨트롤이 활성화되어 있는지 여부.
*
* @return {부울}
* 컨트롤이 활성화된 경우 true, 그렇지 않은 경우 false
*/
활성화() {
this.enabled_를 반환합니다.
}
/**
* 비활성화된 경우 이 슬라이더에 대한 컨트롤을 활성화합니다.
*/
할 수 있게 하다() {
if (이.활성화()) {
반품;
}
this.on('마우스다운', this.handleMouseDown_);
this.on('터치스타트', this.handleMouseDown_);
this.on('keydown', this.handleKeyDown_);
this.on('클릭', this.handleClick_);
// TODO: 더 이상 사용되지 않음, controlsvisible이 실행되지 않는 것 같습니다.
this.on(this.player_, 'controlsvisible', this.update);
if (이.플레이어 이벤트) {
this.on(this.player_, this.playerEvent, this.update);
}
this.removeClass('비활성화됨');
this.setAttribute('tabindex', 0);
this.enabled_ = 참;
}
/**
* 이 슬라이더에 대한 컨트롤이 활성화된 경우 비활성화
*/
장애를 입히다() {
if (!this.enabled()) {
반품;
}
const doc = this.bar.el_.ownerDocument;
this.off('마우스다운', this.handleMouseDown_);
this.off('터치스타트', this.handleMouseDown_);
this.off('키다운', this.handleKeyDown_);
this.off('클릭', this.handleClick_);
this.off(this.player_, 'controlsvisible', this.update_);
this.off(doc, 'mousemove', this.handleMouseMove_);
this.off(doc, 'mouseup', this.handleMouseUp_);
this.off(doc, 'touchmove', this.handleMouseMove_);
this.off(doc, 'touchend', this.handleMouseUp_);
this.removeAttribute('tabindex');
this.addClass('비활성화됨');
if (이.플레이어 이벤트) {
this.off(this.player_, this.playerEvent, this.update);
}
this.enabled_ = 거짓;
}
/**
* `Slider`의 DOM 요소를 만듭니다.
*
* @param {문자열} 유형
* 생성할 요소의 유형.
*
* @param {객체} [소품={}]
* 개체 형식의 속성 목록입니다.
*
* @param {객체} [속성={}]
* 객체 형태의 속성 목록.
*
* @return {요소}
* 생성되는 요소.
*/
createEl(유형, 소품 = {}, 속성 = {}) {
// 슬라이더 요소 클래스를 모든 하위 클래스에 추가
props.className = props.className + 'vjs-slider';
소품 = 할당({
탭 인덱스: 0
}, 소품);
속성 = 할당({
'역할': '슬라이더',
'아리아-valuenow': 0,
'아리아-valuemin': 0,
'아리아-valuemax': 100,
'탭인덱스': 0
}, 속성);
return super.createEl(유형, 소품, 속성);
}
/**
* `Slider`에서 `mousedown` 또는 `touchstart` 이벤트를 처리합니다.
*
* @param {EventTarget~Event} 이벤트
* 이 기능을 트리거한 `mousedown` 또는 `touchstart` 이벤트
*
* @listens mousedown
* @listens 터치스타트
* @fires 슬라이더#slideractive
*/
handleMouseDown(이벤트) {
const doc = this.bar.el_.ownerDocument;
if (event.type === '마우스다운') {
event.preventDefault();
}
// Chrome에서 touchstart 시 preventDefault()를 호출하지 않습니다.
// 콘솔 경고를 피하기 위해. '터치 액션: 없음' 스타일 사용
// 대신 의도하지 않은 스크롤을 방지합니다.
// https://developers.google.com/web/updates/2017/01/scrolling-intervention
if (event.type === '터치스타트' && !IS_CHROME) {
event.preventDefault();
}
Dom.blockTextSelection();
this.addClass('vjs-sliding');
/**
* 슬라이더가 활성 상태일 때 트리거됨
*
* @event 슬라이더#slideractive
* @type {이벤트대상~이벤트}
*/
this.trigger('slideractive');
this.on(doc, 'mousemove', this.handleMouseMove_);
this.on(doc, 'mouseup', this.handleMouseUp_);
this.on(doc, 'touchmove', this.handleMouseMove_);
this.on(doc, 'touchend', this.handleMouseUp_);
this.handleMouseMove(이벤트, 참);
}
/**
* 이 `Slider`에서 `mousemove`, `touchmove` 및 `mousedown` 이벤트를 처리합니다.
* `mousemove` 및 `touchmove` 이벤트는 동안에만 이 기능을 트리거합니다.
* `마우스다운` 및 `터치스타트`. 이는 {@link Slider#handleMouseDown} 및
* {@link Slider#handleMouseUp}.
*
* @param {EventTarget~Event} 이벤트
* 트리거된 `mousedown`, `mousemove`, `touchstart` 또는 `touchmove` 이벤트
* 이 기능
* @param {boolean} mouseDown `handleMouseMove`가 직접 호출되는 경우 true로 설정되어야 하는 플래그입니다. 이것은 우리가 마우스를 눌렀을 때 발생하지 않아야 하지만 일반 마우스 이동 처리기에서 발생해야 하는 일을 건너뛸 수 있게 해줍니다. 기본값은 false입니다.
*
* @listens mousemove
* @listens 터치무브
*/
handleMouseMove(이벤트) {}
/**
* `Slider`에서 `mouseup` 또는 `touchend` 이벤트를 처리합니다.
*
* @param {EventTarget~Event} 이벤트
* 이 기능을 트리거한 `mouseup` 또는 `touchend` 이벤트.
*
* @listens 터치엔드
* @listens mouseup
* @fires 슬라이더#sliderinactive
*/
handleMouseUp() {
const doc = this.bar.el_.ownerDocument;
Dom.unblockTextSelection();
this.removeClass('vjs-sliding');
/**
* 슬라이더가 더 이상 활성 상태가 아닐 때 트리거됩니다.
*
* @event 슬라이더#sliderinactive
* @type {이벤트대상~이벤트}
*/
this.trigger('sliderinactive');
this.off(doc, 'mousemove', this.handleMouseMove_);
this.off(doc, 'mouseup', this.handleMouseUp_);
this.off(doc, 'touchmove', this.handleMouseMove_);
this.off(doc, 'touchend', this.handleMouseUp_);
this.update();
}
/**
* `슬라이더`의 진행률 표시줄을 업데이트합니다.
*
* @return {숫자}
* 진행률 표시줄이 나타내는 진행률
* 0에서 1까지의 숫자.
*/
업데이트() {
// VolumeBar init에는 팝업 및 업데이트를 위한 setTimeout이 있습니다.
// 실행 스택의 끝까지. 플레이어는 그 전에 파괴됩니다.
// 업데이트하면 오류가 발생합니다.
// 막대가 없으면...
if (!this.el_ || !this.bar) {
반품;
}
// 0과 1 사이에서 클램프 진행
// 아래에서 2로 반올림하므로 소수점 이하 네 자리까지만 반올림합니다.
const 진행 = this.getProgress();
if (진행 === this.progress_) {
진행 상황을 반환합니다.
}
this.progress_ = 진행;
this.requestNamedAnimationFrame('슬라이더#업데이트', () => {
// 새 막대 너비 또는 높이를 설정합니다.
const sizeKey = this.vertical() ? '높이 너비';
// css 값에 대한 백분율로 변환
this.bar.el().style[sizeKey] = (진행률 * 100).toFixed(2) + '%';
});
진행 상황을 반환합니다.
}
/**
* 채워야 하는 막대의 백분율을 가져옵니다.
* 그러나 고정되고 둥글다.
*
* @return {숫자}
* 슬라이더가 채워지는 백분율
*/
getProgress() {
return Number(clamp(this.getPercent(), 0, 1).toFixed(4));
}
/**
* 슬라이더의 거리 계산
*
* @param {EventTarget~Event} 이벤트
* 이 기능을 실행하게 만든 이벤트.
*
* @return {숫자}
* 슬라이더의 현재 위치.
* - 수직 `슬라이더`에 대한 position.x
* - 수평 `슬라이더`에 대한 position.y
*/
계산거리(이벤트) {
const position = Dom.getPointerPosition(this.el_, event);
if (this.vertical()) {
반환 위치.y;
}
반환 position.x;
}
/**
* `Slider`에서 `keydown` 이벤트를 처리합니다. 왼쪽, 오른쪽, 위쪽 및 아래쪽에 대한 시계
* 화살표 키. 이 함수는 슬라이더에 포커스가 있을 때만 호출됩니다. 보다
* {@link Slider#handleFocus} 및 {@link Slider#handleBlur}.
*
* @param {EventTarget~Event} 이벤트
* 이 함수를 실행하게 만든 `keydown` 이벤트.
*
* @listens 키다운
*/
handleKeyDown(이벤트) {
// 왼쪽 및 아래쪽 화살표
if (keycode.isEventKey(event, 'Left') || keycode.isEventKey(event, 'Down')) {
event.preventDefault();
event.stopPropagation();
this.stepBack();
// 위쪽 및 오른쪽 화살표
} 그렇지 않으면 (keycode.isEventKey(event, 'Right') || keycode.isEventKey(event, 'Up')) {
event.preventDefault();
event.stopPropagation();
this.stepForward();
} else {
// 지원되지 않는 키에 대한 keydown 처리를 전달합니다.
super.handleKeyDown(이벤트);
}
}
/**
* 클릭을 방지하는 데 사용되는 슬라이더의 클릭 이벤트에 대한 리스너
* 버블링에서 버튼 메뉴와 같은 부모 요소까지.
*
* @param {객체} 이벤트
* 이 객체를 실행시킨 이벤트
*/
handleClick(이벤트) {
event.stopPropagation();
event.preventDefault();
}
/**
* 슬라이더가 수직에 대해 수평인지 가져오기/설정
*
* @param {부울} [부울]
* - 슬라이더가 수직이면 true,
* - false는 수평입니다.
*
* @return {부울}
* - 슬라이더가 수직인 경우 true이고 점점
* - 슬라이더가 수평이면 false, 점점
*/
수직(부울) {
if (부울 === 정의되지 않음) {
return this.vertical_ || 거짓;
}
this.vertical_ = !!부울;
if (this.vertical_) {
this.addClass('vjs-slider-vertical');
} else {
this.addClass('vjs-slider-horizontal');
}
}
}
Component.registerComponent('슬라이더', 슬라이더);
기본 슬라이더 내보내기;