由于 html 锚点中的 onclick 事件导致页面加载缓慢
Posted
技术标签:
【中文标题】由于 html 锚点中的 onclick 事件导致页面加载缓慢【英文标题】:Slow loading page due to onclick events in html anchors 【发布时间】:2011-07-07 03:17:37 【问题描述】:我们遇到了一个奇怪的问题,我们正在努力解决这个问题。
我们有一个基于网络的系统,相关页面有一个大约 600 行的表格。每行都有两个选项“锁定/解锁”和“编辑”,它们被实现为两个带有 onclick 事件的锚点。 onclick 事件在 html 中定义,不受 jquery 约束 - 这是因为每个 javascript 调用都基于记录的 id 而不同,例如解锁(132);
此页面需要 10 到 25 秒才能在 Internet Explorer 中呈现,但在 chrome 显示中会立即显示。我们的客户仅支持 Internet Explorer! :(
这是我发现的,我希望有人能解释发生了什么或提供一些原因来解释为什么会出现问题:
如果我将 javascript 调用从 onclick 移到 href 内,页面会立即加载 - 为什么会有任何不同?
如果我将 javascript 调用替换为 alert(''); (仍然在 onlick 属性中)页面立即加载 2a。所以我把我的javascript调用放回去,但用空存根替换了函数,页面仍然加载缓慢。这很奇怪,因为现在我不知道 Internet Explorer 在做什么!
有人听说过类似的事情或对正在发生的事情提供了很好的解释吗?
最好的问候 马修
【问题讨论】:
【参考方案1】:这对我有用:
$(document).ready(function()
$( "a.scrollLink" ).click(function( event )
event.preventDefault();
$("html, body").animate( scrollTop: $($(this).attr("href")).offset().top , 500);
);
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="#anchor1" class="scrollLink">Scroll to anchor 1</a>
<a href="#anchor2" class="scrollLink">Scroll to anchor 2</a>
<div>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
</div>
<p id="anchor1"><strong>Anchor 1</strong> - Lorem ipsum dolor sit amet, nonumes voluptatum mel ea.</p>
<p id="anchor2"><strong>Anchor 2</strong> - Ex ignota epicurei quo, his ex doctus delenit fabellas.</p>
这篇文章你可以在原here找到。
【讨论】:
【参考方案2】:@马修 嗨,我也面临着完全相同的问题。我有一个 java 脚本函数,它接受两个参数并与锚标记上的 onclick 事件绑定。这会减慢 IE 中页面的加载时间。
解决方案: 使用 jQuery 来绑定 onclick 事件,而不是在锚标记内绑定 onclick。 U 可以使用正则表达式来搜索锚元素。 在 document.ready() 中使用如下代码:
$(document.ready(function()
$("a[id^=elemID]").click(function()
//Your call to the javascript function.
);
);
这绝对会解决你的问题。
问候
【讨论】:
【参考方案3】:我很难学到这一点。当文档准备好时使用 js 绑定元素事件对于具有大量元素的页面来说非常非常慢。更不用说通过 js 渲染 HTML(在 ajax 调用之后,我想用新信息更新我的页面,但必须重新渲染整个页面,以防页面其他部分出现新数据)。我的页面一直超时。那是你的IE。所以我决定使用内联事件绑定并在每个事件之后重新加载页面。
【讨论】:
【参考方案4】:如果没有看到一个活生生的例子,很难说为什么会出现问题。我在过去看到过类似的项目,其中 IE6 存在非常严重的性能问题,其中处理程序被动态绑定到大表中的锚点。但当它们在 html 中被硬编码时就不是这样了。
解决此问题的一种方法是在 DOM 中的更高级别捕获一次点击事件,然后识别源锚点。如果您使用的是 jQuery (>=v1.4.2),您可以使用 delegate 快速实现这一点。
在 html 中有以下锚点(注意:data-id
属性将使用 html5 doctype 进行验证):
<td>
<a href="#" class="lock" data-id="123">Lock/Unlock</a>
<a href="#" class="edit" data-id="123">Edit</a>
... data ...
</td>
在您的 js 中添加一个 click 事件委托,该委托将为表中的所有锚点触发。然后,您通过其 data-id 识别单击的锚点并调用您需要的任何功能:
$('table').delegate('a', 'click', function()
var el = $(this)
id = el.attr('data-id');
if (id && el.hasClass('lock'))
alert('Lock/unlock ' + id);
// do stuff...
if (id && el.hasClass('edit'))
alert('Edit ' + id);
// do stuff...
);
使用委托的好处是,如果您动态更改表格内容,事件处理将适用于新创建的锚点。例如,假设您决定在使用 ajax 加载新数据的表上添加分页。
更新:
基于 cmets 添加了一个示例http://jsfiddle.net/johnhunter/QKYJ5/,它使用查询字符串参数将数据传递给委托人。这使 js 远离 html,并且可以构成非脚本回退的基础。
【讨论】:
您好 - 感谢您的回复。我应该发帖说我尝试了 JQUERY,它当然可以工作,并且没有页面加载速度变慢。我实际上有 2 个参数需要传递给函数,所以为了进行测试,我向 添加了自定义属性,这并不理想。目前的解决方案似乎是将 onclick JS 移动到 HREF 属性中,这不是很好,但可以解决眼前的问题。我只是想知道 IE 正在做什么导致问题。 @Matthew 没问题。 IMO 多个自定义属性是可以的 - 毕竟数据应该在 html 中,而行为在 js 中。您可以做的另一件事是将这些参数作为锚点 href 中的查询字符串并在 js.js 中解析它们。这样,如果需要,您可以选择实施非 js 后备。 我其实很喜欢将它们添加为查询字符串参数的机制——JS 中的解析很简洁,意味着 html 没有被污染。感谢您的帮助和这个想法!以上是关于由于 html 锚点中的 onclick 事件导致页面加载缓慢的主要内容,如果未能解决你的问题,请参考以下文章
动态创建 onclick 事件锚元素 - Javascript