Mint-ui 프레임워크 Popup 및 Datetime Picker 구성 요소 스크롤 관통 문제 해결
현상 환원
공식 주소
핸드폰 스캔으로 데모를 보고 두 개의 구성 요소인 Popup 구성 요소와 Datetime의 예를 보여 줍니다.
문제의 원인
HTML5 터치 이벤트 touchmove 이벤트: 손가락이 화면에서 미끄러질 때 연속적으로 터치
따라서 구성 요소 Popup 구성 요소와 Datetime Picker의 팝업 레이어를 활성화할 때, 우리가 탄층에서 내용을 선택할 때 위아래로 연속적으로 미끄러지면 이 이벤트를 촉발합니다
사고방식을 해결하다
팝업층이 나타나면 바디를 막는 터치무브 이벤트, 팝업층이 사라지면 저지 이벤트를 제거합니다.
mint-ui 구성 요소 라이브러리 사용 해결 방법
Popup 구성 요소
//공식 사례
<mt-popup
v-model="popupVisible"
position="bottom">
...
</mt-popup>
//해결 방식, popupVisible 변수를 감청함으로써 탄창이 나타난 후 bode 노드 touchMove 이벤트를 금지하고, 탄창이 사라진 후 body 노드를 복구하는 touchMove 이벤트
const handler = function(e) {
e.preventDefault();
}
// vue
watch: {
popupVisible: function (val) {
if(val) {
document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
} else {
document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
}
}
}
Datetime Picker//공식 사례
<mt-datetime-picker
ref="picker"
type="time"
v-model="pickerValue">
</mt-datetime-picker>
//해결 방법: 이 구성 요소는 비교적 구덩이입니다. Datetime Picker가 탄창 표시와 숨겨진 귀속 변수를 제공하지 않았기 때문에 우리는 popup을 해결하는 방식으로 문제를 해결하지 않았습니다. 이벤트를 열고 이벤트를 확인하며 이벤트를 취소하고 몽환된 탄창을 클릭하여 사라지는 몇 가지 시간만 해결할 수 있습니다.정부에서 제시한 속성 방법은 이벤트 확인, 이벤트 열기만 지원합니다.사건을 취소하는 리셋 함수를 명문으로 제시하지 않았고, 몽타주 창을 클릭하여 사건을 사라지는 것도 지원하지 않아 구덩이였다.
<mt-datetime-picker
ref="picker"
type="time"
v-model="pickerValue"
@confirm="confirm">
</mt-datetime-picker>
const handler = function(e) {
e.preventDefault();
}
//vue 인스턴스 내
methods: {
openPicker() { //
document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
this.$refs.picker.open();
},
confirm() { //
document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
}
}
이 때 리셋 취소와 몽타주 클릭 이벤트가 하나 부족합니다. 그리고 원본 코드를 보면 사실 mint-ui 원본 코드는 리셋 취소 이벤트를 지원합니다. 또한 놀랍게도 2.0 버전 이후의mint-ui가 Datetime picker 구성 요소에visible-change 이벤트와close OnClick Modal 속성(전송문)을 추가했지만 공식 문서는 여전히 이러한 속성을 업데이트하지 않았습니다.지금 상술한 문제를 잘 해결하였다.그리고visible-change 사건이 생기면 상술한 사고방식대로 해결하지 않아도 된다.어셈블리 섹션 소스는 다음과 같습니다.
props: {
...,
closeOnClickModal: {
type: Boolean,
default: true
}
},
watch: {
...,
visible(val) {
this.$emit('visible-change', val);
}
},
...
<span class="mint-datetime-action mint-datetime-cancel" @click="visible = false;$emit('cancel')">{{ cancelText }}</span>
직접visible-change 방법으로 해결합니다.
<mt-datetime-picker
ref="picker"
type="time"
v-model="pickerValue"
@confirm="confirm"
@visible-change=""handleValueChange>
</mt-datetime-picker>
const handler = function(e) {
e.preventDefault();
}
// vue
methods: {
handleValueChange: function (val) {
if(val) {
document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
} else {
document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
}
}
}
위의 방법은 프로젝트가 부딪힌 구덩이를 해결할 수 있지만, 모든 페이지에 구성 요소인 Popup 구성 요소와 Datetime Picker를 사용하려면 이 코드를 추가해야 합니다. 페이지에 여러 개의 Popup 구성 요소가 존재하면 여러 개의 변수를 감청해야 합니다.더 좋은 해결 방식(상술한 방식은 인터넷에서도 유사한 해결 방식이 있고visible-change 방안을 스스로 보충했다)
프로젝트에서 위와 같이 해결하는 것은 너무 번거롭기 때문에 비교적 좋은 해결 방안을 생각했다. 탄층의 출현과 사라짐은 구성 요소의 업데이트를 촉발하기 때문에 전체 국면에 지령 v-roll을 등록하고 지령의componentUpdated 갈고리를 활용하여 이 기능을 실현할 수 있다고 생각했다.코드는 다음과 같습니다.
//
const handler = (e) => {
e.preventDefault();
};
Vue.directive('roll', {
componentUpdated(el, binding) {
if (binding.value) {
document.getElementsByTagName('body')[0].addEventListener('touchmove', handler, { passive: false });
} else {
document.getElementsByTagName('body')[0].removeEventListener('touchmove', handler, { passive: false });
}
}
});
이렇게 되면 많은 코드를 간소화하고 다른 개발자들은 사용할 때 대응하는 구성 요소에 v-roll 명령을 추가하면 된다.
// popup
<mt-popup
v-model="popupVisible"
v-roll:visible=popupVisible>
...
</mt-popup>
// mt-datetime-picker
<mt-datetime-picker
ref="datePicker"
v-model="date"
@visible-change="handleVisibleChange"
v-roll:visible=pVisible
...>
</mt-datetime-picker>
...
data: {
pVisible: false
},
methods: {
handleVisibleChange (isVisible) {
this.pVisible = isVisible;
}
}
이어 같은 보기 페이지에 여러 개의 구성 요소 Popup 구성 요소와 Datetime Picker가 명령을 사용할 때 집단적으로 명령을 터치하는 구덩이가 있습니다.그래서 서로 덮어씁니다. 예를 들어 A탄층을 열어 페이지touchMove 이벤트를 막지만 다른 popuu 구성 요소도 갈고리 함수를 터치하고 TouchMove 이벤트를 막아서 효과가 없습니다.componentUpdated: 명령어가 있는 구성 요소의 VNode와 하위 VNode를 모두 업데이트한 후 호출합니다.//현재 자신의 이해는 탄층이 나타나고 사라지면서 보이는 인터페이스 노드가 업데이트되었기 때문에 다른 노드가 v-roll 명령을 연결한 갈고리도 촉발되었다
해결 방안: 한 보기에 여러 개의 구성 요소 Popup 구성 요소와 Datetime Picker를 사용하는 명령어 입력 그룹 형식
//
const handler = (e) => {
e.preventDefault();
};
Vue.directive('roll', {
componentUpdated(el, binding) {
if (binding.value instanceof Array) {
const visible = binding.value.some(e => e); // true, touchmove
if (visible) {
document.getElementsByTagName('body')[0].addEventListener('touchmove', handler, { passive: false });
} else {
document.getElementsByTagName('body')[0].removeEventListener('touchmove', handler, { passive: false });
}
} else if (typeof binding.value === 'boolean') {
if (binding.value) {
document.getElementsByTagName('body')[0].addEventListener('touchmove', handler, { passive: false });
} else {
document.getElementsByTagName('body')[0].removeEventListener('touchmove', handler, { passive: false });
}
}
}
});
// popup
<mt-popup
v-model="popupVisible"
v-roll:visible=[popupVisible, pVisible]>
...
</mt-popup>
// mt-datetime-picker
<mt-datetime-picker
ref="datePicker"
v-model="date"
@visible-change="handleVisibleChange"
v-roll:visible=[popupVisible, pVisible]
...>
</mt-datetime-picker>
...
data: {
pVisible: false
},
methods: {
handleVisibleChange (isVisible) {
this.pVisible = isVisible;
}
}
현재mint-ui는 아직 이 문제를 복구하지 않았기 때문에 당분간 상술한 방안을 사용하여 해결합니다.처음에는 원본 코드를 바꾸려고 했지만, 비현실적이었다. 왜냐하면 나중에mint-ui 버전을 업데이트해야 할 수도 있기 때문이다.여러분도 위와 같은 해결 방식에 구덩이가 있는지 확인해 주실 수 있습니다.추가 정보: vue에서 mint-ui의 날짜 플러그인을 사용할 때 ios에서 스크롤 관통 문제가 발생합니다
문제:ios에서 날짜를 선택하면 위아래로 미끄러질 때 전체 페이지가 스크롤됩니다. 안드로이드는 정상입니다.
해결 방법은 날짜 팝업 층이 나타날 때 페이지의 기본 스크롤 메커니즘을 금지하고, 날짜 팝업 층이 사라질 때 금지 페이지의 기본 스크롤 메커니즘을 해제하는 것이다
1. 날짜 구성 요소 호출
<div class="datePicker" style="z-index: 9999">
<mt-datetime-picker
type="date"
ref="picker"
v-model="nowTime"
year-format="{value} "
month-format="{value} "
date-format="{value} "
@confirm="handleConfirm"
:startDate="startDate"
:endDate="endDate"
>
</mt-datetime-picker>
</div>
2. 감청 함수 설정
data () {
return {
birthday:"", //
startDate: new Date('1952'),
endDate:new Date(),
nowTime:'1992-09-15',
/*--------- --------------*/
handler:function(e){e.preventDefault();}
}
},
methods:{
/* iphone */
closeTouch:function(){
document.getElementsByTagName("body")[0].addEventListener('touchmove',
this.handler,{passive:false});//
console.log("closeTouch haved happened.");
},
openTouch:function(){
document.getElementsByTagName("body")[0].removeEventListener('touchmove',
this.handler,{passive:false});//
console.log("openTouch haved happened.");
},
}
그리고 감청, 탄창이 사라질 때 상응하는 방법을 사용한다
//
watch:{
signReasonVisible:function(newvs,oldvs){//picker ,
if(newvs){
this.closeTouch();
}else{
this.openTouch();
}
}
},
다음은datetime-picker의 처리입니다. (openPicker1은 선택기를 여는 이벤트를 터치하기 위해handleConfirm(data)는 선택한 날짜의 리셋 함수입니다)
openPicker () {
this.$refs.picker.open();
this.closeTouch();//
},
handleConfirm (data) {
let date = moment(data).format('YYYY-MM-DD')
this.birthday = date;
this.openTouch();//
},
그리고 이 문제를 해결했어!이상에서 Mint-ui 프레임워크 팝업과 Datetime Picker 구성 요소가 스크롤되어 관통하는 문제를 해결한 것은 바로 편집자가 여러분에게 공유한 모든 내용입니다. 참고 부탁드리고 저희도 많이 사랑해 주세요.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
팝 업 팝 업 상자 에 데이터 추가 방법창 P1 에 데 이 터 를 표시 하고 추가 단 추 를 제공 합 니 다. 단 추 를 누 르 면 새 브 라 우 저 창 P2 가 팝 업 됩 니 다.데 이 터 를 추가 하고 제출 하면 창 P2 가 자동 으로 닫 힙 니 다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.