Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #21655 > unrolled thread

prob with js...

Started byUne Bévue <unbewusst.sein@fai.invalid>
First post2013-10-19 15:29 +0200
Last post2013-10-21 08:52 +0200
Articles 8 — 5 participants

Back to article view | Back to comp.lang.javascript


Contents

  prob with js... Une Bévue <unbewusst.sein@fai.invalid> - 2013-10-19 15:29 +0200
    Re: prob with js... Danny <dann90038@gmail.com> - 2013-10-19 13:02 -0700
      Re: prob with js... Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-10-19 23:45 +0200
        Re: prob with js... Une Bévue <unbewusst.sein@fai.invalid> - 2013-10-20 06:57 +0200
          Re: prob with js... JJ <duh@nah.meh> - 2013-10-20 17:41 +0700
            Re: prob with js... Une Bévue <unbewusst.sein@fai.invalid> - 2013-10-21 08:50 +0200
          Re: prob with js... dhtml <dhtmlkitchen@gmail.com> - 2013-10-20 05:25 -0700
            Re: prob with js... Une Bévue <unbewusst.sein@fai.invalid> - 2013-10-21 08:52 +0200

#21655 — prob with js...

FromUne Bévue <unbewusst.sein@fai.invalid>
Date2013-10-19 15:29 +0200
Subjectprob with js...
Message-ID<l3u1fg$lr7$1@shakotay.alphanet.ch>
I've found a workaround, however, I'd like to understand ;-)

I've a constructor :

function GrowlNotification(...){...}
which insert html in the page by (in short):
document.body.innerHTML+='<div id="growlnotifications" style="right: 
-312px;bottom:20px;">blahblahblah</div>';

I've named this added element :
this.growlnotifications=document.getElementById('growlnotifications');

After that i wanted to add a method to change inner text of this div :
this.setText=function(text){
   this.growlnotifications.innerHTML=text;
}

this never works correctly (without any warning), i got always 
"blahblahblah", my workaround is to get back to "document.getElementById" :

this.setText=function(text){
   document.getElementById('growlnotifications').innerHTML=text;
}


why such a behaviour ?

[toc] | [next] | [standalone]


#21657

FromDanny <dann90038@gmail.com>
Date2013-10-19 13:02 -0700
Message-ID<0cc5ab2c-9864-4ee8-8306-1d5eaf1e0849@googlegroups.com>
In reply to#21655
To Une Bévue

this one is the case why using innerHTML property is not very reliable for READS, only for WRITES, that is, if you inject or ADD the elements to the document by using .innerHTML, the WRITE, that is, the ADDITION goes fine, but if you try to read any of the elements, like retriving by using the ID or even crawling the document tree to it, won't work very well.

for instances in which you need to READ elements or access elements added to the document, do not use the .innerHTML property, instead use the DOM methods like .createElement() and .appendChild() and .createTextNode().  Long as the DOM methods may be, and often maybe even redundantly worded, they're very reliable when accessing or adding elements to the document.

[toc] | [prev] | [next] | [standalone]


#21658

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-10-19 23:45 +0200
Message-ID<4035931.IXUBZ7Uc5o@PointedEars.de>
In reply to#21657
Danny wrote:

> To Une Bévue

Will you *please* learn to quote?
 
> this one is the case why using innerHTML property is not very reliable for
> READS, only for WRITES, that is, if you inject or ADD the elements to the
> document by using .innerHTML, the WRITE, that is, the ADDITION goes fine,
> but if you try to read any of the elements, like retriving by using the ID
> or even crawling the document tree to it, won't work very well.

Nonsense.
 
> for instances in which you need to READ elements or access elements added
> to the document, do not use the .innerHTML property, instead use the DOM
> methods like .createElement() and .appendChild() and .createTextNode(). 

Nonsense.  The issue with the “innerHTML” is not unreliable read access; it 
is mostly proprietary subtree serialization.  But that has nothing to do 
with the fact that you can add elements with “+=”; it is just inefficient 
because previous siblings need to be serialized.

