我想要一个元素的Y坐标和Y值= 0之间的确切距离,我认为它是文档的顶部.
myElement.getBoundingClientRect().top;
Run Code Online (Sandbox Code Playgroud)
但是getBoundingClientRect()的值似乎在滚动时发生了变化.如何获得myElement和Y坐标= 0(文档顶部)之间的实际距离?
所以当全屏部分在视口中时,我试图调用一些函数.假设我有7个部分,然后当某个部分位于视口内时我希望发生某些事情(我有一个函数将部分捕捉到视口中,因此视口中永远不会有多个部分,但我试图找到在视口中可以看到哪个部分.
这是一个小提琴:http://jsfiddle.net/h7Hb7/2/
function isInViewport() {
$("section").each(function () {
var $this = $(this),
wHeight = $(window).height(),
rect = $this.getBoundingClientRect(); // Error in console
// Borrowed from http://stackoverflow.com/a/7557433/5628
if (rect.top >= 0 && rect.bottom <= wHeight) {
console.log($this.attr("id") + "in viewport");
}
});
}
$(window).scroll(function () {
// Other functions are called inside the setTimeout function, can't remove
clearTimeout($.data(this, "scrollTimer"));
$.data(this, "scrollTimer", setTimeout(function () {
isInViewport();
}, 1200));
});
Run Code Online (Sandbox Code Playgroud)
我不知道从哪里开始看,但我猜它与每个功能有关.每个功能都会造成问题吗?它不能是CSS问题,因为在CSS已经加载时滚动时会出现问题.
我在画布上进行绘图操作.在我看来,相对于画布左上角计算光标位置的最佳方法是使用.getBoundingClientRect():
HTMLCanvasElement.prototype.relativeCoords = function(event) {
var x,y;
//This is the current screen rectangle of canvas
var rect = this.getBoundingClientRect();
//Recalculate mouse offsets to relative offsets
x = event.clientX - rect.x;
y = event.clientY - rect.y;
//Debug
console.log("x(",x,") = event.clientX(",event.clientX,") - rect.x(",rect.x,")");
//Return as array
return [x,y];
}
Run Code Online (Sandbox Code Playgroud)
我认为这段代码没有错,它可以在firefox中运行.测试一下.
但是在谷歌浏览器中,我的调试行打印出来:
x(
NaN)= event.clientX(166) - rect.x(undefined)
我究竟做错了什么? 这不符合规格吗?
编辑:似乎我的代码遵循W3C:
getBoundingClientRect()
getBoundingClientRect()调用该方法时,必须返回以下算法的结果:
让list成为调用
getClientRects()此方法的同一元素的调用结果.如果列表为空,则返回一个
DOMRect对象x,其中y, …
someElement.getBoundingClientRect()返回类型(或显然)的特殊对象的结果ClientRectDomRect
它的结构就像 {top: 10, right: 20, bottom: 30, left: 10, width: 10}
不幸的是,这个对象的行为与其他对象不同.
例如,使用Object.keys它返回一个空数组(我认为因为ClientRect属性不可枚举
我找到了一种转换为普通对象的脏方法:
var obj = {}
for (key in rect) {
obj[key] = rect[key]
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,有更好的方法吗?
有没有办法检测元素的getBoundingClientRect()矩形何时发生变化而没有实际计算getBoundingClientRect()?像"脏旗"的东西?天真地,我认为在浏览器的内部工作中必须存在这样的机制,但是我无法在DOM API中发现这个事物.也许有一种方法可以用MutationObservers做到这一点?
我的应用程序是一个Web组件,它将DOM元素转换为图形的节点,并将边缘绘制到全屏画布上.看到这里.
现在,我正在调用getBoundingClientRect()每个元素,每个动画帧帧一次,即使没有任何变化.这感觉很贵.我通常以60 fps的速度在功能强大的计算机上获得%15-%50的CPU使用率.
有谁知道这样的事情?你认为期待这样的事情是否合理?这种事情可行吗?有没有提过过?
javascript dom dom-events mutation-observers getboundingclientrect
我刚刚发现并且非常喜欢,getBoundingClientRect因为它包含子像素精度.这使我能够创建一致的对齐,即使用户键入Ctrl+或Ctrl+ -.
它具有的属性top,bottom,left,right,& &.widthheight
这是简单的找到在互联网上的浏览器的支持,但没有这么多的的width和height特别的属性.看来这是事后添加的.它适用于Firefox,Chrome和IE10,但是IE8和IE9呢?我不能方便地测试这些.
我正在处理一些使用Element.getBoundingClientRect(gBCR) 加上内联样式更新来执行计算的代码。这不适用于一般网站,我不关心或不感兴趣是否有“更好的 CSS 方法”来完成这项任务。
JavaScript同步运行并执行以下步骤:
我是否保证计算出的客户端边界将反映第 4 步中父对象的新边界矩形?
如果规范没有保证,这是现代1浏览器实现的“保证”吗?如果“基本保证”,有哪些值得注意的例外?
元素不会被添加到 DOM 或从 DOM 中移除,并且被修改的元素是父节点的直接子节点;如果此类限制/信息相关。
1 “现代”:UIWebView (iOS 6+)、WebView (Android 2+),以及常见的 Chrome/WebKit、FF、IE9+ 嫌疑人——包括移动版本。
我有<textarea>元素并在其中创建范围:
document.createRange()<textarea>获取via的唯一子节点textarea.childNodes[0]range.setStart通过和设置范围开始和范围结束range.setEnd然后我打电话range.getBoundingClientRect():
let textarea = document.querySelector('textarea');
let node = textarea.childNodes[0];
let range = document.createRange();
range.setStart(node, 3);
range.setEnd(node, 5);
console.log(range.getBoundingClientRect());Run Code Online (Sandbox Code Playgroud)
<textarea>aa bb cc</textarea>Run Code Online (Sandbox Code Playgroud)
但我收到ClientRect全零字段的对象,即left = top = width = height = 0. 为什么这些字段为零?
<textarea>请注意,如果我用普通的 div替换,一切正常:
let textarea = document.querySelector('div');
let node = textarea.childNodes[0];
let range = document.createRange();
range.setStart(node, 3);
range.setEnd(node, 5);
console.log(range.getBoundingClientRect());Run Code Online (Sandbox Code Playgroud)
<div>aa bb cc</div>Run Code Online (Sandbox Code Playgroud)
我想以可靠的方式找出 DOM 元素的尺寸。
我的考虑是为此使用 getBoundingClientRect 。
const elementRef = useRef<HTMLUListElement | null>(null);
const [dimensions, setDimensions] = useState<DOMRect | undefined>();
const element: HTMLUListElement | null = elementRef.current;
/**
* Update dimensions state.
*/
const updateDimensions = useCallback(() => {
if (!element) return;
setDimensions(element.getBoundingClientRect());
}, [element, setDimensions]);
/**
* Effect hook to receive dimensions changes.
*/
useEffect(() => {
if (element) {
updateDimensions();
}
}, [element, updateDimensions]);
Run Code Online (Sandbox Code Playgroud)
这种方法的问题是 useEffect 只对 elementRef.current 做出反应,而不对 rect 的变化做出反应。显然浏览器中组件的绘制还没有完成,因为尺寸总是0。
如果我在 useEffect 之外做整个事情,那么它就可以工作。在控制台中,我看到 0 的 2 倍值,然后是正确的尺寸。
使用效果: …
dimensions reactjs getboundingclientrect react-hooks ionic-react
javascript ×9
dom ×4
css ×2
html ×2
dimensions ×1
dom-events ×1
ionic-react ×1
jquery ×1
range ×1
react-hooks ×1
reactjs ×1
reflow ×1
safari ×1