Jsdom: HTMLElement offsetParent é indefinido

Criado em 13 out. 2015  ·  6Comentários  ·  Fonte: jsdom/jsdom

Eu tenho alguns códigos que dependem de offsetParent de um HTMLElement, especificamente dentro de um ouvinte de evento. Código que tenho aqui:

window.addEventListener('mousemove', function(e) {
  const control = e.target.offsetParent;
  if (!control) {
    return;
  }

  const factor = this.state.duration / control.offsetWidth;
  const time = e.pageX * factor;
  actions.setCurrentTime(time);
});

No entanto, quando eu testo isso com jest (e, portanto, JSDOM), não consigo fazer com que offsetParent seja definido de forma alguma.

Este é um atributo sem suporte de um HTMLElement?

Comentários muito úteis

Eu sei que isso é antigo, mas se alguém descobrir isso e tiver problemas, resolvi fazer algo semelhante ao acima:

Object.defineProperty(HTMLElement.prototype, 'offsetParent', {
    get() { return this.parentNode; },
});

Todos 6 comentários

Veja # 1013, é basicamente o mesmo problema. Provavelmente não seremos capazes de fazer isso.

Poderia ser corrigido ad hoc? Algo como HTMLElement.prototype.offsetParent = document.createElement('div')

Eu testei isso e não pareceu afetar o e.target

Alguma ideia de como eu poderia fazer algo assim?

Isso pode funcionar, quando você vai fazer isso? O melhor lugar para colocar o código de correção é o retorno de chamada created em jsdom.env , já que ele será executado antes que o documento seja realmente carregado.

Então, como eu disse. Estou usando isso no Jest. Portanto, ele lida com jsdom.env nos bastidores. Estou efetivamente fazendo isso em tempo de execução:

//patch
HTMLElement.prorotype.offsetParent = div;

// handle event
window.addEventListener('mousemove', function event(e) {
  console.log(e.target.offsetParent); // undefined
});

// dispatchEvent
window.dispatchEvent(windowEvent)

Eu sei que isso é antigo, mas se alguém descobrir isso e tiver problemas, resolvi fazer algo semelhante ao acima:

Object.defineProperty(HTMLElement.prototype, 'offsetParent', {
    get() { return this.parentNode; },
});

@panganibanpj Obrigado pelo código cortado. Eu o aprimorei com algumas das especificações do

Object.defineProperty(HTMLElement.prototype, 'offsetParent', {
    get() {
        let element = this;
        while (!isNullOrUndefined(element) &&
                    (isNullOrUndefined(element.style) ||
                    isNullOrUndefined(element.style.display) ||
                    element.style.display.toLowerCase() !== 'none')) {
            element = element.parentNode;
        }

        if (!isNullOrUndefined(element)) {
            return null;
        }

        if (!isNullOrUndefined(this.style) && !isNullOrUndefined(this.style.position) && this.style.position.toLowerCase() === 'fixed') {
            return null;
        }

        if (this.tagName.toLowerCase() === 'html' || this.tagName.toLowerCase() === 'body') {
            return null;
        }

        return this.parentNode;
    },
});
Esta página foi útil?
0 / 5 - 0 avaliações