4

i have a button that when is clicked/pressed will trigger a click() on a input type=file and allow the user to upload a file, it works fine on every platform, but sometimes i need to make a request before opening the upload window, when i need to make the request it work on every platform except on Safari/IOS Safarai, in Safari the request is made and i get the response but doesn’t trigger the input click().

Here is my code.

  async handleClickUpload(origin: string) {
    try {
      this._setDocumentType({ origin });
      const { code: documentCode } = this.currentDocument;

      if (this._isDocumentBackVariant(documentCode)) {
        await this._variantBackDocumentHandler();
      }
      this._handleUploadMethod();
    } catch (e) {
      console.error(e);
    }
  }

Here i make the request and set the variation of the document, (it work fine on the Safari)

  async _variantBackDocumentHandler() {
    const { variation } = await this.getSpecificDocument("cnh_rg_frente");

    console.error("Encontrou variação", variation);
    if (!variation) {
      this._setDocumentType({ open: true });
      throw new Error("Variação não encontrada");
    }
    this._setDocumentType({ variation });
  }

On this method i choose if i open the user camera or allow the user to upload files, (working fine on Safari).

  _handleUploadMethod() {
    const { origin = "" } = this.documentType;
    if (origin === "camera") {
      this.cameraController.open = true;
    } else {
      this._uploadInputHandler();
    }
  }

Here i trigger the click of a hidden input, i have consoled the const uploadInput and it get the element (even in safari). On every browser it will trigger the click() and open a window to upload the file, but on Safari nothing happens.

  _uploadInputHandler() {
    const uploadInput: HTMLInputElement | null = document.querySelector("#uploadInput");

    uploadInput?.click();
  }

Here is my input

    <input
      id="uploadInput"
      @change="(event) => $emit('receiveFile', event)"
      type="file"
      style="visibility: hidden"
      accept="application/pdf, image/png, image/jpeg"
    />

Here is my .browserlistrc

defaults
not IE 11
maintained node versions
last 10 ios_saf versions
last 10 safari versions

Here is my babel.config.js

const plugins = () => {
  const defaultPlugins = [
    "@babel/plugin-proposal-optional-chaining",
    "@babel/plugin-proposal-throw-expressions",
    "@babel/plugin-syntax-throw-expressions",
    [
      "@babel/plugin-transform-runtime",
      {
        absoluteRuntime: false,
        corejs: false,
        helpers: true,
        regenerator: true,
        useESModules: false,
      },
    ],
  ];
  // if (process.env.NODE_ENV === "production") {
  //   defaultPlugins.push("transform-remove-console");
  // }
  return defaultPlugins;
};

module.exports = {
  presets: [
    [
      "@vue/cli-plugin-babel/preset",
      {
        polyfills: [
          "es.array.iterator",
          "es.promise",
          "es.object.assign",
          "es.promise.finally",
          "es.symbol",
        ],
      },
    ],
  ],
  plugins: plugins(),
};

And i have the theses two import on my main.ts

import "core-js/stable";
import "regenerator-runtime/runtime";

The method is working fine on every browser, but when i need to make the request before the click() nothing happens on IOS Safari, on others browser it works.

João Vitor
  • 51
  • 1
  • 3

1 Answers1

5

It's a known issue.

Safari, in the name of security, does not register click events on elements with:

  • visibility: hidden;
  • opacity: 0
  • display: none
  • or which are not a "valid click target" - this is a loose concept they keep toying with but, for example, they don't consider an <a> without a href attribute a valid click target. Which means clicks on <a href> work, but on <a> do not. The undefined href adds validity to the click target, by Apple standards.

If you want the user to be able to click on an "invisible" element, don't give that element visibility: hidden. Instead, change its opacity to 0.01.

Side-note: your issue is not Vue related. It can be repro-ed in React, Angular or plain JS. You might want to change the title to "Web not working correctly in Safari IOS".

tao
  • 82,996
  • 16
  • 114
  • 150