为什么在函数中用createElement创建的元素,函数结束后不能访问,为null,而在下一个函数中却能访问?

我在一个函数中用docment.createElement()方法创建一个元素后,在这个函数外便无法访问,用alert()来看,为null。但是我在下一个函数中又可以访问。
请问这个是为什么??
js部分:

//begin
function addLoadEvent(func){
    var oldonload=window.onload;
    if (typeof window.onload !="function"){
        window.onload=func;
    }
    else{
        window.onload=function(){
            oldonload();
            func();
        }
    }
}
function insertAfter(newElement, targetElement){
    var parent=targetElement.parentNode;
    if (parent.lastChild==targetElement){
        parent.appendChild(newElement);
    }
    else{
        parent.insertBefore(newElement, targetElement.nextSibling);
    }
}
function preparePlaceholder(){
    if (!document.createElement) return false;
    if (!document.createTextNode) return false;
    if (!document.getElementById) return false;
    if (!document.getElementsByTagName) return false;
    var placeholder=document.createElement("img");
    placeholder.setAttribute("id", "placeholder");
    placeholder.setAttribute("src", "image/placeholder.png");
    placeholder.setAttribute("alt", "my gallery");
    var description=document.createElement("p");
    description.setAttribute("id", "description");
    var text=document.createTextNode("Choose one");
    description.appendChild(text);
    var gallery=document.getElementById("imagegallery");
    insertAfter(placeholder, gallery);
    insertAfter(description, placeholder);
}
function prepareGallery(){
    if (!document.getElementsByTagName) return false;
    if (!document.getElementById) return false;
    if (!document.getElementById("imagegallery")) return false;
    var gallery=document.getElementById("imagegallery");
    var links=gallery.getElementsByTagName("a");
    for (var i = 0; i < links.length; i++) {
        links[i].onclick=function(){
            return showpic(this);
        }
    }
}
var des=document.getElementById("description");
alert(des);//这里的时候浏览器显示null;
function showpic(pic){
    if (!document.getElementById("placeholder")) return false;
    var source=pic.getAttribute("href");
    var plc=document.getElementById("placeholder");
    if (plc.nodeName!="IMG") return false;
    plc.setAttribute("src", source);
    var des=document.getElementById("description");
alert(des);//这里的时候浏览器显示 object;
    if (document.getElementById("description")){
        var text=pic.getAttribute("title") ? pic.getAttribute("title") : "";
        var description=document.getElementById("description");
        if (description.firstChild.nodeType==3){        
            description.firstChild.nodeValue=text;
        }
    }
    return false;
}
var des=document.getElementById("description");
alert(des);,
addLoadEvent(preparePlaceholder);
addLoadEvent(prepareGallery);

html部分:

 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>testP1</title>
    <link rel="stylesheet" href="sheet.css">
</head>
<body>
    <h1>Click To Change</h1>
    <ul id="imagegallery">
        <li>
            <a href="image/red.png" title="Red"><img src="image/red.png" alt="Red"></a>
        </li>
        <li>
            <a href="image/yellow.png"  title="Yellow"><img src="image/yellow.png" alt="Yellow"></a>
        </li>
        <li>
            <a href="image/green.png"  title="Green"><img src="image/green.png" alt="Green"></a>
        </li>
    </ul>
    <script src="gallery.js"></script>
</body>
</html>

谢谢各位了!!感激不尽。

阅读 3.6k
2 个回答

外层alert(des)执行的时候,你的创建元素的函数还没执行呢。
创建元素的函数是LoadEvent的回调函数。

addLoadEvent(preparePlaceholder);

走到这一行之前时,外部的alert已经执行,但是回调事件还没执行(不止没执行,都没创建事件监听)

就这么简单。你可以写个debugger或者多加几个console.log("各个函数的名字")看看执行顺序。


简化下你的程序

        function createEl() {
            var el = document.createElement("p");
            el.setAttribute("id", "description");
            document.body.appendChild(el);
            console.log('创建对象')
        }
        var des = document.getElementById("description");
        console.log('获取des')
        console.log(des,'输出des');
        window.onload = createEl;
        console.log('主js执行完毕');

你创建元素的时候,都已经获取过了,des指向null了,还怎么指向你创建的元素。
而且在浏览器端事件的回调函数是主js走完之后才可能被执行。
就是说createEl虽然在console.log()之前被声明了,但是执行是在console.log('主js执行完毕');这个语句执行之后,并且触发window.onload才会执行,还不明白就去搜js Event Loop

谢邀。楼上正解。你等整段代码应该是这个样子的。#description这个是由preparePlaceholder创建的。你不调用这个。他永远不会触发。js是单线程的,从上到下。

function addLoadEvent(func){}
function insertAfter(newElement, targetElement){}
function preparePlaceholder(){}
function prepareGallery(){}
function showpic(pic){}
var des = undefined;

des=document.getElementById("description");
alert(des);//这里的时候浏览器显示null;
des=document.getElementById("description");
alert(des);

addLoadEvent(preparePlaceholder);
addLoadEvent(prepareGallery);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题