我对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;
});
}
答案 0 :(得分:4)
我认为有三个不相关的问题:
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);
}
}
关于此的一些注释:
new
调用的函数,如Date
),它们最初有上限,伪常量是有时在全部大写中完成。所以element
而不是Element
,doSomething
而不是DoSomething
等。HTMLImageElement#complete
加载。但是,根据该规范,存在一种竞争条件,因为completed
在我们检查它和挂钩load
事件之间可能会发生变化(直到我寻找参考时我才意识到这一点;令人惊讶的是,因此可能需要更强大的方法。Element
是一个jQuery实例,其他部分将它传递给$
,就好像它不是。在上面我假设它是一个原始的DOM元素;如果它是一个jQuery实例,只需删除$element = $(element)
位并使用element
而不是$element
。watchForBottomDimension
接受一个名为callback
的参数,该参数应该是一个函数。之后,它调用具有维度的函数(也传回元素,必须作为参考)。loaded
的图像。done
逻辑,所以我将它放在一个嵌套函数中(因为其中一个地方位于load
事件处理程序中)。done
致电setTimeout
。error
),它可能应该;如果图像加载失败,它将永远不会发出回调。您可能会发现this other SO answer关于观看图片加载有用。
答案 1 :(得分:0)
您从哪个角度开始计算元素?
我建议等待整个页面加载bevor你计算任何东西。
您可以使用Jquery函数准备好:
$(document).ready(function(){...});
此处提供更多信息:
答案 2 :(得分:0)
首先,祝贺一个非常优雅的插件!
不幸的是,onload
只会触发:
<body>
<link>
和<script>
<frame>
,<frameset>
和<iframe>
<img>
如果您可以提前预测图像尺寸,那将是理想的选择。由于您的用例不允许,您可以根据脚注的内容绑定到onload
事件:
var resize = function() {
// within this handler, `this` will refer to the img tag.
var container = $(this).closest('.sidenote');
// ... resize calculation ...
}
// bind images in the sidenote to the resize handler
$('img', sidenote).load(resize);
答案 3 :(得分:-1)
尝试以下
$(选择器).height();