iOS14.5以降で二重サブミット防止が機能しない

事象

二重サブミット防止を行いたいリンクがあり、押下時にpointer-events:noneのスタイルを付与することで実現しようとしています。
挙動について確認したところ、iOS14.5よりも前のバージョンではうまく機能したのですが、iOS14.5以上だとpointer-events:noneになっているにも関わらずリンクが何回も押下できてしまいます。
AngularというよりiOS側の問題のような気はするのですが、原因にお心あたりがある方いらっしゃいましたらご意見いただければと存じます。

詳細

以下のように事象が発生するリンクと発生しないリンクがあります。
また、iOS14.5.0より前のバージョンではいずれも事象が発生しませんでした。

リンク1:事象が発生するリンク
クリック時にpointer-events:noneの適用とクリック回数のカウントアップが行われるが、押下する度にカウントアップできてしまう。(pointer-events:noneが効いていない)

<div class="m-block-app">
    <a href="javascript:void(0);" (click)="click1()" [ngStyle]="styles1" class="m-btn-grad">
        <span class="e-inr">リンク1</span>
    </a>
</div>

リンク2:事象が発生しないリンク
リンク1との違いはspanタグの個数のみ

<div class="m-block-app">
    <a href="javascript:void(0);" (click)="click2()" [ngStyle]="styles2" class="m-btn-grad">
        <span class="e-inr"><span>リンク2</span></span>
    </a>
</div>

リンク3:事象が発生しないリンク
リンク1との違いはspanタグに対するclass指定の有無のみ

<div class="m-block-app">
    <a href="javascript:void(0);" (click)="click3()" [ngStyle]="styles3" class="m-btn-grad">
        <span>リンク3</span>
    </a>
</div>

ソースコード

再現手順

  • ソースコードのdistフォルダ配下にあるビルド後資材をApache等で起動
  • iOS14.5.0以上のiPhone実機またはXcodeのエミュレータのSafariでアプリ画面を表示
  • リンク1を連打する

環境情報

Angular:12.2.0
iOS:14.5.1
※14.5.0より前のバージョンでは発生せず。

pointer-eventsの振る舞いが変わるのは奇妙で原因はわからないですが、そもそも二重サブミットの防止としてpointer-eventsだけで防ごうとするのは不十分かと思います。

pointer-events: noneはその要素自体でポインターイベントを発生させなくなりますが、子孫要素が明示的に別の値を持っていれば親の指定は無視できます。

onClickのハンドラーですでに実行中でないかを確認したり、いったん onClick$ Subjectにキューイングしてdebounceなどで流れを制御したり、つまりCSSではなくJavaScript側での防御をベースにして、CSSは補助的に考えたほうがいいかと思います。

lacolacoさん
ご意見ありがとうございます。
js側での制御について大変参考になりました。
ありがとうございます。

本件についてですが、以下iOS14.5以上で発生するバグということで整理がつきました。
ご参考まで。
https://bugs.webkit.org/show_bug.cgi?id=225561

「いいね!」 1