Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the ElementHandle's class name when using Puppeteer?

Tags:

puppeteer

I'm trying to get an ElementHandle's class name using Puppeteer... is it possible? Am I using the wrong approach? In this jsBin is part of my code, so you can understand what I am trying to achieve.

CriticalCssPlugin.prototype.load = function( page, src ) {
  return page.goto( src, { waitUntil: 'networkidle2' } )
    .then( () => {
      return page
        .$$( '*' )
        .then( elements => {
          return Promise.all( elements.map( element => {
            return element.boundingBox()
          } ) )
            .then( positions => {
              let visible = positions.filter( ( rect, index ) => {
                if ( !rect ) {
                  return rect
                }

                rect.element = elements[ index ]

                return this.isAnyPartOfElementInViewport( rect, page.viewport() )
              } )

              this.getClasses( visible )
            } )
        } )
    } )
}

CriticalCssPlugin.prototype.getClasses = function( visibles ) {
  Promise.all( visibles.map( visible => {
    return visible.element.getProperty( '' )
  } ) )
    .then( classes => {
      console.log(classes);
    } )
}

CriticalCssPlugin.prototype.isAnyPartOfElementInViewport = function( rect, viewport ) {
  const windowHeight = viewport.height
  const windowWidth = viewport.width
  const vertInView = ( rect.y <= windowHeight ) && ( ( rect.y + rect.height ) >= 0 )
  const horInView = ( rect.x <= windowWidth ) && ( ( rect.x + rect.width ) >= 0 )

  return ( vertInView && horInView )
}

https://jsbin.com/kuzejoluji/edit?js,output

Thank you :D

like image 895
Gabriel Bueno Avatar asked May 18 '18 13:05

Gabriel Bueno


Video Answer


4 Answers

Going to drop this here since this page is currently first result searching for "elementhandle class name"

From the docs, you should just be able to the following

const el = await page.$('.myElement')
const className = await el.getProperty('className')

// alternatively,
// page.$('.myElement')
//    .then(el => el.getProperty('className'))
//    .then(className => ... )
like image 53
jimmyjoy Avatar answered Oct 18 '22 04:10

jimmyjoy


jimmyjoy's answer is right but this may help others use the elementHandle

  page.$(el) // This grabs the element (returns a elementHandle)
    .then((el) => el.getProperty("className")) // Returns a jsHandle of that property
    .then((cn) => cn.jsonValue()) // This converts the className jsHandle to a space delimitedstring       
    .then((classNameString) => classNameString.split(" ") // Splits into array
    .then((x) => console.log(x)

Which would log an array of classes

Note: when i tried to do a .split on the end of jsonValue() it didn't work as i believe the promise isn't resolved at that point so cn.jsonValue().split(" ") wont work


References

List of properties on elements

Puppeteer docs for ElementHandle

like image 10
Daniel Avatar answered Oct 18 '22 03:10

Daniel


I found a solution that helps in parts, but it was good enough to me. I've got the class name acessing ElementHandle._remoteObject.description. Hope this helps someone.

like image 5
Gabriel Bueno Avatar answered Oct 18 '22 04:10

Gabriel Bueno


you can get the element variable and use evaluate function like that:

const element = await page.$(".some-class"); // for ids you can write "#some-id"
const className = await page.evaluate(el => el.className, element);
console.log('className', className) // here you can get the class name
like image 4
Muho Avatar answered Oct 18 '22 04:10

Muho