Как добиться того, чтобы при использовании асинхронного вызова clipboard API в сафари, он считал, что вызов происходит именно по нажатию на кнопку?

Как можно исправить ошибку, возникающую при нажатии на кнопку с задержкой в Safari, в то время как в других браузерах такой проблемы нет? Код для примера доступен по ссылке ниже. Кроме того, при использовании кнопки для вызова API возникает ошибка при любой задержке. Как можно решить эту проблему?
  • 8 февраля 2024 г. 17:49
Ответы на вопрос 1
Вероятно, вы имеете в виду проблему с ограниченными возможностями доступа к API буфера обмена (`Clipboard API`) в Safari, которые срабатывают только в ответ на "живые" события, такие как клик мышью. Это означает, что попытка выполнить асинхронный вызов `navigator.clipboard.writeText()` не будет работать, если он не инициирован прямо из обработчика событий, связанных с пользовательскими действиями (например, нажатием кнопки).

К сожалению, вы не предоставили прямую ссылку на ваш код, поэтому я не могу проанализировать его напрямую. Тем не менее, я могу предложить общий подход к решению:

```javascript
document.querySelector("#myButton").addEventListener("click", async () => {
    // Это событие "живого" действия пользователя

    // Прямой вызов API буфера обмена, без задержек
    try {
        await navigator.clipboard.writeText("Текст для копирования");
        console.log("Текст скопирован");
    } catch (error) {
        console.error("Ошибка при копировании: ", error);
    }
});
```

Вы упомянули задержку. Если вам нужно выполнить асинхронную операцию перед копированием текста в буфер обмена, в Safari это станет проблемой, так как браузер может рассматривать асинхронную операцию как действие, не связанное непосредственно с действием пользователя. В некоторых случаях может помочь использование `setTimeout` с нулевой задержкой, чтобы совместить асинхронную задачу с обработчиком событий, но это не гарантирует работу во всех ситуациях, особенно если задержка значительная или если браузер строго проверяет "живость" события.

```javascript
document.querySelector("#myButton").addEventListener("click", () => {
    // Запланировать асинхронное действие с минимальной задержкой
    setTimeout(async () => {
        try {
            await navigator.clipboard.writeText("Текст для копирования после задержки");
            console.log("Текст скопирован после задержки");
        } catch (error) {
            console.error("Ошибка при копировании после задержки: ", error);
        }
    }, 0);
});
```

Тем не менее, Safari может по-прежнему блокировать такие вызовы, и, с точки зрения безопасности, это понятно, так как API буфера обмена может использоваться злоумышленниками. Если ваш асинхронный вызов должен выполняться с задачей, которая требует значительного времени (например, подгрузка данных с сервера), то лучше предупредить пользователя о необходимости повторного нажатия, чтобы инициировать копирование после завершения асинхронной задачи.

Обратите внимание, что практики и возможности работы с буфером обмена могут меняться с обновлением браузеров. Убедитесь, что вы используете самую последнюю версию Safari и проверьте современные практики и обходные решения, которые могут быть доступны на момент чтения этой информации.
Похожие вопросы