document.getElementById 返回空值

Isi*_*oan -3 html javascript

你好,我有这些 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>
Run Code Online (Sandbox Code Playgroud)

我希望在屏幕上显示三个按钮,然后单击隐藏两个 div 并仅显示一个。

button id="userButton" onclick ="showOnClick('layoutGroup1');">ECA </button
Run Code Online (Sandbox Code Playgroud)
button id="userButton" onclick ="showOnClick('layoutGroup1');">ECA </button
Run Code Online (Sandbox Code Playgroud)

上面是我使用的函数,尽管它给了我一个错误,即getElementByIDis null

Mak*_*yen 6

nullgetElementById()HTML 中的 for 元素获取

null您从调用中获取的特定问题getElementById()可能是由于您的 JavaScript 在页面的 HTML 完全加载之前运行而引起的(即元素在 DOM 中尚不存在,因此null)。然而,虽然这可能是问题所在,但我们无法知道这就是问题所在,因为您的问题没有向我们显示您的 HTML 和 JavaScript 之间的关系(即,它没有显示 JavaScript 是如何以及何时在页)。

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

//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.
});
Run Code Online (Sandbox Code Playgroud)

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

代码的其他方面

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

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

//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.
});
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)

更通用/可重用的代码:

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

<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>
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)

更紧凑的代码:

如果您正在寻求代码的简洁性,您可以执行类似以下的操作[注意:使用 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>
Run Code Online (Sandbox Code Playgroud)
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';
    })})
}
Run Code Online (Sandbox Code Playgroud)

上面的代码片段使用gavgrif 的回答中提供的 HTML 。