document.getElementById返回空值 [英] document.getElementById returns null value

查看:82
本文介绍了document.getElementById返回空值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好我有这些div:

 < div id =layoutGroup1> 
< h2> UK Map< / h2>
< div div style =width:650px; height:700px; ID = MapDIV >< / DIV>
< div id =userUpdateDIV>< / div>
< div id =BarChartDIV>< / div>
< div id =divPack1>< / div>
< / div>
< div id =layoutGroup2>
< div id =tree>< / div>
< / div>
< div id =layoutGroup3>
< div id =map>< / div>
< / div>

我希望屏幕上有三个按钮,然后点击隐藏两个div并只显示一个。

 按钮ID =userButtononclick =showOnClick('layoutGroup1');> ; ECA< / button 



function showOnClick(element){
if(element =='layoutGroup1'){
document.getElementById('layoutGroup1')。style.display =='block';
document.getElementById('layoutGroup2')。style.display =='none';
document.getElementById('layoutGroup3')。style.display =='none';
} else if(element =='layoutGroup2'){
document.getElementById(layoutGroup1)。style.display =='none';
document.getElementById(layoutGroup2)。style.display =='block';
document.getElementById('layoutGroup3')。style.display =='none';
} else {
document.getElementById(layoutGroup3)。style.display ==block;
document.getElementById(layoutGroup1)。style.display ==none;
document.getElementById(layoutGroup2)。style.display ==none;




$ b $ p
$ b

以上是我使用的函数,虽然它给了我 getElementByID 的错误是 null

解决方案

getElementById()为HTML中的元素获取 null



从您的调用中获取 null 的具体问题为 getElementById()可能是由于您的页面的HTML被完全加载之前运行的JavaScript引起的(即元素不存在于DOM中,因此 null )。然而,虽然这很可能是问题,但我们不能知道问题是因为你的问题没有告诉我们你的HTML和你的JavaScript之间的关系(即它不会显示JavaScript在页面中的加载/运行方式和时间)。



在页面中的元素可用之前运行JavaScript的问题的解决方案是延迟执行JavaScript,直到页面加载。有多种方法可以做到这一点。一种方法是在HTML的底部添加< script> 标签。然而,延迟直到页面加载完成通常是通过将你的代码(或者只是你的初始化代码)包装在一个函数中来完成的,该函数然后被分配为在<$的各个阶段触发的各种事件之一的监听器c $ c>< document> 准备就绪。最常用的是< document> DOMContentLoaded 事件。你可以用下面的代码来做到这一点:

  //等待DOM初始化代码运行,直到DOM完全加载。这需要
//当想要访问HTML以后的元素而不是< script>时。
if(document.readyState ==='loading'){
document.addEventListener('DOMContentLoaded',afterLoaded);
} else {
// DOMContentLoaded事件已经被触发。只需运行代码即可。
afterLoaded();
}

afterLoaded(){
//您的初始化代码放在这里。这是从你的代码开始
//运行的地方,如果它想访问你的HTML文件放置在DOM中的元素。
//如果您想要访问JavaScript插入的DOM元素,您可能需要
//才能延迟更多,或者使用MutationObserver查看它们何时插入。
});

该事件也可以作为 document.onready 。以这种方式访问​​它会在多个脚本尝试这样做时导致问题,因为只有一个脚本可以使用此方法。因此,使用 addEventListener()方法来侦听此事件或任何其他事件会更好。



< h2>您代码的其他方面

他的回答中, gavgrif在代码结构方面提供了一些好处,包括通过使用JavaScript来添加事件侦听器,并通过首先设置所有字符串来消除字符串(如果语句)不可见,然后设置你想要看到的那个。在他的回答中,暗示你必须使用jQuery来考虑使用不同结构的问题。 jQuery提供了许多方便的功能。其最重要的功能之一是跨浏览器兼容性。但是,它还提供了大量的预定义方法,允许对常用特征进行简短语法访问,在大多数情况下,这些特征会隐式地遍历所有选定的元素。这一切都以85KiB的最小代码为代价。因此,如果您只做了几件事情,jQuery是不合适的。



您可以使用gavgrif在他的答案中使用vanilla JavaScript实现的相同功能。 b
$ b

document.addEventListener('DOMContentLoaded',function(){//等待添加事件侦听器,直到DOM是完全加载的,当需要访问比HTML< script> ;. ',showOnClick);});}); function showOnClick(event){var groupNumber = this.value; queryEll('。layoutGroups')。forEach(function(el){el.style.display ='none'}); document.querySelector('#layoutGroup'+ groupNumber).style.display ='block';} function queryAll(selector){return asArray(document.querySelectorAll(selector))} function asArray(obj){var newArr = []; newArr.push.apply(newArr,obj);返回newArr;}

< script src =https: aaaxax.com.hk ;< button class ='showDiv'value =2> 2< / button>< button class ='showDiv'value =3> 3< / button>< div class =layoutGroupsid = layoutGroup1 > < h2> UK Map< / h2> < div div style =width:650px; height:700px;id =MapDIV>< / div> < div id =userUpdateDIV>< / div> < div id =BarChartDIV>< / div> < div id =divPack1>< / div>< / div>< div class =layoutGroupsid =layoutGroup2> < div id =tree>树< / div>< / div>< div class =layoutGroupsid =layoutGroup3> < div id =map> Map< / div>< / div>

代码更具通用性/可重用性:

通常,我更喜欢使用通用 show() hide()函数,因为它们可能在其他地方被重用。此外,通过处理多种类型的输入(其中大部分不需要),以下内容使得 asArray()更加健壮。



。当需要访问比<< script> ;. HTML中的元素稍后要访问的元素时,需要这个// queryAll('。showDiv')。forEach(function(el){el.addEventListener('click',showOnClick)} );}); function showOnClick(event){var groupNumber = this.value;隐藏(queryAll( layoutGroups。)); showDisplay(arraylikeOrElement,'none')} function show(arraylikeOrElement){setDisplay(arraylikeOrElement,'block')} function setDisplay(arraylikeOrElement,text ){setAStyle(arraylikeOrElement,'display',text);} function setAStyle(arraylikeOrElement,which,text){asArray(arraylikeOrElement).forEach(function(el){el.style [which] = text;});} function queryAll(selector){//返回文档中的所有匹配返回asArray(document.querySelectorAll(selector));} function queryDoc(selector){//仅返回文档中的第一个匹配(对ID有用)。这比querySelectorAll快,因为它不搜索整个DOM。它在第一场比赛后停止。返回document.querySelector(选择器);}函数asArray(obj){//接受数组,像数组的对象(例如NodeLists),单个元素,原语//返回一个数组,即使数组只有一个条目var newArr = []; if(typeof obj!=='object'|| obj instanceof Node){return [obj]; } if(Array.isArray(obj)){return obj; } if(obj === null){return null; } if(typeof obj.length ==='number'){// NodeList和其他类似数组的对象:在大多数浏览器中更快,并且比Array.from()更加兼容。 newArr.push.apply(newArr,obj);返回newArr; } if(typeof obj.nextNode ==='function'){//例如, TreeWalkers,NodeIterator var currentNode; while(currentNode = nodeIter.nextNode()){newArr.push(currentNode); } return newArr; } if(typeof Array.from ==='function'){return Array.from(obj); } //可以使这更复杂来处理更多类型的对象,但不能在//这个演示代码中。 //表明我们不知道如何处理Object return null;}

 < script src =https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js>< / script><按钮类='showDiv'value =1> 1< / button>< button class ='showDiv'value =2> 2< / button>< button class ='showDiv'value =3> ; 3< / button>< div class =layoutGroupsid =layoutGroup1> < h2> UK Map< / h2> < div div style =width:650px; height:700px;id =MapDIV>< / div> < div id =userUpdateDIV>< / div> < div id =BarChartDIV>< / div> < div id =divPack1>< / div>< / div>< div class =layoutGroupsid =layoutGroup2> < div id =tree>树< / div>< / div>< div class =layoutGroupsid =layoutGroup3> < div id =map> Map< / div>< / div>  

更简洁的代码:

如果您正在寻找简洁的代码,可以执行如下操作[注意:使用ES6语法可以进一步减少使用的字符数。]:

  var d = document,q = function(s){return Array.prototype.slice.call(d.querySelectorAll(s))}; d.onready = function(){//使用document.ready不是一个好主意,使用addEventListener。 forEach(function(e){e.addEventListener('click',function(){var element = this.value; q('。layoutGroups')。forEach(function(e){e .style.display ='none'}); q('#layoutGroup'+ element)[0] .style.display ='block';})})}  

< script src =https://ajax.googleapis.com/ajax/libs/jquery/2.1.1>

 

以上代码片段使用 gavgrif的答案中提供的HTML。


Hello I have these divs:

<div id="layoutGroup1">
    <h2>UK Map</h2>
    <div div style="width: 650px; height: 700px;" id="MapDIV"></div>
    <div id="userUpdateDIV"></div>
    <div id="BarChartDIV"></div>
    <div id="divPack1"></div>
</div>
<div id="layoutGroup2">
    <div id="tree"></div>
</div>
<div id="layoutGroup3">
    <div id="map"></div>
</div>

I want by having three buttons on the screen and clicking to hide the two divs and display only one.

button id="userButton" onclick ="showOnClick('layoutGroup1');">ECA </button

function showOnClick(element) {
    if (element == 'layoutGroup1') {
        document.getElementById('layoutGroup1').style.display == 'block';
        document.getElementById('layoutGroup2').style.display == 'none';
        document.getElementById('layoutGroup3').style.display == 'none';
    } else if (element == 'layoutGroup2') {
        document.getElementById("layoutGroup1").style.display == 'none';
        document.getElementById("layoutGroup2").style.display == 'block';
        document.getElementById('layoutGroup3').style.display == 'none';
    } else {
        document.getElementById("layoutGroup3").style.display == "block";
        document.getElementById("layoutGroup1").style.display == "none";
        document.getElementById("layoutGroup2").style.display == "none";
    }
 }

Above is the function I use, although it gives me an error that the getElementByID is null.

解决方案

Getting null from getElementById() for elements in your HTML

Your specific problem of getting null from your calls to getElementById() is probably caused by your JavaScript running prior to the HTML of your page being fully loaded (i.e. the elements don't exist in the DOM yet, thus null). However, while that is likely the problem, the we can not know that is the problem because your question does not show us the relationship between your HTML and your JavaScript (i.e. it does not show how and when the JavaScript is loaded/run in the page).

The solution to the problem of JavaScript running prior to the elements in the page being available is to delay the execution of your JavaScript until the page has loaded. There are multiple ways to do this. One is to just have your <script> tags at the bottom of your HTML. However, delaying until the page has loaded is usually accomplished by wrapping your code (or just your initialization code) in a function which is then assigned as a listener for one of the variety of events which are triggered at the various stages of the <document> being ready. The most common to use is the <document>'s DOMContentLoaded event. You can do this with the following code:

//Wait to run your initialization code until the DOM is fully loaded. This is needed
// when wanting to access elements that are later in the HTML than the <script>.
if(document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', afterLoaded);
} else {
    //The DOMContentLoaded event has already fired. Just run the code.
    afterLoaded();
}

afterLoaded() {
    //Your initialization code goes here. This is from where your code should start
    //  running if it wants to access elements placed in the DOM by your HTML files.
    //  If you are wanting to access DOM elements inserted by JavaScript, you may need
    //  to delay more, or use a MutationObserver to see when they are inserted.
});

That event can also be accessed as document.onready. Accessing it this way can cause problems when multiple scripts try to do so, as only one can use this method. Thus, it is much better to use the addEventListener() method to listen for this, or any other, event.

Other aspects of your code

In his answer, gavgrif makes some good points regarding the structure of your code including separating your HTML from your JavaScript by using JavaScript to add your event listeners and eliminating the string of if statements by first setting all to be not visible, then set the one you want to be visible. In his answer, it is implied that you have to use jQuery to think about the problem using a different structure. jQuery provides many convenient features. One of its most important feature is cross browser compatibility. However, it also provides a large number of predefined methods which allow short syntax access to commonly used features, which, in most cases, implicitly iterate over all elements which are selected. This all comes at the cost of 85KiB of minimized code. Thus, jQuery is inappropriate if you are only doing a few things.

You can implement the same functionality that gavgrif showed in his answer using vanilla JavaScript.

document.addEventListener('DOMContentLoaded', function(){
    //Wait to add event listeners until the DOM is fully loaded. This is needed
    // when wanting to access elements that are later in the HTML than the <script>.
    queryAll('.showDiv').forEach(function(el){
        el.addEventListener('click',showOnClick);
    });
});

function showOnClick(event){
    var groupNumber=this.value;
    queryAll('.layoutGroups').forEach(function(el){
        el.style.display='none'
    });
    document.querySelector('#layoutGroup'+groupNumber).style.display='block';
}

function queryAll(selector){
    return asArray(document.querySelectorAll(selector))
}

function asArray(obj){
    var newArr = [];
    newArr.push.apply(newArr, obj);
    return newArr;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class='showDiv' value="1">1</button>
<button class='showDiv' value="2">2</button>
<button class='showDiv' value="3">3</button>

<div class="layoutGroups" id="layoutGroup1">
  <h2>UK Map</h2>
  <div div style="width: 650px; height: 700px;"id = "MapDIV"></div>
  <div id="userUpdateDIV"></div>
  <div id = "BarChartDIV"></div>
  <div id="divPack1"></div>
</div>
<div class="layoutGroups" id="layoutGroup2">  
  <div id= "tree">Tree</div>
</div>
<div class="layoutGroups" id="layoutGroup3">
  <div id = "map">Map</div>
</div>

Code that is a bit more general purpose/reusable:

In general, I would prefer to have generic show() and hide() functions, as they might be re-used elsewhere. In addition, the following makes asArray() more robust by handing multiple types of input (most of which is not needed here).

document.addEventListener('DOMContentLoaded', function(){
    //Wait to add event listeners until the DOM is fully loaded. This is needed
    // when wanting to access elements that are later in the HTML than the <script>.
    queryAll('.showDiv').forEach(function(el) {
        el.addEventListener('click',showOnClick)
    });
});

function showOnClick(event){
    var groupNumber = this.value;
    hide(queryAll('.layoutGroups'));
    show(queryDoc('#layoutGroup'+groupNumber));
}

function hide(arraylikeOrElement) {
    setDisplay(arraylikeOrElement,'none')
}

function show(arraylikeOrElement) {
    setDisplay(arraylikeOrElement,'block')
}

function setDisplay(arraylikeOrElement,text) {
    setAStyle(arraylikeOrElement,'display',text);
}

function setAStyle(arraylikeOrElement,which,text) {
    asArray(arraylikeOrElement).forEach(function(el) {
        el.style[which]=text;
    });
}

function queryAll(selector){
    //Returns all matches in the document
    return asArray(document.querySelectorAll(selector));
}

function queryDoc(selector){
    //Returns only the first match in the document (useful for IDs). This is faster
    //  than querySelectorAll because it does not search the entire DOM.  It stops
    //  after the first match.
    return document.querySelector(selector);
}

function asArray(obj) {
    //accepts Arrays, array-like Objects (e.g. NodeLists), single elements, primitives
    //  returns an array, even if the array only has one entry
    var newArr = [];
    if(typeof obj !== 'object' || obj instanceof Node) {
        return [obj];
    }
    if(Array.isArray(obj)){
        return obj;
    }
    if(obj === null) {
        return null;
    }
    if(typeof obj.length === 'number') {
        //NodeList and other array-like objects: faster in most browsers and 
        //  more compatible than Array.from().
        newArr.push.apply(newArr, obj);
        return newArr;
    }
    if(typeof obj.nextNode === 'function') {
        //e.g. TreeWalkers, NodeIterator
        var currentNode;
        while(currentNode = nodeIter.nextNode()) {
            newArr.push(currentNode);
        }
        return newArr;
    }
    if(typeof Array.from === 'function') {
        return Array.from(obj);
    }
    //Could make this much more complex to handle more types of Objects, but not in
    //  this demo code.
    //Indicate that we don't know what to do with the Object
    return null;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class='showDiv' value="1">1</button>
<button class='showDiv' value="2">2</button>
<button class='showDiv' value="3">3</button>

<div class="layoutGroups" id="layoutGroup1">
  <h2>UK Map</h2>
  <div div style="width: 650px; height: 700px;"id = "MapDIV"></div>
  <div id="userUpdateDIV"></div>
  <div id = "BarChartDIV"></div>
  <div id="divPack1"></div>
</div>
<div class="layoutGroups" id="layoutGroup2">  
  <div id= "tree">Tree</div>
</div>
<div class="layoutGroups" id="layoutGroup3">
  <div id = "map">Map</div>
</div>

More compact code:

If you are looking for brevity of code, you could do something like the following [Note: Using ES6 syntax could further reduce the number of characters used.]:

var d=document,q=function(s){return Array.prototype.slice.call(d.querySelectorAll(s))};
d.onready=function(){ //Using document.ready is not a good idea, use addEventListener.
    q('.showDiv').forEach(function(e){e.addEventListener('click',function(){
        var element=this.value;
        q('.layoutGroups').forEach(function(e){e.style.display='none'});
        q('#layoutGroup'+element)[0].style.display='block';
    })})
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class='showDiv' value="1">1</button>
<button class='showDiv' value="2">2</button>
<button class='showDiv' value="3">3</button>

<div class="layoutGroups" id="layoutGroup1">
  <h2>UK Map</h2>
  <div div style="width: 650px; height: 700px;"id = "MapDIV"></div>
  <div id="userUpdateDIV"></div>
  <div id = "BarChartDIV"></div>
  <div id="divPack1"></div>
</div>
<div class="layoutGroups" id="layoutGroup2">  
  <div id= "tree">Tree</div>
</div>
<div class="layoutGroups" id="layoutGroup3">
  <div id = "map">Map</div>
</div>

The above code snippets use the HTML provided in gavgrif's answer.

这篇关于document.getElementById返回空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