搜索

首页  >  问答  >  正文

javascript - js代码放在body里能用,放head里就不能用了?

我把写在了单独的js文件中,并且用了window.onload=function(){}防止加载问题
1.直接从body里插入代码,能用;
2.从body里插入js文件,不能用;文件中删掉window.onload=function(){},能用;
3.写在head里,无论直接插入代码还是文件,都不能用;
4.控制台没报错且能在调试器中找到这个js文件。
觉得是页面加载出问题了,具体哪里的问题,说不上来。。。
贴上代码吧

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>图片库</title>
        <link rel="stylesheet" type="text/css" href="4.2图片库.css"/>
        <script src="4.2图片库.js" type="text/javascript" charset="utf-8"></script>
    </head>
    <body>
        <h1>我的图片库</h1>
        <a href="http://www.baidu.com" target="_blank">百度一下你就知道</a>
        <ul>
            <li>
                <a href="images/捕获0.png" title="截图一" class="pic">截图一</a>
            </li>
            <li>
                <a href="images/捕获1.png" title="截图二" class="pic">截图二</a>
            </li>
            <li>
                <a href="images/捕获2.png" title="截图三" class="pic">截图三</a>
            </li>
            <li>
                <a href="images/捕获3.png" title="截图四" class="pic">截图四</a>
            </li>
        </ul>
        <img src="images/示例图片.jpg"/ id="placeholder" alt="图片库封面">
        <p id="alt">封面:</p>
    </body>
</html>

js代码是这样的

window.onload=function(){
    function showPic(whichpic){
        var source=whichpic.getAttribute('href'); 
        var place_holder=document.getElementById('placeholder');                
        place_holder.src=source;
        var p=document.getElementById("alt");
        var text=whichpic.getAttribute('title');
        p.firstChild.nodeValue=text;
    }
    var lis=document.getElementsByTagName('a');
    for(i=0;i<lis.length;i++){
        if(lis[i].getAttribute('class')=='pic'){
//            lis[i].onclick=function(){
//                showPic(this);
//                return false;
//            }    
            lis[i].setAttribute('onclick','showPic(this);return false;');
        }
    }
}
伊谢尔伦伊谢尔伦2739 天前741

全部回复(5)我来回复

  • 曾经蜡笔没有小新

    曾经蜡笔没有小新2017-05-19 10:26:41

    首先提一个建议:关于文件命名最好不要夹杂中文,一般也不以数字开头,有很多命名规范自己可以找找看看。

    关于问题:
    控制台没报错且能在调试器中找到这个js文件:只要你使用了window.onload=function(){},js代码是肯定执行的,不论你是放在head里面还是body里面,也不论你是不是以文件的形式引入的,里面的代码都会执行。

    从body里插入js文件,不能用;文件中删掉window.onload=function(){},能用:html中的onclick="showPic(this)",这个showPic函数是定义在全局作用域下面的,不能用window.onload包裹,当你包裹的时候,showPic的作用域就处于onload这个函数里面了,在全局作用域下找不到showPic,所以点击时,showPic函数里面的代码没有执行,其他的js代码是执行的,你看看a标签里面已经添加上了onclick等代码。

    写在head里,无论直接插入代码还是文件,都不能用:涉及到dom查询,这个时候dom树还没构建完成,所以查询不到a标签。写在head里面的dom查询js代码要用window.onload包裹一下,但是你要把showPic这个函数提出来放在全局作用域下,这样才能正常运行。

    @张冬冬 回答的没毛病,但是他用的是element.onclick绑定事件的方法(你注释掉的代码),这个时候,在作用域链上是能找到showPic函数的,所以能执行。

    @stephenhuang 写在onload里面的showPic代码能运行?

    回复
    0
  • 迷茫

    迷茫2017-05-19 10:26:41

    script应该放在body下面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Blog</title>
        <link rel="stylesheet" type="text/css" href="4.2图片库.css"/>
    </head>
    <body>
        <p id="box">id</p>
         <script src="4.2图片库.js" type="text/javascript" charset="utf-8"></script>
    </body>
    </html>

    首先要了解到的是:

    html文件是自上而下的执行方式,但引入的css和javascript的顺序有所不同,css引入执行加载时,程序仍然往下执行,而执行到<script>脚本是则中断线程,待该script脚本执行结束之后程序才继续往下执行。

    所以,大部分网上讨论是将script脚本放在<body>之后,那样dom的生成就不会因为长时间执行script脚本而延迟阻塞,加快了页面的加载速度。

    但又不能将所有的script放在body之后,因为有一些页面的效果的实现,是需要预先动态的加载一些js脚本。所以这些脚本应该放在<body>之前。

    所以,我认为script放置位置的原则“页面效果实现类的js应该放在body之前,动作,交互,事件驱动的js都可以放在body之后”。

    回复
    0
  • 巴扎黑

    巴扎黑2017-05-19 10:26:41

    因为放在head里面,遇到js标签就去下载js了,dom渲染还没完成,这时js取不到dom元素。

    回复
    0
  • ringa_lee

    ringa_lee2017-05-19 10:26:41

    首先script是可以放在head里面的,而且有很多网站这样使用,比如页面打开就要判断是否是手机端还是pc端的js方法等等。
    其次,针对你这个问题,我稍微修改了一点,测试可以运行的啊。只改了js部分,html部分没动。

    window.onload=function(){

    function showPic(whichpic){
        var source=whichpic.getAttribute('href'); 
        var place_holder=document.getElementById('placeholder');                
        place_holder.src=source;
        var p=document.getElementById("alt");
        var text=whichpic.getAttribute('title');
        p.firstChild.nodeValue=text;
    }
    var lis=document.getElementsByTagName('a');
    for(i=0;i<lis.length;i++){
        if(lis[i].getAttribute('class')=='pic'){
            lis[i].onclick=function(event){
                showPic(this);
                event.preventDefault();
            }    
         
        }
    }

    }

    所以可能还是js代码写的不对。

    回复
    0
  • phpcn_u1582

    phpcn_u15822017-05-19 10:26:41

    太感谢了,这下终于明白是怎么回事了!建议很有用收下了。
    不小心写到答案区了,不过既然写了那就写点有用的吧,添加几行代码
    让lis[i].setAttribute('onclick','showPic(this);return false;');这样的写法也能起作用:

    addLoadEvent(pics)
    function addLoadEvent(func){
        var oldonload=window.onload;
        if(typeof window.onload!='function'){window.onload=func;}
        else{window.onload=function(){oldonload();func;}
        }
    }
    //上面这段代码为了使所有函数共享window.onload事件
    function pics(){
        var lis=document.getElementsByTagName('a');
            for(i=0;i<lis.length;i++){
            if(lis[i].getAttribute('class')=='pic'){
    //            lis[i].onclick=function(){
    //                showPic(this);
    //                return false;
    //            }    
                lis[i].setAttribute('onclick','showPic(this);return false;');
            }
        }
    }```
    
    主要就是最后一行代码的问题(this指代不明,楼上大神解释得很棒),其实只要换成被注释掉的那一段或者楼上改的那一段就行了。如果坚持不换,把window.onload事件换成上文第一段函数也能行。
    

    回复
    0
  • 取消回复