【问题标题】:Loading elements with javascript then applying them javascript使用 javascript 加载元素然后应用它们 javascript
【发布时间】:2014-12-14 11:34:02
【问题描述】:

我正在尝试使用 jquery .load("file") 函数加载“header.html”,将 css 应用于加载的元素(作品),然后将 JS 应用于加载的元素,滚动浮动菜单等功能,但这不起作用。这是我在头部导入文件的顺序:

<!-- Elements going to be loaded are using this font-awesome css
so they must be loaded before anything -->
<link rel="stylesheet" href="awesome/css/font-awesome.min.css" />

<!-- Then importing the jquery -->
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>

<!-- This is the point where i load the header.html -->
<script src="js/indexLoad.js"></script>

<!-- Then apply css to the loaded elements (works) -->
<link rel="stylesheet" href="css/index.css" />

<!-- Then apply JS to the loaded elements (doesnt work) -->
<script src="js/index.js"></script>

在 header.html 中,我导入了一些元素,例如 nav
然后将样式更改为nav 以将其显示为红色。
当我在index.js 中使用var newHeight = $("nav").position().top 时,我只得到cannot read property value of null... 为什么css 将样式应用于加载的元素而JS 却无法获取它们?

我在两个 .js 文件中都正确使用了$(document).ready( function(){}

indexLoad.js

$(document).ready( function(){
    $("header").load("http://localhost/js/header.html");
});

index.js

$(document).ready( function(){
var newHeight = $("nav").position().top;
});

【问题讨论】:

标签: javascript jquery html css


【解决方案1】:

总是首先加载所有 CSS 文件,然后加载 JS 脚本。总是。

并且所有访问 DOM 元素的 JS 都需要在 DOM 准备好之后加载。通过使用其中一个处理程序(如 $(document).ready)或简单地将脚本放在 HTML 正文的最后。 (不确定你是否对所有脚本都这样做,你可能是)

由于您使用 AJAX 调用来加载标头,因此您需要等待它加载,以便 nav 元素可供 JS 使用。因此,使用load() 回调函数来执行所有操作标头标记的操作。


关键内容:由于您分别加载 index.js 和 indexLoad.js,因此您实际上需要在它们之间进行某种协调。我建议在 index.js 文件中设置一个事件侦听器,并在标头准备好后在 indexLoad.js 中触发该事件(在load() 回调中)。像这样的:

indexLoad.js

$(document).ready( function(){
    $("header").load("http://localhost/js/header.html", function() {
        $('body').trigger('headerReady');
    });
});

index.js

$('body').on('headerReady', function(){
    var newHeight = $("nav").position().top;
    // everything else that requires header elements goes here
    // or under a similar listener
});

这是一个简单的snipper,它使用超时来模拟异步调用延迟:

setTimeout(function(){
  $('body').append('<nav>Nav here</nav>');
  $('body').trigger('headerReady'); // simulating a 3s delay
  }, 3000);

$('body').on('headerReady', function() {
  alert('header is ready');
  $('nav').css('color', 'green');
  })
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"&gt;&lt;/script&gt;

【讨论】:

  • 很好的解释,谢谢,它现在可以正常工作了:D
【解决方案2】:

JS 是异步的,因此即使在页面下方进行newHeight 测量,也不意味着它将在加载完成后执行/运行。相反,使用回调:

$(document).ready( function(){
    $("header").load("http://localhost/js/header.html", function() {
        var newHeight = $("nav").position().top;
    });
});

...或延迟对象:Using jQuery load with promises

【讨论】:

  • 问题是我不能使用这样的函数,它们只会“绑定”到那个文件。例如,如果其他功能取决于“导航”位置,我将无法使用它们。
  • 那么你的另一个选择是使用延迟对象。当 .done() 被传递时,运行依赖于 newHeight 的函数。请参阅我的答案中的链接。
猜你喜欢
  • 2017-11-16
  • 1970-01-01
  • 2020-02-06
  • 2014-04-02
  • 2011-03-05
  • 2015-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多