> Long as the DOM methods may be, and often maybe even redundantly worded,
> they're very reliable when accessing or adding elements to the document.

Very likely the issue here is the common one that the element with ID 
“growlnotifications” has not been parsed yet when

  this.growlnotifications = document.getElementById('growlnotifications');

is executed.  As a result, this.growlnotifications is assigned “null”, and
the assignment in

  this.setText = function (text) {
    this.growlnotifications.innerHTML = text;
  };

fails with something like

|> (null).answer = "42";
| TypeError: Cannot set property 'answer' of null

Therefore, your suggestion will not work.

  this.setText = function (text) {
    document.getElementById('growlnotifications').innerHTML=text;
  };

works because the element object reference is not retrieved before the 
setText() method is called, after the element has been parsed.  The solution 
is not to call the wrapper constructor before the element has been parsed; 
it should be called in the “load” event listener for the “body” element 
instead.

-- 
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

[toc] | [prev] | [next] | [standalone]


#21661

FromUne Bévue <unbewusst.sein@fai.invalid>
Date2013-10-20 06:57 +0200
Message-ID<l3vnsf$buv$1@shakotay.alphanet.ch>
In reply to#21658
Le 19/10/13 23:45, Thomas 'PointedEars' Lahn a écrit :
> Very likely the issue here is the common one that the element with ID
> “growlnotifications” has not been parsed yet when
>
>    this.growlnotifications = document.getElementById('growlnotifications');
>
> is executed.  As a result, this.growlnotifications is assigned “null”, and
> the assignment in
>
>    this.setText = function (text) {
>      this.growlnotifications.innerHTML = text;
>    };
>
> fails with something like
>
> |> (null).answer = "42";
> | TypeError: Cannot set property 'answer' of null
>
> Therefore, your suggestion will not work.
>
>    this.setText = function (text) {
>      document.getElementById('growlnotifications').innerHTML=text;
>    };
>
> works because the element object reference is not retrieved before the
> setText() method is called, after the element has been parsed.  The solution
> is not to call the wrapper constructor before the element has been parsed;
> it should be called in the “load” event listener for the “body” element
> instead.


fine, thanks, clear to me.
i have to add, i had exactly the "contrary" (excuse my poor english) of 
what you wrote.

the code (building a <select /> with a tenth of options) was, as a first 
step written like that :

myElement=document.getElementById('myElementID');
myElement.innerHTML='<select id="ListeElement" onchange="VerifListe();"> ';
for(...){
   myElement.innerHTML+='<option value="valeur n">Option n</option>';
}
myElement.innerHTML+='</select>';

this wasn't working (on Safari at least)
because the parse closed the opened <select> before adding any option.
on the web inspector i had something like :
<select id="ListeElement" onchange="VerifListe();"></select>
(ie. a select without any option)
and then :
<option value="valeur n">Option n</option>

i don't remember what does the parser with the final insert of 
'</select>' (closing tag).

I do have another issue with adding event listener, I'll open a new 
thread for that.

[toc] | [prev] | [next] | [standalone]


#21662

FromJJ <duh@nah.meh>
Date2013-10-20 17:41 +0700
Message-ID<4gk6h6rq5oiu$.1hd08ghqd7nv1$.dlg@40tude.net>
In reply to#21661
On Sun, 20 Oct 2013 06:57:50 +0200, Une Bévue wrote:
> the code (building a <select /> with a tenth of options) was, as a first 
> step written like that :
> 
> myElement=document.getElementById('myElementID');
> myElement.innerHTML='<select id="ListeElement" onchange="VerifListe();"> ';
> for(...){
>    myElement.innerHTML+='<option value="valeur n">Option n</option>';
> }
> myElement.innerHTML+='</select>';

Construct the HTML code in a string variable first, then when all is done,
assign the innerHTML from the variable.

[toc] | [prev] | [next] | [standalone]


#21671

FromUne Bévue <unbewusst.sein@fai.invalid>
Date2013-10-21 08:50 +0200
Message-ID<l42ir2$38h$2@shakotay.alphanet.ch>
In reply to#21662
Le 20/10/13 12:41, JJ a écrit :
> Construct the HTML code in a string variable first, then when all is done,
> assign the innerHTML from the variable.

