未找到onload函数init

时间:2014-04-12 05:06:42

标签: javascript windows-phone-8

我遇到了一个奇怪的问题。我正在开发一个书籍应用程序并使用javascript onload。我在某处读到最好在html末尾包含你的javascript。这适用于大多数加载的html。但有些人抱怨没有找到onload init()。如果我在html头中包含javascript,这会得到解决。但是,与其他htmls开始表现奇怪。在页面完全加载之前调用onload。我没有得到正确的滚动宽度。请提出一些可能的建议。什么是包含javascripts的最佳方式。感谢

html如下

columizer id使用css列宽,我已经像这样定义了。 下面的CSS样式

#columnizer 
{
width:290px;
height:450px;
column-width:290px;
column-gap:10px;
word-wrap:break-word; 
}

Javascript onload is defined like this.

function init() 
{
docScrollWidth = document.getElementById('columnizer').scrollWidth;
document.getElementsByTagName('body')[0].style.width = docScrollWidth  + "px";
window.external.notify(str);
}

2 个答案:

答案 0 :(得分:0)

首先,让我来定义问题。程序员使用window.onload事件来启动他们的Web应用程序。这可能是一些微不足道的事情,如动画菜单或复杂的事情,如初始化邮件应用程序。问题是onload事件在加载所有页面内容(包括图像和其他二进制内容)后触发。如果您的页面包含大量图像,那么在页面变为活动状态之前您可能会看到明显的延迟。我们想要的是一种确定DOM何时完全加载而不等待所有那些讨厌的图像加载的方法。

Mozilla为此提供量身定制的(未记录的)事件:DOMContentLoaded。以下代码将完全符合我们对Mozilla平台的要求:

// for Mozilla browsers

if (document.addEventListener) {
  document.addEventListener("DOMContentLoaded", init, false);
}

那么Internet Explorer呢?

IE支持标签的非常方便(但非标准)属性:defer。此属性的存在将指示IE在加载DOM之前推迟加载脚本。但这仅适用于外部脚本。另一个需要注意的重要事项是无法使用脚本设置此属性。这意味着您无法使用DOM方法创建脚本并设置defer属性 - 它将被忽略。

使用handy defer属性,我们可以创建一个调用onload处理程序的迷你脚本:

<script defer src="ie_onload.js" type="text/javascript"></script>

这个外部脚本的内容将是一行代码来调用我们的onload事件处理程序:

init();

这种方法存在一个小问题。其他浏览器将忽略defer属性并立即加载脚本。这有几种方法。我首选的方法是使用conditional comments隐藏其他浏览器的延迟脚本:

<!--[if IE]><script defer src="ie_onload.js"></script><![endif]-->

IE也支持conditional compilation。以下代码是上述HTML的等效JavaScript:

// for Internet Explorer

/*@cc_on @*/
/*@if (@_win32)
  document.write("<script defer src=ie_onload.js><\/script>");
/*@end @*/

到目前为止一切顺利?我们现在需要支持其余的浏览器。我们只有一个选择 - 标准的window.onload事件:

// for other browsers

window.onload = init;

还有一个问题(谁说这很容易?)。因为我们正在为其余的浏览器捕获onload事件,所以我们将为IE和Mozilla两次调用init函数。为了解决这个问题,我们应该标记该函数,使其只执行一次。所以我们的init方法看起来像这样:

function init() {
  // quit if this function has already been called
  if (arguments.callee.done) return;

  // flag this function so we don't do the same thing twice
  arguments.callee.done = true;

  // do stuff
};

我提供了展示此技术的sample page

答案 1 :(得分:0)

由于实际答案在我的评论中,我将其添加到我的答案中:

我的猜测是,您正在执行window.onload = init();而不是window.onload = init;之类的操作,并且必须在执行该任务之前声明init函数。您在没有parens的情况下分配函数引用。使用parens使它立即执行。


您说您正在使用此代码:

 docScrollWidth = document.getElementsByTagName('body')[0].style.width 

这个问题的主要问题是style.width只能读取直接在body对象上设置的样式属性。它没有得到布局或CSS规则计算的对象宽度。


那么,你应该使用什么取决于你正在尝试做什么。除非您的内容是完全固定的宽度,否则主体宽度几乎总是与窗口宽度相同或更大。那么,这让我想知道你在这里想要完成什么?你应该使用什么取决于你真正想要做的事情。


仅供参考,document.body是对身体对象的直接引用,因此您不需要document.getElementsByTagName('body')[0]