1

I'm currently reading Learning PHP, MySQL & JavaScript With jQuery, CSS & HTML5 4th edition by Robin Nixon.

I'm doing a JavaScript example involving adding an element to the DOM after acknowledgement of the alert dialog and then removing it upon another acknowledgement.

However, the page doesn't load properly in Chrome. The page continues to "load" while the alert is up. Saying it will add the object and while the alert is up saying it will remove the object but the text that should be there the whole time is not loaded until after the second alert box is closed.

The added element itself never loads at all in Chrome. Yet, the page works exactly has intended in both Edge and Firefox. Is there a setting in Chrome I need to adjust to allow the page to load properly or is this just how Chrome is currently designed to work?

The code in question is below as follows

        <!DOCTYPE html>
        <html>
            <head>
                <title>Adding Elements</title>
                <script src='OSC.js'></script>
            </head>
            <body>
                This is a document with only this text in it.<br><br>

                <script type="text/javascript">
                    alert('Click OK to add an element')

                    newdiv = document.createElement('div')
                    newdiv.id = 'NewDiv'
                    document.body.appendChild(newdiv)

                    S(newdiv).border = 'solid 1px red'
                    S(newdiv).width = '100px'
                    S(newdiv).height = '100px'
                    newdiv.innerHTML = "I'm a new object inserted in the DOM"
                    tmp = newdiv.offsetTop

                    alert('Click OK to remove the element')
                    pnode = newdiv.parentNode
                    pnode.removeChild(newdiv)
                    tmp = pnode.offsetTop

                    function O(i) { return typeof i == 'object' ? i : 
                   document.getElementById(i) }

                   function S(i) { return O(i).style }
                   function C(i) { return document.getElementsByClassName(i) }
                </script> 
            </body>
        </html> 

Thank you for your help!

edit: There are 3 functions O, S, and C in the OSC.js file but I don't think they are the cause of any of the problems. I will post them below. Also added them to the snippet directly just so the code will work here. They are not in my actual code.

    function O(i) { return typeof i == 'object' ? i : 
    document.getElementById(i) }

    function S(i) { return O(i).style }
    function C(i) { return document.getElementsByClassName(i) }
Graham P Heath
  • 7,009
  • 3
  • 31
  • 45
blynch
  • 13
  • 4

1 Answers1

1

Browsers handle the rendering of styling differently. TLDR is that Chrome hasn't rendered the element yet, but it has added it to the DOM. There are lots of good articles about how the render cycle works, but since this is coming from a beginners perspective, I'll leave the gory details out.

I did a couple of things, first, I moved your scripts from OSC.js into the head, so they'd be loaded the same as if the script had loaded correctly. JavaScript can hoist functions so this was probably just maintanence and explains why the code worked else where.

After that I added a debugger right before the second alert so that we could interact with the page before the alert fired.

To play along, open Chrome's developer console on this page and run the snippet. There will be screenshots if you don't want to.

You can now see and even interact with the NewDom element, in the dom, but not yet painted in a few ways.

First, just log it out: console.log(newdiv), or document.querySelector('#NewDiv').

In your console you'll see the node, right click on it and "Scroll into view", then right click on it again and "Reveal in elements panel".

You should now see something like this: NewDiv in console and on the page.

What you won't see is equally important: the dom node has no text, nor border. Even if you add a class to the page, the styles from that class will not have rendered.

Then I added a step to the script where we re-add the Element, alert, and then wait for 10 seconds.

If you're playing a long, resume your debugger now.

The script will resume, it will remove the dom node, and repeat adding it, but this time wait 10 seconds. Scroll down now, and observe the NewDiv as originally promised. New div, on dom, not yet removed.

        <!DOCTYPE html>
        <html>
            <head>
                <title>Adding Elements</title>
                <script type="text/javascript">
                 function O(i) { return typeof i == 'object' ? i : 
                   document.getElementById(i) }

                   function S(i) { return O(i).style }
                   function C(i) { return document.getElementsByClassName(i) }
                </script>
            </head>
            <body>
                This is a document with only this text in it.<br><br>

                <script type="text/javascript">
                    alert('Click OK to add an element')

                    newdiv = document.createElement('div')
                    newdiv.id = 'NewDiv'
                    document.body.appendChild(newdiv)

                    S(newdiv).border = 'solid 1px red'
                    S(newdiv).width = '100px'
                    S(newdiv).height = '100px'
                    newdiv.innerHTML = "I'm a new object inserted in the DOM"
                    tmp = newdiv.offsetTop
                    debugger;
                    alert('Click OK to remove the element')
                    pnode = newdiv.parentNode
                    pnode.removeChild(newdiv)
                    tmp = pnode.offsetTop

                    alert('Click OK to re-add the element')
                    document.body.appendChild(newdiv)

                    setTimeout(() => {
                      alert('Click OK to remove the element')
                      pnode = newdiv.parentNode
                      pnode.removeChild(newdiv)
                      tmp = pnode.offsetTop
                    }, 10000)
                </script> 
            </body>
        </html> 
Graham P Heath
  • 7,009
  • 3
  • 31
  • 45
  • I tried this code with both chrome and safari and in both the div was fully painted. It had the text and border. – chetan Apr 26 '20 at 20:57