简体   繁体   English

onload Javascript的最佳实践

[英]Best Practices for onload Javascript

What is the best way to handle several different onload scripts spread across many pages? 处理遍布多个页面的几个不同的onload脚本的最佳方法是什么?

For example, I have 50 different pages, and on each page I want to set a different button click handler when the dom is ready. 例如,我有50个不同的页面,并且在每个页面上,我想在dom准备好时设置不同的按钮单击处理程序。

Is it best to set onclicks like this on each individual page, 最好在每个页面上设置这样的onclicks,

<a id="link1" href="#" onclick="myFunc()" />

Or a very long document ready function in an external js file, 或者在外部js文件中有一个很长的文档就绪函数,

Element.observe(window, 'load', function() {
  if ($('link1')) {
    // set click handler
  }
  if ($('link2')) {
   // set click hanlder
  }
  ...
}

Or split each if ($('link')) {} section into script tags and place them on appropriate pages, 或者将每个if ($('link')) {}部分拆分成脚本标记并将它们放在适当的页面上,

Or lastly, split each if ($('link')) {} section into its own separate js file and load appropriately per page? 或者最后,将每个if ($('link')) {}部分拆分为自己独立的js文件,并在每页上适当加载?

Solution 1 seems like the least elegant and is relatively obtrusive, solution 2 will lead to a very lengthy load function, solution 3 is less obtrusive then 1 but still not great, and solution 4 will load require the user to download a separate js file per page he visits. 解决方案1似乎是最不优雅且相对突兀的,解决方案2将导致非常冗长的加载功能,解决方案3不那么突兀然后1但仍然不是很好,解决方案4将加载需要用户下载单独的js文件他访问的页面。

Are any of these best (or worst) or is there a solution 5 I'm not thinking of? 这些中最好的(或最差的)还是有解决方案5我没有想到的?

Edit: I am asking about the design pattern, not which onload function is the proper one to use. 编辑:我问的是设计模式,而不是哪个onload函数是正确使用的。

Have you thought about making a class for each type of behavior you'd like to attach to an element? 您是否考虑过为要附加到元素的每种行为创建一个类? That way you could reuse functionality between pages, just in case there was overlap. 这样,您可以在页面之间重用功能,以防万一有重叠。

For example, let's say that on some of the pages you want to a have button that pops up some extra information on the page. 例如,假设您想要的某些页面上有一个按钮,可以在页面上弹出一些额外的信息。 Your html could look like this: 你的HTML看起来像这样:

<a href="#" class="more-info">More info</a>

And your JavaScript could look like this: 你的JavaScript看起来像这样:

jQuery(".more-info").click(function() { ... });

If you stuck to some kind of convention, you could also add multiple classes to a link and have it do a few different things if you needed (since jQuery will let you stack event handlers on an element). 如果您遵循某种约定,您还可以向链接添加多个类,并在需要时让它执行一些不同的操作(因为jQuery将允许您在元素上堆叠事件处理程序)。

Basically, you're focusing on the behaviors for each type of element you're attaching JavaScript to, rather than picking out specific ids of elements to attach functionality to. 基本上,您专注于将JavaScript附加到的每种元素的行为,而不是选择要附加功能的元素的特定ID。

I'd also suggest putting all of the JavaScript into one common file or a limited number of common files. 我还建议将所有JavaScript放入一个公共文件或有限数量的常见文件中。 The main reason being that, after the first page load, the JavaScript would be cached and won't need to load on each page. 主要原因是,在第一次页面加载之后,JavaScript将被缓存,并且不需要在每个页面上加载。 Another reason is that it would encourage you do develop common behaviors for buttons that are available throughout the site. 另一个原因是,它会鼓励您为整个站点中可用的按钮开发常见行为。

In any case, I would discourage attaching the onlick directly in the html (option #1). 在任何情况下,我都不鼓励在html(选项#1)中直接附加onlick。 It's obtrusive and limits the flexibility you have with your JavaScript. 它是突兀的,限制了JavaScript的灵活性。

Edit: I didn't realize Diodeus had posted a very similar answer (which I agree with). 编辑:我没有意识到Diodeus发布了一个非常相似的答案(我同意)。

I would use JQuery's document ready if possible 如果可能的话,我会使用JQuery的 文档

  $(document).ready(function() {

      // jQuery goodness here.
 });

First of all I dont understand why you think setting event listeners is obtrusive? 首先,我不明白为什么你认为设置事件监听器是突兀的?

but ... 但......

Solution one is a bad idea 解决方案之一是一个坏主意

<a id="link1" href="#" onclick="myFunc()" />

because you should keep your make-up and your scripts seperate. 因为你应该保持你的化妆和你的脚本分开。

Solution two is a bad idea 解决方案二是一个坏主意

Element.observe(window, 'load', function() {
  if ($('link1')) {
    // set click handler
  }
  if ($('link2')) {
   // set click hanlder
  }
  ...
}

because you are using a lot of unneeded javascript for every page. 因为你每个页面都使用了很多不需要的javascript。

Solution three is a bad idea for the same reason I said solution one is a bad idea. 解决方案三是一个坏主意,出于同样的原因我说解决方案是一个坏主意。

Solution 4 is the best idea, yeah its one extra load per page, but if for each page you just split each if ($('link')) {} section, the file size can not be that large? 解决方案4是最好的主意,是的,每页额外加载一次,但如果每个页面只拆分if($('link')){}部分,文件大小不能那么大? Plus, if you take this code out of the global javascript, then its load time will be reduced. 另外,如果您从全局javascript中获取此代码,则其加载时间将减少。

You could hack the class name and use it in a creative manner: 你可以破解类名并以创造性的方式使用它:

<a class="loadevent functionA" id="link1" href="#" onclick="myFunc()" />

... on another page... ......在另一页......

<a class="loadevent functionB" id="link1" href="#" onclick="myFunc()" />

You could select by class name " loadevent " and grab the other class names for that tag, the other class name being the actual function name you want to hook into. 您可以按类名“ loadevent ”选择并获取该标记的其他类名,另一个类名是您要挂钩的实际函数名。 This way one handler would be able to do every page and all you have to do is provide the corresponding class names. 这样一个处理程序就能够完成每个页面,您所要做的就是提供相应的类名。

While Chris is somewhat correct in that you can do this: 虽然克里斯在某种程度上是正确的,你可以这样做:

$(document.ready(function() {
  // A
});
$(document.ready(function() {
  // B
});
$(document.ready(function() {
  // C
});

and all functions will be called (in the order they are encountered), it's worth mentioning that the ready() event isn't quite the same to onload(). 并且将调用所有函数(按照它们遇到的顺序),值得一提的是ready()事件与onload()不完全相同。 From the jQuery API docs : 来自jQuery API文档

Binds a function to be executed whenever the DOM is ready to be traversed and manipulated. 绑定要在DOM准备好遍历和操作时执行的函数。

You may want the load() event instead: 您可能需要load()事件:

$(document).load(function() {
  // do stuff
});

which will wait for images and the like to be loaded. 等待图像等加载。

Without resorting to the kneejerk jQuery, if the page varying JS is relatively light I would include it in an inline header script (binding to the onload event trigger, yes) similar to #4, but I wouldn't do this as a separate JS script and download, I'd be looking to handle this with a server side include - however you want to handle that (me? I'd go with XSLT includes). 如果页面变化的JS相对较轻,我会将它包含在内联头文件脚本中(绑定到onload事件触发器,是的)类似于#4,但我不会将其作为单独的JS脚本和下载,我希望通过服务器端包含来处理这个问题 - 但是你想要处理它(我?我将使用XSLT包括)。

That gives you both a high degree of modular separation and keeps the download as light as possible. 这为您提供了高度的模块化分离,并使下载尽可能轻松。

Having a lot of different pages, I would allow different handling of events for those pages ... 拥有很多不同的页面,我会允许对这些页面进行不同的事件处理......

If, however, differencies were slight, I would try to find a pattern I could hang on to, and probably make a real simple algorithm to tell the pages apart ... 但是,如果差异很小,我会尝试找到一个我可以依赖的模式,并且可能会制作一个真正简单的算法来区分页面......

The last thing I would resort to, was to use a (big) library (jquery, mootools or whatever !-) if I wasn't going to use it in any other way ... 我要采取的最后一件事是使用(大)库(jquery,mootools或其他什么! - ),如果我不打算以任何其他方式使用它...

Now you're talking of best practices, best practice would always be what your users will experience as the lightest solution, and in that, users should be understood in the widest possible way, including developers and so on who are to maintain that site !o] 现在您谈论的是最佳实践,最佳实践始终是您的用户将体验为最轻的解决方案,并且应该以最广泛的方式理解用户,包括开发人员等维护该网站的人员! O]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM