javascript - 根据位置在屏幕上移动许多元素的有效方法
问题描述
假设我们在屏幕上有许多 div:
...我们想将这些一致地向左移动:
...在右边:
一种天真的方法是简单地遍历每个元素,获取其当前位置,并将通用移位量应用于每个 div,如下所示:
function set_element_positions(new_top, new_left) {
var all_elems = document.getElementsByClassName("my_div");
for(var i=0; i < all_elems.length; i++) {
var rect = all_elems[i].getBoundingClientRect();
var current_top = rect.top;
var current_left = rect.left;
all_elems[i].style.top = current_top + new_top + "px";
all_elems[i].style.left = current_left + new_left + "px";
}
}
as_change
我可以在鼠标事件期间调用上述函数。例如,滑块可以在更改的同时调用上述函数,这意味着该函数显然会被非常频繁地调用。
这适用于较少数量的 div;它们实时一致地移动。但是一旦 div 的数量变大(~30),它就会开始变慢。
有没有更有效的方法来统一更改所有元素的位置,以便像滑块这样的东西可以快速循环遍历它们并实时修改它们?
解决方案
由于我不确定您要完成什么,因此我将根据不同的情况列出一些解决该问题的方法。
场景 1:移动单个容器中的所有元素
如果这是您的情况,那么您很幸运,因为这是最简单的解决方案。阿尔瓦罗实际上是在正确的轨道上。在这种情况下,您需要的是容器中的容器。让我用一个小例子来解释。首先,HTML:
<div id="viewPort">
<div id="innerContainer">
<div class="my_div"></div>
<div class="my_div"></div>
<div class="my_div"></div>
</div>
</div>
然后,CSS:
#viewPort {
/* Example width/height. Use whatever you want here. */
width: 300px;
height: 200px;
overflow: hidden;
}
#innerContainer {
position: relative;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
}
这个想法是有一个比外部容器占用更多空间的内部容器,并且隐藏溢出(除非您出于某种原因想要滚动条)。设置完成后,您可以 1) 仅调整内部容器的top
和left
属性,或 2) 调整 viewPort (scrollTop
和scrollLeft
) 的滚动位置,从而在不实际移动任何东西的情况下产生移动的错觉。
场景 2:仅移动单个容器中的部分元素
这是事情变得有点棘手的地方,因为您不能再使用移动容器技巧。如果您设置了不想移动到的元素,上述滚动技巧在技术上仍然有效position: fixed
。但是,这将需要调整它们top
和left
属性以确保它们保持在正确的位置。
不幸的是,即使您要移动的所有元素都具有相同的类,您也不能即时更新该类,因为 Javascript 无法修改样式表中的 CSS 样式。您可以尝试获取元素上的现有transform
属性,添加到它,然后使用transformX()
and重新应用它transformY()
,而不是修改left
and top
(关于此主题的上一个问题)。
场景 3:你正在尝试制作游戏
Javascript 是一种解释性语言。与编译语言相比,代码执行速度不会那么快。事实上,带有 Javascript 的基本 HTML 并不是真正设计用于处理可以处理游戏玩法的场景,除了一些例外情况,您可以解决这些限制。如果你想用 HTML5 做一些严肃的事情,你最好的选择是学习<canvas>
or<svg>
标签,并使用其中一个。
推荐阅读
- hibernate - ORA-01400: 当使用 @onetomany 映射并且在子端具有复合主键时,无法将 NULL 插入
- python-3.x - 在列表中删除 0 时跳过 False
- apache-kafka - Kafka K-SQL 数据类型
- excel - 更新工作表内容会导致其他工作表之间的链接中断
- asp.net-mvc - Viewbag 为每次迭代分配值导致错误
- angular - 无法导入“@angular/common/http”
- c# - c++ 和 C# 中的等效系统时钟毫秒数?
- fortran - 为什么 Fortran 比 Octave 慢?
- azure - 是否可以选择将文件从 Azure VM 复制到 VMSS 中的多个 VM
- database - 如何使用 AWS 数据库删除保护删除数据库