SPで一覧表示からtable内をタップしても詳細に遷移しないようにしたい

SPで一覧表示後にテーブル内のどのデータをタップしても詳細ページに遷移してしまいます。

これをブロックするおとはできないでしょうか?

スマホでは縦横のスクロールするたびに誤タップしやすく。一覧→誤タップ→詳細を繰り返すのが非常に使いづらく。。

理想は編集アイコンはをタップした場合のみ、詳細ページに遷移するようにしたいです。

(PCと同様の挙動)

 trタグのonclickでreturnしてみたのですがダメでした。アラートでいったん止まってもそのまま遷移してしまいます。

$(“tr”).on({

    ‘click’:function(){

    alert(‘詳細ページにに遷移しないで!’);

    return;

    }

});

質問文のコードだと、click イベントを新たに追加する挙動になっているため、初期化時に kintone の実装によって table row に登録されている click イベント(レコード詳細に遷移)が先に発生してしまいます。

回避する実装は下記が考えられますが、2の方法で解決できます。

  1. 既存の click イベントを削除また上書きする
    → onclick 属性に設定したイベントなら容易に削除できるが、kintone の実装は addEventListener(jQuery でいう on 関数)でイベント登録されているため、元のコードがさわれない限り削除は困難
  2. addEventListener の第三引数 useCapture = true を使用して、既存の click イベントよりも先に動く処理を登録させ、Event.stopImmediatePropagation 関数で後続のイベントを抑止する
    → addEventListener はデフォルト(useCapture =  false)ではイベントの登録順に動作するが、kintone の実装はデフォルトでイベント登録されているため、useCapture = true を使用すれば既存のイベントよりも先に実行する処理を登録できる

jQuery の on 関数は useCapture が指定できないので、 jQuery を使わず実装する必要があります。以下サンプルです。

const tr = // table row 要素を取得

tr.addEventListener(
  'click',
  function (e) {
    e.stopImmediatePropagation(); // tr要素に登録されている後続のイベントをすべてキャンセル
  },
  true // useCapture を有効にして既に登録されているイベントよりも先に動作させる
);

※ kintone のカスタマイズはDOM操作をサポートしていないので、保守を念頭に運用することをお勧めします。

以上になります。不明な点がありましたら、気兼ねなくご質問ください。

 

川村さん

返信ありがとうございます!!

早速試してみましたが、結果としては遷移してしまいました。

    const tr = document.getElementsByTagName('tr'); // table row 要素を取得

1行目以外は教えていただいたとおりに書いてみました。

事象としては一覧から詳細ページに遷移してしまいました。

もしかしたら、登録しているイベントを削除する要素が間違っているのかもしれません。。

ソースを追加してtr同様にtdも同時に試してイベントをキャンセルしても遷移してしましました。それ以外で考えられる要素はありますでしょうか?

それ以外ではチャットワークに通知するプラグインを設定しているのですが、そのプラグインを有効にするとトークンエラーが要素をタップするたびに発生してしまいました。そのプラグインでの何らかのイベントも削除しているためかなと予測しています。

ご参考に、イベントを抑止する方法として、CSS で指定することも出来ます。

CSS の場合は、詳細画面等でも適用されてしまいますので、できるだけ対象要素を限定する必要があります。

なお、下記だとルックアップのリンクも無効になります。

.gaia-mobile-v2-indexviewpanel-tableview .gaia-mobile-v2-app-index-recordlist-table-cell:not(:first-child) {
    pointer-events: none;
}

small wave さん

下記だと TR 要素が複数取得できてしまうため、1要素ずつ設定する必要があります。

const tr = document.getElementsByTagName('tr'); // table row 要素を取得

サンプルですが、下記でお望みの動作になると思います。TR要素はレコード一覧に含まれるものに限定しています。

document
.querySelectorAll('tr.gaia-mobile-v2-app-index-recordlist-table-bodyrow')
.forEach(function (tr) {
  tr.addEventListener(
    'click',
    function (e) {
      e.stopImmediatePropagation();
    },
    true
  );
});

※レコード一覧が更新された場合、一覧の要素がリフレッシュされるため、mobile.app.record.index.show 発生時に上記処理を登録する必要があります。

rex0220 さんの仰る通り CSS でも実現可能です(参考になりました、書き込みありがとうございます!)。:has 擬似クラスを使用すれば、セル内のリンクを対象外とすることも可能かと思います。

CSSでの実装は手軽ではあるものの、振る舞いまで制御してしまうと、実装上の責任分界点がわかりにくくなる可能性はあります。また、他のプラグインへの影響や、利用するブラウザなど、要件次第といったところでしょうか。

以上になります。

 

rex0220さん

CSSで制御できるとは知らなかったです。実装できました、ありがとうございます!

 

川村さん

コードまでありがとうございます!実装できました。要件としては今回JS,CSSどちらでも問題ないのですが、今回はJSでいきます。

JSやCSSでのコーディングが10年数年ぶりで進化に驚いています。本当にありがとうございます!

一応 CSS の方も誰かの参考になるかもしれませんので直しておきます。

下記のほうがよさそうです。親要素はイベント不可、子要素のリンクを有効にします。

.gaia-mobile-v2-indexviewpanel-tableview .gaia-mobile-v2-app-index-recordlist-table-cell {
    pointer-events: none;
}
.gaia-mobile-v2-indexviewpanel-tableview .gaia-mobile-v2-app-index-recordlist-table-cell a {
    pointer-events: auto;
}