HTMLElement.getBoundingClientRect
Element.getBoundingClientRect()
戻り値は、DOMRect
要素全体 (パディングとボーダー幅を含む) を囲む最小の四角形であるオブジェクトです。このオブジェクトは、left、top、right、bottom、x、y、width 和 height
これらのいくつかの読み取り専用プロパティをピクセル単位で使用して、四角形全体の位置とサイズを記述します。幅と高さ以外のプロパティは、ビュー ウィンドウの左上隅を基準にして計算されます。
このメソッドによって返される DOMRect オブジェクトの幅と高さのプロパティには、コンテンツ部分の幅と高さだけでなく、パディングとボーダー幅が含まれます。
標準のボックス モデルでは、これら 2 つのプロパティ値は、それぞれ要素の幅/高さ + パディング + ボーダー幅に等しくなります。
box-sizing: border-box の場合、2 つのプロパティは要素の幅または高さに直接等しくなります。
getBoundingClientRect を介して取得される属性値は、スクロール オフセットを計算せず、ブラウザの表示可能領域に相対的です。
.box {
background-color: palevioletred;
height: 200px;
width: 200px;
}
.box {
background-color: palevioletred;
height: 200px;
width: 200px;
padding: 20px;
border: 10px solid green;
}
.box {
background-color: palevioletred;
height: 200px;
width: 200px;
margin: 30px;
}
<div className="App">
<div className='state_box'></div>
<div className='parent_box' id='parent_box'>
<div className='box' id='box'>
</div>
</div>
</div>
.state_box {
height: 200px;
background-color: aquamarine;
}
.parent_box {
height: 600px;
width: 600px;
background-color: olivedrab;
margin-left: 100px;
padding: 30px 50px;
}
.box {
height: 200px;
width: 200px;
background-color: palevioletred;
}
const boxDom = document.getElementById('box')
console.log('boxDom',boxDom?.getBoundingClientRect());
ボックスにパディング、ボーダー、マージンを追加した後
.state_box {
height: 200px;
background-color: aquamarine;
}
.parent_box {
height: 600px;
width: 600px;
background-color: olivedrab;
margin-left: 100px;
padding: 30px 50px;
}
.box {
height: 200px;
width: 200px;
background-color: palevioletred;
border: 10px solid orange;
padding: 10px 20px;
margin: 10px 20px;
}
const boxDom = document.getElementById('box')
console.log('boxDom',boxDom?.getBoundingClientRect());
console.log('getClientRects',boxDom?.getClientRects() );
HTMLElement.clientWidth
読み取り専用プロパティ Element.clientWidth は、インライン要素および CSS スタイルのない要素の場合は 0 です。それ以外の場合は、要素内のピクセル単位の幅です。このプロパティにはパディングが含まれますが、境界線、マージン、および垂直スクロールバー (存在する場合) は含まれません。
属性値は整数に丸められます。小数値が必要な場合に使用できますelement.getBoundingClientRect()
。
<div className="App">
<div className='state_box'></div>
<div className='parent_box' id='parent_box'>
<div className='box' id='box'>
</div>
</div>
</div>
.state_box {
height: 200px;
background-color: aquamarine;
}
.parent_box {
height: 600px;
width: 600px;
background-color: olivedrab;
margin-left: 100px;
padding: 30px 50px;
}
.box {
height: 200px;
width: 200px;
background-color: palevioletred;
border: 10px solid orange;
padding: 10px 20px;
margin: 10px 20px;
}
const boxDom = document.getElementById('box')
console.log('clientWidth',boxDom?.clientWidth);
console.log('clientHeight',boxDom?.clientHeight);
console.log('clientLeft',boxDom?.clientLeft);
console.log('clientTop',boxDom?.clientTop);
clientLeft: 要素の左ボーダーの幅は border-left
clientTop: 要素の上ボーダーの幅は border-top
境界テストを修正する
.box {
height: 200px;
width: 200px;
background-color: palevioletred;
border-top: 30px solid orange;
border-bottom: 30px solid orange;
border-left: 20px solid orange;
border-right: 20px solid orange;
padding: 10px 20px;
margin: 10px 20px;
}
ボックスが box-sizing に変更された場合: border-box;
.box {
height: 200px;
width: 200px;
background-color: palevioletred;
border-top: 30px solid orange;
border-bottom: 30px solid orange;
border-left: 20px solid orange;
border-right: 20px solid orange;
padding: 10px 20px;
margin: 10px 20px;
box-sizing: border-box;
}
HTMLElement.offsetWidth
HTMLElement.offsetWidth
HTMLElement.offsetWidth は、要素のレイアウト幅を返す読み取り専用プロパティです。典型的な offsetWidth は、包含要素の境界 (border)、水平線のパディング (padding)、垂直スクロールバー (scrollbar) (存在する場合)、および CSS によって設定された幅 (width) の測定値です。
クエリ: https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/offsetWidth
const computeItem = (text, last, paddingRight = 10) => {
let width = 0;
const span = document.createElement('span');
span.innerText = text;
if (!last) {
// 非最后一个元素,padding-right设置10px
span.style.paddingRight = `${
paddingRight}px`;
}
span.className = 'getTextWidth';
document.querySelector('body')?.appendChild(span);
span.style.display = 'inline-block';
width = document.querySelector('.getTextWidth')?.offsetWidth;
// 移除元素
document.querySelector('.getTextWidth')?.remove();
console.log('text-width', width);
return width;
};
HTMLElement.offsetLeft
HTMLElement.offsetLeft は、HTMLElement.offsetParent ノードの左端に対する現在の要素の左上隅のオフセットをピクセル単位で返す読み取り専用プロパティです。
HTMLElement.offsetTop
TMLElement.offsetTop は、offsetParent 要素の上部パディングに対する現在の要素の距離を返す読み取り専用プロパティです。
HTMLElement.offsetParent
HTMLElement.offsetParent は、この要素または最も近い table、td、th、body 要素を含む最も近い (包含レベルで最も近いものを参照する) 配置された要素へのポインターを返す読み取り専用プロパティです。要素の style.display が「none」に設定されている場合、offsetParent は null を返します。
const dom = document.querySelector('.box');
console.log('offsetParent', dom?.offsetParent);
console.log('offsetLeft', dom?.offsetLeft);//offsetLeft 60
オフセットデモ
スクロールトップ
要素が最後までスクロールされたかどうかを判断する
scrollTop は整数ではなく、scrollHeight と clientHeight は丸められているため、スクロール領域が一番下までスクロールしたかどうかを判断する唯一の方法は、スクロール量が特定のしきい値に十分近いかどうかを確認することです。
Math.abs(element.scrollHeight - element.clientHeight - element.scrollTop) < 1
スクロール幅
Element.scrollWidth この読み取り専用プロパティは、オーバーフローのために画面に表示されないコンテンツを含む、要素のコンテンツの幅の尺度です。
scrollWidth 値は、要素が水平スクロールバーを使用せずにすべてをビューポートに収めるために必要な最小幅に等しくなります。幅は clientWidth と同じ方法で測定されます。要素のパディングは含まれますが、境界線、マージン、または垂直スクロールバー (存在する場合) は含まれません。::before や ::after などの疑似要素の幅を含めることもできます。要素のコンテンツが水平スクロールバーなしで収まる場合、その scrollWidth は clientWidth と等しくなります
.state_box {
height: 200px;
background-color: aquamarine;
}
.parent_box {
height: 600px;
width: 600px;
background-color: olivedrab;
margin-left: 100px;
padding: 30px 50px;
overflow: auto;
}
.box {
height: 200px;
width: 1000px;
background-color: palevioletred;
border-top: 30px solid orange;
border-bottom: 30px solid orange;
border-left: 20px solid orange;
border-right: 20px solid orange;
padding: 10px 20px;
margin: 10px 20px;
}
const boxDom = document.getElementById('box')
console.log('clientWidth',boxDom?.clientWidth);
console.log('clientHeight',boxDom?.clientHeight);
console.log('scrollWidth',boxDom?.scrollWidth);
console.log('scrollHeight',boxDom?.scrollHeight);
console.log('scrollLeft',boxDom?.scrollLeft);
console.log('offsetTop',boxDom?.scrollTop);
親要素にスクロールバーが表示されます
useEffect(() => {
const boxDom = document.getElementById('box')
console.log('clientWidth', boxDom?.clientWidth);
console.log('clientHeight', boxDom?.clientHeight);
console.log('scrollWidth', boxDom?.scrollWidth);
console.log('scrollHeight', boxDom?.scrollHeight);
console.log('scrollLeft', boxDom?.scrollLeft);
console.log('offsetTop', boxDom?.scrollTop);
// 监听滚动事件
window.addEventListener('scroll', (e) => {
console.log('e',e);
console.log('------------------');
const boxDom = document.getElementById('parent_box')
console.log('clientWidth', boxDom?.clientWidth);
console.log('clientHeight', boxDom?.clientHeight);
console.log('scrollWidth', boxDom?.scrollWidth);
console.log('scrollHeight', boxDom?.scrollHeight);
console.log('scrollLeft', boxDom?.scrollLeft);
console.log('offsetTop', boxDom?.scrollTop);
console.log('------------------');
}, true)
}, [])
イベント マウス pageX、pageY、clientX、clientY、screenY、screenX
コンピューター画面の左上隅の screenX: コンピューター画面の左上隅を基準としたマウス クリック位置の水平オフセット screenY: コンピューター画面の左上隅を基準としたマウス クリック位置の垂直オフセット
e.screenX
ブラウザのコンテンツ領域の左上隅にある clientX: ブラウザの表示可能領域に対するマウス クリック位置の水平オフセット (水平スクロールの距離は計算されません) clientY: ブラウザの表示可能領域に対するマウス クリック位置の垂直オフセットブラウザの表示可能領域 (垂直スクロールバーの距離は計算されません)
e. clientX
ページの左上隅 pageX: Web ページの左上隅に対するマウス クリック位置の水平オフセット、つまり clientX と水平スクロール バーの間の距離 pageY: の垂直水平オフセットWeb ページの左上隅を基準としたマウス クリック位置、つまり、clientY に垂直スクロール バー
e.pageXの距離を加えたもの
offsetX: トリガー イベント オブジェクトに対するマウス クリック位置の水平距離 offsetY: トリガー イベント オブジェクトに対するマウス クリック位置の垂直距離
e.nativeEvent.offsetX
<div className="box" onClick={(e) => {
console.log('e', e);
}}
>
hello
</div>
e.nativeEvent.layerX
e.nativeEvent.layerY
HTMLElement.outerText
HTMLElement.outerTextは非標準のプロパティです。getter として、HTMLElement.innerText と同じ値を返します。
デモ
左右に分かれた箱。
- 左ラベルの長さと右ラベルの長さの合計値がボックスの長さより短く、すべて表示される
- 左ラベルの長さ + 右ラベルの長さがボックスの長さより大きい
- 左辺が全長の半分より大きい場合、左辺が表示する長さを超えています...
const leftList = ['hello world', 'this is pencil', '大熊猫', '平摊TER', 'this is pencil', '大熊猫', '平摊TER', 'this is pencil', '大熊猫', '平摊TER'];
const rightList = ['阳光 沙滩', 'this is pencil', '大熊猫'];
- 右側が全長の半分より大きい場合、右側が表示長を超えて表示する...
const leftList = ['hello world', 'this is pencil', '大熊猫', '平摊TER'];
const rightList = ['阳光 沙滩', 'this is pencil', '大熊猫', '平摊TER', '阳光 沙滩', 'this is pencil', '大熊猫', '平摊TER'];
- どちらも全長の半分を超えると、左右それぞれに表示が……
const leftList = ['hello world', 'this is pencil', '大熊猫', '平摊TER', 'this is pencil', '大熊猫', '平摊TER'];
const rightList = ['阳光 沙滩', 'this is pencil', '大熊猫', '平摊TER', '阳光 沙滩', 'this is pencil', '大熊猫', '平摊TER'];
dom 要素のデモの長さを計算する
const leftList = ['hello world', 'this is pencil', '大熊猫', '平摊TER'];
const rightList = ['阳光 沙滩', 'this is pencil', '大熊猫', '平摊TER', '阳光 沙滩', 'this is pencil', '大熊猫', '平摊TER'];
const leftRef = useRef(null);
const rightRef = useRef(null);
const [leftWidth, setLeftWidth] = useState<number | undefined>(undefined);
const [rightWidth, setRightWidth] = useState<number | undefined>(undefined);
useEffect(() => {
console.log('leftRef', leftRef);
console.log('leftRef', leftRef?.current?.clientWidth);
console.log('rightRef', rightRef);
console.log('rightRef', rightRef?.current?.clientWidth);
// 20代表右侧margin-right, 59代码标题width
// eslint-disable-next-line max-len
const leftBoxWidth = leftList?.reduce((sum, text, i, arr) => sum + computeItem(text, i === arr?.length - 1), 0) + 20 + 58;
// eslint-disable-next-line max-len
const rightBoxWidth = rightList?.reduce((sum, text, i, arr) => sum + computeItem(text, i === arr?.length - 1), 0) + 20 + 58;
console.log('leftBoxWidth', leftBoxWidth);
console.log('leftBoxWidth', rightBoxWidth);
// 给左右盒子设置 width
// 当两者之和超出box宽度时,需要设置width进行...隐藏
if (leftBoxWidth + rightBoxWidth > 800) {
if (leftBoxWidth >= 400 && rightBoxWidth >= 400) {
setLeftWidth(400);
setRightWidth(400);
}
if (leftBoxWidth > 400 && rightBoxWidth < 400) {
setLeftWidth(800 - rightBoxWidth);
setRightWidth(rightBoxWidth);
}
if (leftBoxWidth < 400 && rightBoxWidth > 400) {
setLeftWidth(leftBoxWidth);
setRightWidth(800 - leftBoxWidth);
}
} else {
setLeftWidth(undefined);
setRightWidth(undefined);
}
}, []);
<div className="box">
<div className="left-box" ref={leftRef} style={
{
width: leftWidth }}>
<span className="title">左侧信息</span>
{
leftList?.map((v, i) => (
<span key={i} className="item">{v}</span>
))
}
</div>
<div className="right-box" ref={rightRef} style={
{
width: rightWidth }}>
<span className="title">右侧信息</span>
{
rightList?.map((v, i) => (
<span className="item" key={i}>{v}</span>
))
}
</div>
</div>
.box {
margin-top: 40px;
width: 800px;
border: 1px solid #888;
display: flex;
.title {
padding-right: 10px;
}
.left-box {
margin-right: 20px;
padding-bottom: 10px;
padding-top: 10px;
// 超出不换行
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
box-sizing: border-box;
.item {
margin-right: 10px;
background-color: #e7e7e7;
padding-top: 4px;
padding-bottom: 4px;
&:last-child {
margin-right: 0px;
}
}
}
.right-box {
box-sizing: border-box;
padding-bottom: 10px;
padding-top: 10px;
margin-right: 20px;
// 超出不换行
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
.item {
margin-right: 10px;
background-color: #e7e7e7;
padding-top: 4px;
padding-bottom: 4px;
&:last-child {
margin-right: 0px;
}
}
}
}
window.devicePixelRatio = 1 //屏幕分辨率1920,浏览器缩放比例100%
window.devicePixelRatio = 1.5 //屏幕分辨率1920,浏览器缩放比例150%
window.devicePixelRatio は、ラップトップ画面のスケーリング設定によって決定されます
- ピクセル画面の最小の色ブロック、各色ブロックはピクセル (Pixel) と呼ばれます。
- 解像度 解像度 = 画面の水平方向のピクセル数 * 画面の垂直方向のピクセル数。
window.devicePixelRatio = ディスプレイ デバイスの CSS ピクセル解像度 / ディスプレイ デバイスの物理ピクセル解像度
ディスプレイ
デバイスの幅 物理ピクセル値 = window.screen.width * window.devicePixelRatio;
React がスクロール イベントをリッスンするのは無効です
useEffect(() => {
// 监听滚动事件
window.addEventListener('scroll', (e) => {
console.log('e',e);
})
}, []) ```
解决是addEventListener事件添加第3个参数设置true即可
```js
useEffect(() => {
// 监听滚动事件
window.addEventListener('scroll', (e) => {
console.log('e',e);
}, true)
}, [])
! ! !
ソース ネットワークの一部