由於Safari存在安全限制,訪問剪貼簿內容時會彈出粘貼氣泡按鈕,影響將用戶端剪貼簿內容同步至雲手機剪貼簿的體驗。本文介紹如何通過Web SDK實現將本地複製的文本粘貼至Safari瀏覽器。
方案概述
在本地用戶端添加剪貼簿按鈕,點擊剪貼簿按鈕,彈出氣泡輸入框。
將用戶端中需要發送至雲手機的內容輸入至氣泡輸入框。
點擊氣泡輸入框中的立即粘貼按鈕,將內容同步至雲手機的剪貼簿和輸入框。
實現步驟
雲手機參數配置
配置
readClipboardDataByUser開啟,無需SDK自行讀取剪貼簿。配置
useCustomIme開啟本地IME,將內容同步到雲機輸入框需要開啟本地IME。
//是否是Safari
function isSafari() {
return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
}
//主控配置 禁止SDK自行讀取剪貼簿和開啟本地IME
connConfig = {..., readClipboardDataByUser:isSafari(), useCustomIme:true};
var appInfo = {
...,
connConfig: connConfig,
...
};
var sessionParam = {
...,
appInfo: appInfo,
....
};
var wuyingSdk = Wuying.WebSDK;
session = wuyingSdk.createSession('appstream', sessionParam);
//縮圖配置 開啟本地IME
this.thumbnail = new window.Wuying.ThumbnailSDK({
...,
connectionConfig: {
useCustomIme: true,
},
},
{
onConnected: (data) => {
this.thumbnail.session.getLocalConfig().setClipboardEnabled(true);
},
onDisConnected: (data) => {},
onThumbnailData: (url) => {},
}
);構建氣泡輸入框
在用戶端構建剪貼簿按鈕,並通過點擊按鈕喚出支援與剪貼簿互動的對話方塊。可參考如下代碼:
function showInput() {
showCustomDialog();
// 點擊遮罩層關閉彈框
document.querySelector('.modal-overlay').addEventListener('click', function (e) {
if (e.target === this) {
closeModal();
}
});
// ESC鍵關閉彈框
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') {
closeModal();
}
});
}
function closeModal() {
console.log('closeModal');
const overlay = document.querySelector('.modal-overlay');
if (overlay) {
overlay.style.display = 'none';
overlay.remove();
}
}
function submitContent() {
const content = document.querySelector('.input-field').value.trim();
if (!content) {
alert('請輸入內容');
return;
}
//同步內容到雲機
sendMsgToCloudPhoneOperation(content);
closeModal();
}
function showCustomDialog() {
// 建立模態框背景
const overlay = document.createElement('div');
overlay.className = 'modal-overlay';
// Ensure the modal captures all events and is displayed at the highest level
overlay.style.pointerEvents = 'all';
overlay.style.zIndex = '9999';
// Prevent events from propagating to underlying layers
const stopPropagation = function(e) {
e.stopPropagation();
};
overlay.addEventListener('contextmenu', stopPropagation, true);
// Add event listeners to intercept all keyboard events
overlay.addEventListener('keydown', stopPropagation, true);
overlay.addEventListener('keyup', stopPropagation, true);
overlay.addEventListener('keypress', stopPropagation, true);
overlay.innerHTML = `
<div class="modal">
<div class="modal-header">
<h2 class="modal-title">剪貼簿</h2>
<button class="close-btn" onclick="closeModal()">×</button>
</div>
<div class="input-container">
<textarea
class="input-field"
placeholder="請輸入內容"
maxlength="500"
></textarea>
</div>
<button class="submit-btn" onclick="submitContent()">
立即粘貼
</button>
</div>
`;
document.body.appendChild(overlay);
// Focus the textarea when the modal opens to ensure keyboard events are captured
setTimeout(() => {
const textarea = overlay.querySelector('.input-field');
if (textarea) {
textarea.focus();
}
}, 100);
}將複製的文本發送至雲手機
觸發同步任務
function submitContent() {
const content = document.querySelector('.input-field').value.trim();
if (!content) {
alert('請輸入內容');
return;
}
//同步內容到雲機
sendMsgToCloudPhoneOperation(content);
closeModal();
}將內容同步至雲手機
function sendMsgToCloudPhoneOperation(msg) {
//主控
if (session) {
session.setClipboardModule('sendClipboardDataToRemote', msg)
}
//縮圖
for (const [key, value] of thumbnailSDKMap) {
console.log('thumbnial sendMsgToCloudPhoneOperation ', key, msg);
value.thumbnail.session.getClipboardModule().sendClipboardDataToRemote(msg);
}
}注意事項
新建立的對話方塊需要完全接管鍵盤事件,避免鍵盤事件被其他案頭元素接管,否則普通按鍵資訊無法在對話方塊中正確響應。配置參考如下:
overlay.addEventListener('contextmenu', stopPropagation, true);
// Add event listeners to intercept all keyboard events
overlay.addEventListener('keydown', stopPropagation, true);
overlay.addEventListener('keyup', stopPropagation, true);
overlay.addEventListener('keypress', stopPropagation, true);