0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【非公式】メルカリに「オークション一覧タブ」を実装してみた。

0
Posted at

はじめに

メルカリにオークション機能が昨年導入された際は結構驚きました。まさかオークションに参入するとは。実際に僕自身も何度か入札に参加してみましたが結果は惨敗です。なぜ落札できなかったのか?

なぜオークションで落札できなかったのか?

原因は以下の2つが考えれれます。

  1. プッシュ通知を許可していなかったこと(現在はプッシュ通知をONにしています)
  2. 公式のマイページに「オークションページ」が存在しない
    前者はこちらの設定の問題、後者はUI/UXの話になります。
    UX的な話でいうとオークション入札後に自分が入札したアイテムへの直線的な遷移が存在しません。

現在はすべてがフラットな一覧として表示される状態です。
スクリーンショット 2026-04-21 14.58.46.png

そのためオークションに参加した商品を見つけるのは中々難しいです。これを解決するために、ブラウザ拡張機能を使ってマイページに「オークションタブ」を増設し、特定のステータスを持つ商品を抽出する機能を勝手に実装しました。メルカリヘビーユーザーの勝手な愛だと思ってお許しください。

オークションタブを導入。クリックすると『オークションのみ』が表示される。
スクリーンショット 2026-04-21 14.59.03.png

解決したい課題

  • 管理の煩雑さ: オークションと通常の商品が混ざっていているUIを改善したい。
  • 直感的な操作性: メルカリに迷惑をかけずにUIそのものを拡張して、かつ公式機能のような体験(UX)を実現したい。

実装の戦略

メルカリのマイページ(出品した商品)のタブメニューに「オークション」という項目をDOM操作で追加し、そのタブがクリックされた際に特定条件(例:タイトルに特定の記号がある、あるいは独自ストレージに保存された商品など)に合致する商品のみをフィルタリングして表示する形にしています。

技術スタック

言語: Vanilla JavaScript (TypeScript)

技術: Chrome Extension (Content Scripts)

手法: DOM Injection, MutationObserver

実装コードの解説

  1. タブメニューの増設(DOM Injection)

既存のタブ(「出品中」「売却済み」など)の並びに、新しいタブを差し込みます。

/**
 * マイページに「オークション」タブを注入する
 */
const injectAuctionTab = () => {
    // 既存のタブリスト(ulやnav要素)を取得
    const tabList = document.querySelector('.tab-list-selector'); 
    if (!tabList || document.getElementById('merpro-auction-tab')) return;

    // 新しいタブ要素の作成
    const auctionTab = document.createElement('li');
    auctionTab.id = 'merpro-auction-tab';
    auctionTab.className = 'custom-tab-item';
    auctionTab.innerHTML = `<a href="javascript:void(0)">オークション</a>`;

    // クリックイベントの登録
    auctionTab.addEventListener('click', (e) => {
        e.preventDefault();
        switchToAuctionView();
    });
...
};
  1. 表示の切り替えロジック

「オークション」タブが押された際、公式のリストを非表示にし、条件に合う要素だけを再描画(またはフィルタリング)します。

/**
 * オークション形式の商品のみを表示する
 */
const switchToAuctionView = () => {
    const items = document.querySelectorAll('.item-card-container');
    
    items.forEach(item => {
        const title = item.querySelector('.item-name')?.textContent || "";
        
        // 例:タイトルに「🔥」が含まれるものをオークション対象とする
        if (title.includes('🔥')) {
            item.style.display = 'block';
            // ここに残りの「終了時間」をバッジとして表示するロジックを注入
            appendCountdownBadge(item);
        } else {
            item.style.display = 'none';
        }
    });

    // タブの「アクティブ状態」のスタイル制御
...
};

苦労した点:SPA(Single Page Application)への対応

メルカリはSPA構成のため、ページ遷移時に要素が再描画されると、注入したタブが消えてしまいます。これを解決するために MutationObserver を使用し、DOMの変化を監視して、必要に応じて再注入する処理を行っています。


const observer = new MutationObserver(() => {
    if (location.href.includes('/mypage/listings')) {
        injectAuctionTab();
    }
});
...

開発してみて思ったこと

既存の巨大なプラットフォームのUIに、自分の欲しい機能を「タブ」という形でシームレスに統合できるのは、ブラウザ拡張機能開発の醍醐味です。

特にオークション形式の運用では、**「一覧性」がそのまま「管理ミス(終了時間の見落とし)の防止」**に直結します。UIを書き換えることで、オークションの見落としを大きく軽減できることが分かりました。またこの機能で少しでも出品者さんの商品が多くの目に触れることを願っております。

今後の展望

  • タブ内での「残り時間順」のソート機能。
    (ヤフーオークションではこの機能が初期の頃からあり結構助けられています。)

募集

現在、この「メルプロ」拡張機能をさらに進化させるべく、ベータ版ユーザーを募集しています。エンジニアとして「UIをこう変えたらもっと使いやすい」という視点をお持ちの方、ぜひフィードバックをいただけますと幸いです!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?