yes, right, it's what I've done already ))

[toc] | [prev] | [next] | [standalone]


#21664

Fromdhtml <dhtmlkitchen@gmail.com>
Date2013-10-20 05:25 -0700
Message-ID<b5b2257c-d491-4963-8f95-b907c5c68652@googlegroups.com>
In reply to#21661
On Saturday, October 19, 2013 9:57:50 PM UTC-7, Une Bévue wrote:
> Le 19/10/13 23:45, Thomas 'PointedEars' Lahn a écrit :
> 
> > Very likely the issue here is the common one that the element with ID
> 
> > “growlnotifications” has not been parsed yet when
> 
> >
> 
> >    this.growlnotifications = document.getElementById('growlnotifications');
> 
> >
> 
> > is executed.  As a result, this.growlnotifications is assigned “null”, and
> 
> > the assignment in
> 
> >
> 
> >    this.setText = function (text) {
> 
> >      this.growlnotifications.innerHTML = text;
> 
> >    };
> 
> >
> 
> > fails with something like
> 
> >
> 
> > |> (null).answer = "42";
> 
> > | TypeError: Cannot set property 'answer' of null
> 
> >
> 
> > Therefore, your suggestion will not work.
> 
> >
> 
> >    this.setText = function (text) {
> 
> >      document.getElementById('growlnotifications').innerHTML=text;
> 
> >    };
> 
> >
> 
> > works because the element object reference is not retrieved before the
> 
> > setText() method is called, after the element has been parsed.  The solution
> 
> > is not to call the wrapper constructor before the element has been parsed;
> 
> > it should be called in the “load” event listener for the “body” element
> 
> > instead.
> 
> 
> 
> 
> 
> fine, thanks, clear to me.
> 
> i have to add, i had exactly the "contrary" (excuse my poor english) of 
> 
> what you wrote.
> 
> 
> 
> the code (building a <select /> with a tenth of options) was, as a first 
> 
> step written like that :
> 
> 
> 
> myElement=document.getElementById('myElementID');
> 
> myElement.innerHTML='<select id="ListeElement" onchange="VerifListe();"> ';
> 
> for(...){
> 
>    myElement.innerHTML+='<option value="valeur n">Option n</option>';
> 
> }
> 
> myElement.innerHTML+='</select>';
> 
> 
> 
> this wasn't working (on Safari at least)
> 
> because the parse closed the opened <select> before adding any option.
> 
> on the web inspector i had something like :
> 
> <select id="ListeElement" onchange="VerifListe();"></select>
> 
> (ie. a select without any option)
> 
> and then :
> 
> <option value="valeur n">Option n</option>
> 
> 
> 
> i don't remember what does the parser with the final insert of 
> 
> '</select>' (closing tag).
> 
In general: Build a string first then insert it. 

For SELECT: Do not use innerHTML. It is problematic in many versions of IE. 

Create the subtree first, then add it to the document. 

 s = document.createElement("select");
 o = document.createElement("option");
 s.appendChild(o);

 myElement.appendChild(s);

> 
> 
> I do have another issue with adding event listener, I'll open a new 
> 
I suggest using a more descriptive subject line indicating the problem.

[toc] | [prev] | [next] | [standalone]


#21672

FromUne Bévue <unbewusst.sein@fai.invalid>
Date2013-10-21 08:52 +0200
Message-ID<l42iuu$38h$3@shakotay.alphanet.ch>
In reply to#21664
Le 20/10/13 14:25, dhtml a écrit :
> In general: Build a string first then insert it.

yes right.

>
> For SELECT: Do not use innerHTML. It is problematic in many versions of IE.
>
> Create the subtree first, then add it to the document.
>
>   s = document.createElement("select");
>   o = document.createElement("option");
>   s.appendChild(o);
>
>   myElement.appendChild(s);

I've change my code using dom instead of innerHTML, this is more verbose :
59 lines with innerHTML
91 lines with dom.

May be I'm too leasy...

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web