缺少要隐藏或显示的HTML元素

时间:2017-09-14 23:49:54

标签: javascript html node.js

我已使用socket-ionodejs实施了聊天应用程序。该应用程序运行正常,但有时我会遇到问题以处理HTML内容,因为当我尝试$('#id').hide()$('#id').show()时没有任何反应,因为元素 id < / em>不可用。

如果我尝试刷新页面按 F5 ,有时它会起作用,因为在我尝试隐藏或显示它之前会渲染该元素。我在使用Google Developer工具进行调试时遇到了这种情况,但我不确定它是否真的是为什么&#34;。

我试图在互联网上找到DOM元素的生命周期,但我找不到能够澄清我想法的东西。

我试图在开发环境中重现这个问题,但我很快就遇到了问题:

<script>
    console.log('Creating socket');
    var socket = io();
    console.log('Socket created');
    socket.on('connected', function (data) {
        console.log('connected to server');
    }); 

    function timeout() {
        setTimeout(function() {console.log('sleeping')}, 5000);
    }

    $(document).ready(function(){
        timeout(); // is possible to stuck process on this point?
        console.log('Ready');
    });
</script>

无论我把socket.on('connected'..放在哪里,因为它总是在console.log('Ready')之后调用。基于此,我的 F5 刷新理论不正确,我觉得我在圈子里跑。

任何人都知道为什么HTML元素有时不存在?

而且,如果我在socket.on('anyevent, {})内使用$(document).ready(function(){},我是否可以保证只在页面完整呈现后处理该事件?

在现实世界中,我们所有的套接字事件都在$(document).ready(function(){}内,但仍然没有隐藏或显示某些html元素,因为它们不存在。

3 个答案:

答案 0 :(得分:1)

我不确定您的HTML和代码结构,但这听起来像是将事件侦听器绑定到动态添加的元素,但绑定时此元素不存在。

如果我的理解是正确的,你需要在一个元素上添加绑定,但是将操作基于新添加的元素,类似于:

   // Add event listener, bound to the dynamically added element
   $("button").on('click', $("#newElemId"), function(){
       // if element exists, toggle it
       if($("#newElemId").length){
           $("#newElemId").toggle();
       }else{
          console.log('element not present yet');
       }
   }); 

请参阅以下演示:

&#13;
&#13;
$(function(){

   // define function to add an element to the DOM
   var addElement = function(){
       var newElementAsObj = $(document.createElement('div'));
       // add an id for querying later
       newElementAsObj.attr('id', 'newElemId');
       // add some text (so it's visible)
       newElementAsObj.text('New Element');       
       $("#container").append(newElementAsObj);
       console.log('new element added!');
   }
   
   // add a new element after a few secs
   setTimeout( addElement, 5 * 1000); // time is in ms so 5*1000 = 5secs
     
   // Add event listener, bound to the dynamically added element
   $("button").on('click', $("#newElemId"), function(){
       if($("#newElemId").length){
           // if element exists, toggle it
           $("#newElemId").toggle();
       }else{
          console.log('element not present yet');
       }
   });   
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container">
<button>Toggle</button>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

首先,关于这个:

$(document).ready(function(){
    timeout(); // is possible to stuck process on this point?
    console.log('Ready');
});

不,这是不可能的。但你不需要在那里等待。您可以完全删除timeout功能。

您应该将socket.on('connected', function ...移到$(document).ready(...,因为在文档准备好之前您不想响应任何套接字事件。

<script>
    console.log('Creating socket');
    var socket = io(); // It's fine to do this before the document loads
    console.log('Socket created');

    $(document).ready(function(){
        socket.on('connected', function (data) {
            console.log('connected to server');
        });
        console.log('waiting for connection...');
    });
</script>

答案 2 :(得分:0)

JQuery文档描述了在整个页面(而不仅仅是DOM)准备就绪后,您可以使用$(window).on('load', function() {})来运行代码。你可能会尝试,如果仅仅你的DOM已经准备就绪,但你需要等待整个页面被加载。

https://learn.jquery.com/using-jquery-core/document-ready/

  

如果我尝试按F5刷新页面,有时它会起作用,因为在我尝试隐藏或显示它之前会渲染该元素。我在使用Google Developer工具进行调试时遇到了这种情况,但我不确定这是“真正的原因”。

您是否使用$().append()或类似动态创建该元素?如果是这样,请确保在尝试与其进行交互之前实际创建该元素。如果元素不是动态创建的,请确保与元素交互的代码位于$(document).ready$(window).on('load')回调中。

  

无论我在哪里放置socket.on('connected'..因为它总是在console.log('Ready')之后调用。基于此,我的F5刷新理论不正确我觉得我是在圈子里跑。

这是因为建立套接字连接比渲染DOM需要更多时间。通常最好尽快附加事件监听器,以免错过任何事件。如果仅在加载DOM后附加事件侦听器,则可能错过某些事件。但请注意,如果您在事件侦听器回调中操作DOM,那么您无法确定是否已加载DOM并且您的目标元素在那里,除非您在加载DOM后附加事件侦听器。所以我建议在加载DOM之后附加事件监听器。至少那些包含一些代码来修改DOM。

  

任何人都知道为什么有时候HTML元素不存在?

这可能的原因并不多。您的元素尚未加载或您的代码由于某种原因删除了它们。我建议将断点放在你创建元素的地方或以某种方式操纵它们,看看执行顺序是什么。

  

而且,如果我在$(document).ready(function(){}中使用socket.on('anyevent,{}),我是否可以保证只在页面完全呈现后处理该事件?< / p>

您可以保证在anyevent发生时以及DOM准备就绪时执行回调函数,也就是说,所有静态html元素都在那里。