Contextmenu is not triggered on iOS13 - how to fix

Post Reply
User avatar
stararound
Posts: 27
Joined: Wed Apr 17, 2019 1:29 pm

Contextmenu is not triggered on iOS13 - how to fix

Post by stararound »

Tầm tháng 9/2019 trên github có log một issue về việc xử lý nhấp chuột phải (Context menu) trên trang web duyệt trên safari của iPhone, iPad mới cập nhật iOS13 mới, ở link sau: https://github.com/Leaflet/Leaflet/issues/6817

Cụ thể là sau bản cập nhật mới nhất cho iOS 13, iPad không thể Chạm và Giữ để truy cập menu ngữ cảnh nhấp chuột phải (Context menu).
Vấn đề này chỉ xuất hiện trong trình duyệt Safari trên thiết bị iPhone, iPad có iOS 13.

Ví dụ javascript thông thường sau đây mô tả sử dụng contextmenu trên một phần tử html:

Code: Select all

var el = document.createElement('td');

el.oncontextmenu = function(e) {
	alert("right click");
};
Cách xử lý contextmenu trên cssscript.com

Cách xử lý của một số bác trên đó là add thêm event long-press, tham khảo link: https://www.cssscript.com/handle-long-p ... -press-js/

Code: Select all

//import thư viện long-press.js vào html
<script src="dist/long-press.min.js"></script>

var el = document.getElementById('demo');
// gắn xử lý long press cho element 
el.addEventListener('long-press', function(e) {
  // do something
});
Cách xử lý của tác giả John Doherty trên github

Hoặc, dùng thư viện long-press-event.min.js được hướng dẫn ở github của tác giả John Doherty: https://github.com/john-doherty/long-press-event

Add long-press-event.min.js vào trang web và bắt sự kiện long-press:

Code: Select all

// the event bubbles, so you can listen at the root level
document.addEventListener('long-press', function(e) {
  console.log(e.target);
});


// grab the element
var el = document.getElementById('idOfElement');

// listen for the long-press event
el.addEventListener('long-press', function(e) {

  // stop the event from bubbling up
  e.preventDefault()

  console.log(e.target);
});
Cách xử lý của tôi - đơn giản - chuối - dễ hiểu
  1. Xác định lần chạm đầu tiên ở time nào (lấy timestamp: new Date().getTime()/1000)
  2. Xác định time khi kết thúc chạm (lấy timestamp tương tự trên)
  3. Xác định pressTime = time kết thúc chạm - time lần chạm đầu tiên
  4. Nếu pressTime > 0.3 thì quyết định Chạm và Giữ đủ lâu để phát sinh nhấp chuột phải
Đoạn code xử lý như sau:

Code: Select all

var touchStartClientX, touchStartClientY;
var touchStartTime = 0;
var pressTime = 0;

var tdElt = document.createElement('td');

tdElt.addEventListener("touchstart", function (event) {
	if ((!window.navigator.msPointerEnabled && event.touches.length > 1) ||
		event.targetTouches.length > 1) {
		return; // Ignore if touching with more than 1 finger
	}

	touchStartClientX = event.touches[0].clientX;
	touchStartClientY = event.touches[0].clientY;
	
	// Xác định lần chạm đầu tiên ở time nào
	touchStartTime = new Date().getTime()/1000;
	
	event.preventDefault();
});

tdElt.addEventListener("touchend", function (event) {
	if ((!window.navigator.msPointerEnabled && event.touches.length > 0) ||
		event.targetTouches.length > 0) {
		return; // Ignore if still touching with one or more fingers
	}

	var touchEndClientX, touchEndClientY;

	touchEndClientX = event.changedTouches[0].clientX;
	touchEndClientY = event.changedTouches[0].clientY;
	
	// Xác định time khi kết thúc chạm
	// Xác định pressTime = time kết thúc chạm - time lần chạm đầu tiên
	pressTime = new Date().getTime()/1000 - touchStartTime;

	var dx = touchEndClientX - touchStartClientX;
	var absDx = Math.abs(dx);

	var dy = touchEndClientY - touchStartClientY;
	var absDy = Math.abs(dy);

	// Nếu Math.max(absDx, absDy) > 3 nghĩa là touch and move
	if (Math.max(absDx, absDy) > 3) {
		pressTime = 0;
	} else {
		
		// Nếu pressTime > 0.3 thì quyết định Chạm và Giữ đủ lâu để phát sinh nhấp chuột phải
		if (pressTime > 0.3) {
			pressTime = 0;
			alert("Right click");
		} else {
			pressTime = 0;
			alert("Left click");
		}
	}
	
});	
Issue trên tôi tìm thấy khi đang làm chơi game gỡ mìn bằng javascript, html. Tôi đã trình bày các cách xử lý issue và đưa ra cả cách của tôi, tuy chưa hẳn là cách tốt nhất nhưng đã áp dụng được cho game gỡ mìn của tôi: https://nhucvl.com/game/miner

Post Reply