Jsdom: `element.getBoundingClientRect` 및 `element.getClientRects` κ΅¬ν˜„

에 λ§Œλ“  2013λ…„ 07μ›” 05일  Β·  18μ½”λ©˜νŠΈ  Β·  좜처: jsdom/jsdom

#61 및 #135 κ΄€λ ¨.

μ§€κΈˆκΉŒμ§€ ν•΄λ‹Ή λ¬Έμ œμ— λŒ€ν•œ 토둠을 기반으둜 이것이 κ°€λŠ₯ν•œμ§€ ν™•μ‹€ν•˜μ§€ μ•Šμ§€λ§Œ λ‚˜λŠ” 그것을 버릴 것이라고 μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€.

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•΄ μš”μ†Œλ₯Ό μ œμ–΄ν•˜λŠ” β€‹β€‹κ²½μš° μΈμŠ€ν„΄μŠ€λ³„λ‘œ μž¬μ •μ˜ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

μ˜ˆμ‹œ:

function createMockDiv (width, height) {
  const div = document.createElement("div");
  Object.assign(div.style, {
    width: width+"px",
    height: height+"px",
  });
  // we have to mock this for jsdom.
  div.getBoundingClientRect = () => ({
    width,
    height,
    top: 0,
    left: 0,
    right: width,
    bottom: height,
  });
  return div;
}

λͺ¨λ“  18 λŒ“κΈ€

getBoundingClientRectλŠ” μ΅œμ†Œν•œ 기본값을 λ°˜ν™˜ν•˜λŠ” 더미 ν•¨μˆ˜λ‘œ κ΅¬ν˜„λ˜μ–΄μ•Ό ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

ν•©λ¦¬μ μœΌλ‘œ λ³΄μž…λ‹ˆλ‹€. λͺ¨λ“  것에 λŒ€ν•΄ 0μž…λ‹ˆλ‹€. 패치λ₯Ό ν™˜μ˜ν•©λ‹ˆλ‹€.

@F1LT3R , @domenic κ°μ‚¬ν•©λ‹ˆλ‹€! (κ·Έ 사이에 λ‚˜λŠ” μ‹€μ œλ‘œ 이미 μ΄λŸ¬ν•œ ν…ŒμŠ€νŠΈλ₯Ό nodeunitμ—μ„œ μ μ ˆν•œ μ›Ή 기반 ν”„λ ˆμž„μ›Œν¬μΈ QUnit으둜 μ΄μ‹ν•˜κΈ°λ‘œ ν–ˆμŠ΅λ‹ˆλ‹€.) :+1:

getClientRectsκ°€ jsdomμ—μ„œ μž‘λ™ν•©λ‹ˆκΉŒ? 이 jquery ν‹°μΌ“ 에 λ”°λ₯΄λ©΄,

getClientRectsλŠ” μ§€μ›λ˜μ§€ μ•Šκ³  getBoundingClientRect만 μ§€μ›λ©λ‹ˆλ‹€. 항상 빈 λ°°μ—΄(λ˜λŠ” λͺ¨λ“  값에 λŒ€ν•΄ 0이 μžˆλŠ” 단일 rectκ°€ μžˆλŠ” λ°°μ—΄??)을 λ°˜ν™˜ν•˜λŠ” getClientRects()λ₯Ό μΆ”κ°€ν•˜λŠ” PR은 ν›Œλ₯­ν•  κ²ƒμž…λ‹ˆλ‹€.

예, jquery 1.12.0 λŠ” getClientRects λ₯Ό μ‚¬μš©ν•˜λ„λ‘ 핡심 μŠ€νƒ€μΌ κΈ°λŠ₯을 μ—…λ°μ΄νŠΈν–ˆμŠ΅λ‹ˆλ‹€. μš°λ¦¬λŠ” 같은 λ¬Έμ œμ— μ§λ©΄ν–ˆμŠ΅λ‹ˆλ‹€. μ›”μš”μΌμ— 이것을 μΆ”κ°€ν•˜μ—¬ PR을 ν•  수 μžˆμ„μ§€λ„ λͺ¨λ¦…λ‹ˆλ‹€. 우리의 경우 μ§€κΈˆ λ˜μ§€κ³  μžˆλŠ” 것은 .height() ν•¨μˆ˜μ˜€μŠ΅λ‹ˆλ‹€.

