document.getElementById返回null值

时间:2016-11-12 02:01:06

标签: javascript html

您好我有这些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并只显示一个。

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";
    }
 }

上面是我使用的功能,虽然它给我一个getElementByIDnull的错误。

3 个答案:

答案 0 :(得分:3)

null获取getElementById()以获取HTML

中的元素

null调用中获取getElementById()的具体问题可能是由于您的页面HTML完全加载之前运行的JavaScript(即DOM中不存在的元素)因此,null)。但是,虽然可能问题,但我们无法知道这是问题所在,因为您的问题没有向我们展示您的HTML与JavaScript之间的关系(即没有显示在页面中加载/运行JavaScript的方式和时间。)

在页面中的元素可用之前运行JavaScript的问题的解决方案是将JavaScript的执行延迟到page has loaded。有多种方法可以做到这一点。一种方法是在HTML底部放置<script>标记。但是,在页面加载之前延迟通常是通过将代码(或只是初始化代码)包装在一个函数中来完成的,该函数随后被指定为在{{的各个阶段触发的各种事件之一的监听器。 1}}准备好了。最常用的是<document>的{​​{3}}。您可以使用以下代码执行此操作:

<document>

该事件也可以//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. }); 访问。当多个脚本尝试这样做时,以这种方式访问​​它可能会导致问题,因为只有一个人可以使用此方法。因此,使用document.onready方法监听此事件或任何其他事件要好得多。

代码的其他方面

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

您可以使用vanilla JavaScript实现与gavgrif在其答案中显示的相同功能。

if
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>show()函数,因为它们可能会在其他地方重复使用。此外,通过处理多种类型的输入(此处大部分都不需要),以下内容使hide()更加健壮。

asArray()
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;
}

更紧凑的代码:

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

<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>
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';
    })})
}

以上代码段使用his answer中提供的HTML。

答案 1 :(得分:1)

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";
    }
}
#layoutGroup1, #layoutGroup2, #layoutGroup3{
    display: none;  
}
    <button id="userButton1" onclick ="showOnClick('layoutGroup1');">ECA </button>

<button id="userButton2" onclick ="showOnClick('layoutGroup2');">button 2 </button>

<button id="userButton3" onclick ="showOnClick('layoutGroup3');">button 3 </button>

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

这是您更正后的功能

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";
    }
}

if条件==表示将LH与RHS进行比较,而=中的display='block'作为赋值运算符,在右侧为对象赋值< / p>

答案 2 :(得分:1)

虽然你没有为这个问题指定jQuery - 但是有一个非常简单的jquery方法。让三个按钮各自具有与div相对应的值。然后在onclick事件中(并通过删除内联点击处理程序 - 更好的代码结构注意javascript与html的分离) - 你只需获得点击按钮的值,hide()所有div(使用公共类)然后使用其id显示()所需的一个。这也可以通过添加/删除一类隐藏(例如.hidden {display:none}来完成,并且可以使用vanilla javascript完成 - 但所有这些都是如果....注意我添加了一些文本到div2和3这样他们就可以看到他们各自的按钮点击切换。

另请注意,我并不是建议为这个函数加载整个jQuery库 - 对于这个小函数来说太重要了,但只是提供了一个允许小函数成为代码结构更大图片的一部分的操作。

$(document).ready(function(){
  $('.showDiv').click(function(){
    var element = $(this).val();
    $('.layoutGroups').hide();
    $('#layoutGroup'+element).show(); 
  })
})
<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>