Javascript Node Issue

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • ziycon
    Contributor
    • Sep 2008
    • 384

    Javascript Node Issue

    I have this code that doesn't work in FF due to a bug with the firstchild bit:
    Code:
    var opts = obj.childNodes;
      
    var li = document.createElement('li');
    var txt = document.createTextNode(opts[0].firstChild.firstChild.nodeValue);
    And I want to replace it with the below, but I'm not sure how or what I pass to the function?
    Code:
    var opts = obj.childNodes;
      
    var li = document.createElement('li');
    var txt = document.createTextNode(opts[0].getFirstChild().getFirstChild().nodeValue);
    Code:
    function getFirstChild(elm){
        if ( !elm.childNodes.length ){
            return;
        }
        var children = elm.childNodes.length;
        for ( var i = 0; i <= children; ++i ){
            if ( elm.childNodes[i].nodeType == 1 ){
                return elm.childNodes[i];
            }
        }
        return;
    }
  • Dormilich
    Recognized Expert Expert
    • Aug 2008
    • 8694

    #2
    I have this code that doesn't work in FF due to a bug with the firstchild bit
    that’s not a bug, that’s standard compliant behaviour that IE gets wrong.

    you can use .firstElementCh ild* in FF instead.
    Code:
    try {
        return elem.firstElementChild; // FF
    } catch (e) {
        return elem.firstChild; // IE
    }
    you could even use elem.getElement sByTagName("*")[0], so you may not use method chaining on it as well.

    one more thing to note: your getFirstChild() .nodeValue will either return null or undefined. an HTMLElement by default has no nodeValue (by definition), you would need .textContent/.innerText for that.


    * - part of DOM-4-Core
    Last edited by Dormilich; Nov 3 '10, 12:47 PM.

    Comment

    • ziycon
      Contributor
      • Sep 2008
      • 384

      #3
      So if I was to keep its like this:
      Code:
      var opts = obj.childNodes;
        
      var li = document.createElement('li');
      var txt = document.createTextNode(opts[0].firstChild.firstChild.nodeValue);
      All I need to do is:
      Code:
      var opts = obj.childNodes;
        
      var li = document.createElement('li');
      try {
         var txt = document.createTextNode(opts[0].firstElementChild.firstElementChild.nodeValue);
      catch (e) {
         var txt = document.createTextNode(opts[0].firstChild.firstChild.nodeValue);
      }

      Comment

      • Dormilich
        Recognized Expert Expert
        • Aug 2008
        • 8694

        #4
        .firstElementCh ild.nodeValue is always null, see edited post above for an explanation why.

        Comment

        • ziycon
          Contributor
          • Sep 2008
          • 384

          #5
          I've tried the below two, maybe I'm misinterpreting what you said!? Neither worked in IE or FF.
          Code:
          var txt = document.createTextNode(opts[0].firstChild.firstChild.innerText);
          Code:
          var txt = document.createTextNode(opts[0].firstChild.firstChild.textContent);

          Comment

          • Dormilich
            Recognized Expert Expert
            • Aug 2008
            • 8694

            #6
            innerText is for IE only.

            what exactly is opts[0]? (I have an idea, but I’m not sure)

            Comment

            • ziycon
              Contributor
              • Sep 2008
              • 384

              #7
              Here is the whole function as it currently is.

              Code:
              function selectReplacement(obj) {
                document.getElementById('list').style.display= "none";
                var ul = document.createElement('ul');
                ul.className = 'singleList';
                  
                var opts = obj.childNodes;
                
                var li = document.createElement('li');
                var txt = document.createTextNode(opts[0].firstChild.firstChild.nodeValue);
              
                li.appendChild(txt);
                
                li.onclick = function() {
              	  if(document.getElementById('list').style.display=="block"){document.getElementById('list').style.display="none";}
              	  else {document.getElementById('list').style.display="block";}
                }
                
                ul.appendChild(li);
                obj.parentNode.insertBefore(ul,obj);
              }

              Comment

              • Dormilich
                Recognized Expert Expert
                • Aug 2008
                • 8694

                #8
                what type of element is obj?

                Comment

                • ziycon
                  Contributor
                  • Sep 2008
                  • 384

                  #9
                  Sorry, this is where its called from.
                  Code:
                  function setForm() {
                    var s = document.getElementById('list');
                    if(s = document.getElementById('list')){selectReplacement(s);}
                  }
                  Taken from here.
                  Code:
                  <ul style="display: none;" id="list" class="selectReplacement">
                    <li>text 1</li>
                    <li>text 2</li>
                  </ul>

                  Comment

                  • Dormilich
                    Recognized Expert Expert
                    • Aug 2008
                    • 8694

                    #10
                    then it would be obj.firstElemen tChild.textCont ent for FF (obj = <ul>, obj.firstElemen tChild = <li>)
                    Last edited by Dormilich; Nov 3 '10, 02:03 PM.

                    Comment

                    • ziycon
                      Contributor
                      • Sep 2008
                      • 384

                      #11
                      I'm using this code and it works grand in IE but FF gives the below error!?

                      Code:
                      try {
                          var txt = obj.firstElementChild.firstElementChild.textContent;
                        } catch (e) {
                          var txt = document.createTextNode(opts[0].firstChild.firstChild.nodeValue);
                        }
                      Error: uncaught exception: [Exception... "Could not convert JavaScript argument arg 0 [nsIDOMHTMLLIEle ment.appendChil d]" nsresult: "0x80570009 (NS_ERROR_XPC_B AD_CONVERT_JS)" location: "JS frame :: main.js :: selectReplaceme nt :: line 78" data: no]

                      Comment

                      • Dormilich
                        Recognized Expert Expert
                        • Aug 2008
                        • 8694

                        #12
                        that’s simple, .appendChild() requires a Node as input, not a String.

                        Comment

                        • ziycon
                          Contributor
                          • Sep 2008
                          • 384

                          #13
                          So instead of:
                          Code:
                          li.appendChild(txt);
                          I tried:
                          Code:
                          li.appendChild(opts[0]);
                          Code:
                          li.appendChild(obj.firstElementChild.firstElementChild.textContent);
                          It didn't work though, what I'm trying to do is add the text from the first LI to to the li.appendChild code, any ideas where I'm going wrong?

                          Comment

                          • Dormilich
                            Recognized Expert Expert
                            • Aug 2008
                            • 8694

                            #14
                            any ideas where I'm going wrong?
                            yes. you still try to use a String instead of a text node.

                            be it IE, FF or any other browser, a text node is created by document.create TextNode("the text content");

                            Comment

                            • ziycon
                              Contributor
                              • Sep 2008
                              • 384

                              #15
                              All working now, thank you so much for all your help, much appreciated. I've learned a lot with regards to nodes in JS.

                              Comment

                              Working...