注: dom 要素のさまざまな幅と高さ、getBoundingClientRect、clientWidth、clientHeight、offsetWidth、offsetHeight

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)
  }, [])

! ! !
ソース ネットワークの一部

おすすめ

転載: blog.csdn.net/weixin_40119412/article/details/130275074