gpt4 book ai didi

javascript - 内容完全加载后测量元素的高度

转载 作者:搜寻专家 更新时间:2023-11-01 04:27:24 25 4
gpt4 key购买 nike

总的来说,我对 JavaScript/jQuery/编程完全陌生,所以如果我觉得我太天真了,请多多包涵。

我编写了一个脚本,可以将 Tumblr 博客上的脚注转换为“旁注”。在大多数情况下,它工作得很好。你可以see examples on my blog .

我通过将脚注的 innerHTML 附加到一个空的 div,然后使用 CSS (display: none) 隐藏原始脚注来实现这一点。我根本不想更改帖子的标记。这个想法是我可以删除脚本和旁注恢复或“降级”回脚注。

旁注相对于它们的容器是绝对定位的,它们的位置取决于几个因素:前一个旁注的位置、文本中引用链接的位置以及容器的位置。理想情况下,旁注应出现在与文本中引用链接相同的垂直偏移处,但如果前面的元素挡住了路,它会向下移动以避免重叠。

脚本非常简单。基本算术。为了避免元素重叠,我计算了从页面顶部到前一个元素底部的偏移量。如果它大于引用链接的偏移量(和容器的偏移量),则元素向下移动。

如您所见,如果脚注仅包含文本,一切都会完美无缺。但如果它们也包含图像,旁注就会开始重叠。我相信这是因为我正在使用 .outerHeight() 来获取元素的高度,但是如果图像尚未加载,它会返回错误的值。你可以在 one of my test pages 上看到我所说的例子。 .

我想我已经将问题隔离到下面的函数。

我认为如果我使用 .load,它会在执行代码之前等待元素的内容加载。但这似乎并没有发生。

请告诉我我可能做错了什么。我很确定脚本的问题包含在下面的代码中,但如果您认为这看起来不错,我也可以发布脚本的其余部分。或者您可以在 http://resources.contentioninvain.com/scripts/FootnotesToSidenotes.js 查看(抱歉,我是新用户,所以我不能发布超过两个链接,哈哈) .

提前感谢您的任何建议。这是我第一次发布问题,但我发现这个网站在过去非常有用。除了修补之外,这是我第一次尝试从头开始编写脚本(我很自豪我能在没有帮助的情况下走到这一步,哈哈)。

// GetBottomOffset gets the vertical offset to the bottom of an element
// It adds the element's vertical offset and its height:
function GetBottomOffset(Element) {
$(Element).load(function() {
var ElementTop = Element.offset().top; // Vert offset of element
var ElementHeight = Element.outerHeight(true); // Height of element

// Offset to bottom of element
var ElementBottom = ElementTop + ElementHeight;

// Returns ElementBottom
return ElementBottom;
});
}

最佳答案

我认为存在三个不相关的问题:

  1. 我认为您还必须单独观察图像是否加载,并且只有在加载所有内容时才进行计算。
  2. 如果您等待事件先发生,则不能返回函数的值,因为函数在事件发生之前已经返回。您需要使用回调。
  3. 在 Hook load 事件之前,您必须允许图像已经被加载。

例如:

function watchForBottomDimension(element, callback) {
var $element, images, loaded;

// Get a jQuery wrapper for `element`
$element = $(element);

// Find the images within it that aren't loaded yet
images = $element.find("img").filter(function(index, img) {
return !img.complete;
});

// Find any?
if (images.length === 0) {
// No, we're done -- call the callback asynchronously for
// consistency with the case below where we have to wait
setTimeout(done, 0);
}
else {
// We're waiting for some images, do that
loaded = 0;
images.load(function() {
// One of them loaded; was it the last one?
if (++loaded === images.length) {
// Yup, we're done
done();
}
});
}

// Handle completion
function done() {
var top, height, bottom;

top = $element.offset().top; // Vert offset of element
height = $element.outerHeight(true); // Height of element

// Offset to bottom of element
bottom = top + height;

// Call the callback with the value
callback(element, bottom);
}
}

一些注意事项:

  1. 这是题外话,但它可能是您在上面注意到的第一件事,所以:我已经更改了事物的名称。在 JavaScript 中,压倒性的惯例是对除构造函数(您主要使用 new 调用的函数,如 Date)之外的所有内容使用初始小写字母,它们最初是上限的,和有时全部大写的伪常量。所以 element 而不是 ElementdoSomething 而不是 DoSomething,等等
  2. 我正在检查图像是否通过 HTMLImageElement#complete 加载.不过,根据该规范,存在竞争条件,因为 completed 可能会在我们检查它和 Hook load 事件之间发生变化(我直到我才意识到这一点去寻找引用;令人惊讶),因此可能需要更稳健的方法。
  3. 您的部分原始代码假设 Element 是一个 jQuery 实例,其他部分将它传递到 $ 中,就好像它不是。在上面我假设它是一个原始的 DOM 元素;如果它是一个 jQuery 实例,只需删除 $element = $(element) 位并使用 element 而不是 $element
  4. 请注意,我的 watchForBottomDimension 接受一个名为 callback 的参数,它应该是一个函数。稍后,它用维度调用该函数(还传回元素,必须供引用)。
  5. 我删除了观察元素本身的位;它不应该是必需的(除非元素是图像)。但我添加了监视其中的图像——具体来说,是(尚未)加载的图像。
  6. 有两个终止条件:A) 没有我们需要等待的图像,B) 有。所以我们需要在两个地方执行我们的done 逻辑,所以我把它放在一个嵌套函数中(因为其中一个地方在 load 事件处理程序中)。<
  7. 由于我们的终止条件之一是异步,所以我将它们设为异步,因此调用者看到的是相同的东西(异步结果),无论是否有图像是否观看,通过 setTimeout 调用 done 在我们不需要等待任何事情的情况下。
  8. 上面没有监 View 像加载错误(通过 error ),它可能应该这样做;如果图像加载失败,它永远不会发出回调。

您可能会发现 this other SO answer关于观看图像加载很有帮助。

关于javascript - 内容完全加载后测量元素的高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6530831/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com