el.getBoundingClientRect()μ—μ„œ μ˜¬λ°”λ₯Έ 값을 κ°€μ Έμ˜¬ 수 μ—†μŠ΅λ‹ˆλ‹€. λ°˜ν™˜λ˜λŠ” κ°œμ²΄μ—λŠ” λͺ¨λ“  μ˜¬λ°”λ₯Έ ν‚€(높이, λ„ˆλΉ„, μœ„μͺ½ λ“±)κ°€ μžˆμ§€λ§Œ λͺ¨λ“  값은 항상 0μž…λ‹ˆλ‹€. λ‹€λ₯Έ μ‚¬λžŒμ΄ 이 문제λ₯Ό κ²ͺκ³  μžˆλŠ”μ§€ μ•Œκ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

이것은 항상 μ‹€νŒ¨ν•©λ‹ˆλ‹€:

    it('getBoundingClientRect produces correct height', () => {
      container.style.height = '300px'
      expect(container.getBoundingClientRect().height).eql(300)
    })

ν…ŒμŠ€νŠΈλ₯Ό ν†΅κ³Όν•˜κΈ° μœ„ν•œ ν•΄κ²° 방법(λ§ν•˜κΈ° νž˜λ“  문ꡬ)은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

getComputedElHeight(el) {
    return Number(window.getComputedStyle(el).height.split('px')[0])
  }

이 λ¬Έμ œκ°€ 아직 μ—΄λ € μžˆλŠ” λ™μ•ˆ κ³΅μœ ν•  μƒκ°μž…λ‹ˆλ‹€.

μ˜¬λ°”λ₯Έ 값을 갖도둝 κ΅¬ν˜„λ˜μ—ˆλ‹€κ³  μƒκ°ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 그랬던 것 κ°™μ•„μš”
μ˜¬λ°”λ₯Έ μ†μ„±λ§Œ 갖도둝 κ΅¬ν˜„λ©λ‹ˆλ‹€.
2016λ…„ 3μ›” 14일 μ˜€μ „ 9μ‹œ 2뢄에 "lushfuture" [email protected]이 μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

μ˜¬λ°”λ₯Έ 값을 κ°€μ Έμ˜¬ 수 μ—†μŠ΅λ‹ˆλ‹€.
el.getBoundingClientRect(). λ°˜ν™˜λ˜λŠ” κ°μ²΄λŠ” λͺ¨λ“ 
ν‚€(높이, λ„ˆλΉ„, μœ„μͺ½ λ“±)λŠ” μ •ν™•ν•˜μ§€λ§Œ λͺ¨λ“  값은 항상 0μž…λ‹ˆλ‹€.
λ‹€λ₯Έ μ‚¬λžŒμ΄ 이것을 κ²½ν—˜ν•˜κ³  μžˆλŠ”μ§€ μ•Œκ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

이것은 항상 μ‹€νŒ¨ν•©λ‹ˆλ‹€:

it('getBoundingClientRect produces correct height', () => {
  container.style.height = '300px'
  expect(container.getBoundingClientRect().height).eql(300)
})

ν…ŒμŠ€νŠΈλ₯Ό ν†΅κ³Όν•˜κΈ° μœ„ν•œ ν•΄κ²° 방법(μ΄λŠ” λ‚˜λ₯Ό κ΄΄λ‘­νžˆλŠ” λ¬Έκ΅¬μž…λ‹ˆλ‹€.
말) λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

getComputedElHeight(μ—˜) {
λ°˜ν™˜ 번호(window.getComputedStyle(el).height.split('px')[0])
}

이 λ¬Έμ œκ°€ 아직 μ—΄λ € μžˆλŠ” λ™μ•ˆ κ³΅μœ ν•  μƒκ°μž…λ‹ˆλ‹€.

β€”
이 이메일에 직접 λ‹΅μž₯ν•˜κ±°λ‚˜ GitHubμ—μ„œ ν™•μΈν•˜μ„Έμš”.
https://github.com/tmpvar/jsdom/issues/653#issuecomment -196300151.

예, μ‹€μ œ 값을 λ°˜ν™˜ν•˜λ„λ‘ ν•˜λ €λ©΄ 본질적으둜 λŒ€κ·œλͺ¨ μž‘μ—…μ΄ 될 전체 λ ˆμ΄μ•„μ›ƒ 엔진을 κ΅¬ν˜„ν•΄μ•Ό ν•©λ‹ˆλ‹€. 문제 #1322μ—μ„œ ν•΄λ‹Ή 주제λ₯Ό λ‹€λ£Ήλ‹ˆλ‹€.

