1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PuppeteerのElementHandleを拡張してclosestを定義した

Posted at

PuppeteerのElementHandleに対してjQueryのclosestのようなこと(祖先要素のうち、指定したセレクタにマッチする一番近いのを取得する)をしたかったのだけど、そんなメソッドは用意されていないようだったので、拡張することにした。

が、TypeScriptで書いているので、型定義もどうにかしないといけないということで、試行錯誤してどうにか目的を達成したようなので、その成果だけシェアしておこうと思う。

import { ElementHandle } from 'puppeteer/lib/cjs/puppeteer/common/JSHandle';

declare module 'puppeteer' {
  interface ElementHandle<ElementType extends Element = Element> extends JSHandle {
    closest(sel: string): Promise<ElementHandle | null>
  }
}

declare module 'puppeteer/lib/cjs/puppeteer/common/JSHandle' {
  interface ElementHandle extends JSHandle {
    closest(sel: string): Promise<ElementHandle | null>
  }
}

ElementHandle.prototype.closest = async function(sel: string): Promise<ElementHandle | null> {
  const find = async function(e: ElementHandle, sel: string): Promise<ElementHandle | null> {
    const parent = await e.$x('..').then(elems => elems.length > 0 ? elems[0] : null)
    if (parent == null) {
      return null
    } else if (await parent.evaluate((node, sel) => node.matches(sel), sel)) {
      return parent
    } else {
      return find(parent, sel)
    }
  }
  return find(this, sel)
}

メソッドの型情報を2ヶ所に書かないといけないのはどうにかならないものだろうか。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?