ν…ŒμŠ€νŠΈμ—μ„œ ν•΄λ‹Ή λ©”μ„œλ“œ(λͺ¨λ“  μš”μ†Œμ— λŒ€ν•΄)λ₯Ό μž¬μ •μ˜ν•˜μ—¬ ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” μ½”λ“œλ₯Ό ν…ŒμŠ€νŠΈν•˜λŠ” λ™μ•ˆ μ‚¬μš© κ°€λŠ₯ν•œ 값을 얻을 수 μžˆμŠ΅λ‹ˆκΉŒ?

예, λΈŒλΌμš°μ €μ—μ„œμ™€ 같은 λ°©μ‹μœΌλ‘œ: Element.prototype.getBoundingClientRect = function () { ... }

λ‚˜λŠ” λλ‚΄μ—ˆλ‹€
μ°½._μ½”μ–΄. HTMLDivElement.prototype.getBoundingClientRect

잘 μž‘λ™ν–ˆμŠ΅λ‹ˆλ‹€.

μ΄λŠ” jsdom의 ν–₯ν›„ λ¦΄λ¦¬μŠ€μ—μ„œ 쀑단될 κ²ƒμž…λ‹ˆλ‹€(곧, μ‹€μ œλ‘œ). ._core μ œκ±°ν•˜λ©΄ λ©λ‹ˆλ‹€.

κ°μ‚¬ν•©λ‹ˆλ‹€ μ‹œλ„ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€
2016λ…„ 9μ›” 2일 μ˜€ν›„ 9μ‹œ 3뢄에 "Domenic Denicola" [email protected]이 μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

μ΄λŠ” jsdom의 ν–₯ν›„ λ¦΄λ¦¬μŠ€μ—μ„œ 쀑단될 κ²ƒμž…λ‹ˆλ‹€(곧, μ‹€μ œλ‘œ). 단지
_coreλ₯Ό μ œκ±°ν•©λ‹ˆλ‹€.

β€”
당신이 λŒ“κΈ€μ„ λ‹¬μ•˜κΈ° λ•Œλ¬Έμ— 이것을 λ°›λŠ” κ²ƒμž…λ‹ˆλ‹€.
이 이메일에 직접 λ‹΅μž₯ν•˜κ³  GitHubμ—μ„œ ν™•μΈν•˜μ„Έμš”.
https://github.com/tmpvar/jsdom/issues/653#issuecomment -244520584 λ˜λŠ” μŒμ†Œκ±°
μŠ€λ ˆλ“œ
https://github.com/notifications/unsubscribe-auth/AEtD9luz1uJWmJ3JlgdwuO1i5MP04_BXks5qmNWCgaJpZM4Ayv3U
.

ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•΄ μš”μ†Œλ₯Ό μ œμ–΄ν•˜λŠ” β€‹β€‹κ²½μš° μΈμŠ€ν„΄μŠ€λ³„λ‘œ μž¬μ •μ˜ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

μ˜ˆμ‹œ:

function createMockDiv (width, height) {
  const div = document.createElement("div");
  Object.assign(div.style, {
    width: width+"px",
    height: height+"px",
  });
  // we have to mock this for jsdom.
  div.getBoundingClientRect = () => ({
    width,
    height,
    top: 0,
    left: 0,
    right: width,
    bottom: height,
  });
  return div;
}

getboundingclientrect() λ©”μ„œλ“œκ°€ ts 파일의 if else 쑰건에 μžˆλŠ” 경우 μΉ΄λ₯΄λ§ˆ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” 방법.
λˆ„κ΅¬λ“ μ§€ λ„μ™€μ£Όμ„Έμš”.

window.HTMLElement.prototype.getBoundingClientRect = function () {
  return {
    width: parseFloat(this.style.width) || 0,
    height: parseFloat(this.style.height) || 0,
    top: parseFloat(this.style.marginTop) || 0,
    left: parseFloat(this.style.marginLeft) || 0
  }
}

그리고 이것은 μ˜€ν”„μ…‹μ„ μœ„ν•œ 것이기도 ν•©λ‹ˆλ‹€.

Object.defineProperties(window.HTMLElement.prototype, {
  offsetWidth: {
    get () { return parseFloat(this.style.width) || 0 }
  },
  offsetHeight: {
    get () { return parseFloat(this.style.height) || 0 }
  },
  offsetTop: {
    get () { return parseFloat(this.style.marginTop) || 0 }
  },
  offsetLeft: {
    get () { return parseFloat(this.style.marginLeft) || 0 }
  }
})
이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