Browser Height in IE? NOT document height

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kepler

    Browser Height in IE? NOT document height

    How do you get the height of the client browser in IE? Both
    document.body.c lientHeight and document.body.o ffsetHeight return the
    height of the document. If the page is long and there's a vertical
    scrollbar, you get the height of the entire document, screwing up any
    chance of centering a window in the browser using these values.

    Is there a way to get the height of the actual browser window and not
    the entire page height?

    Thanks.
  • Yann-Erwan Perio

    #2
    Re: Browser Height in IE? NOT document height

    Kepler wrote:
    [color=blue]
    > How do you get the height of the client browser in IE? Both
    > document.body.c lientHeight and document.body.o ffsetHeight return the
    > height of the document.[/color]

    Hmm, in modern browsers (including IE) clientHeight does return the
    client height, and scrollHeight returns the whole document height.

    <URL:http://jibbering.com/faq/#FAQ4_9>

    What version of IE, and platform?


    <FAQENTRY>
    In 4_9 the variable redefinition in the different branchs is misleading,
    variable definitions occur once, when execution scopes are created,
    their initialization come later within the corresponding statement
    execution (Ecma-263-12.2).
    </FAQENTRY>

    Comment

    • Richard Cornford

      #3
      Re: Browser Height in IE? NOT document height

      Yann-Erwan Perio wrote:[color=blue][color=green]
      >> How do you get the height of the client browser in IE?
      >> Both document.body.c lientHeight and
      >> document.body.o ffsetHeight return the height of the
      >> document.[/color]
      >
      > Hmm, in modern browsers (including IE) clientHeight
      > does return the client height, and scrollHeight
      > returns the whole document height.
      >
      > <URL:http://jibbering.com/faq/#FAQ4_9>
      >
      > What version of IE, and platform?[/color]

      I am wondering whether there isn't a mismatch in terminology here, and
      it is the IE equivalents of outerWidth/Height that is wanted by the OP.
      [color=blue]
      > <F ... Y>
      > In 4_9 the variable redefinition in the different branchs
      > is misleading, variable definitions occur once, when
      > execution scopes are created, their initialization come
      > later within the corresponding statement execution
      > (Ecma-263-12.2).
      > </F ... Y>[/color]

      Yes, it is not syntactically incorrect but it is certainly misleading.

      Personally, I don't like the answer to 4.9 much anyway. Preferring the
      innerWidth/Height properties certainly simplifies the code considerably
      but they are not the equivalents of the clientWidth/Height properties on
      the root element in IE browsers as they represent dimensions that
      includes the thickness of the scroll bars (if present), while the
      'client' values return the dimensions inside the scroll bar.

      In most practical circumstances I have found that the dimensions inside
      the scroll bars are the dimensions that I would prefer to be using. If,
      for example, a page has a vertical scroll bar but no horizontal scroll
      bar (the common case in a fluid layout) I don't want to be positioning
      anything behind the vertical scroll bar because that is likely to
      introduce a horizontal scroll bar. And that horizontal scroll bar might
      flicker on an off if I am moving something that might partly slip behind
      the vertical scroll bar. So to control movement, or clip the offending
      elements appropriately, to the maximum extent possible, I need (want) to
      know the dimensions inside the scroll bars and only use
      innerWidth/Height when it is the only mechanism available.

      Unfortunately the very simple rules that apply to determining which
      element should be read to retrieve the viewport/visible client-region
      (inside any scroll bars) dimensions on IE browsers are not really
      applicable to any other DOM browsers (except by coincidence on some).
      You simply cannot apply the - document.compat Mode - test and be left
      with a reference to the correct object (Opera is a particular offender
      here). Logic that prefers to use the innerWidth/Height side-steps that
      problem, but preferring to use the correct clientWidth/Height properties
      brings you face to face with it.

      So the problem is that the clientWidth/Height dimensions reported by
      either of - document.body - and/or - document.docume ntElement - might be
      either the dimensions of the viewport/client-region (that are wanted) or
      they might be the client area of the document (which might be bigger
      than the viewport, or smaller). However, given a browser that also
      supports innerWidth/Height, some logic can be applied towards deciding
      which should be used. For example, the real viewport/client-region
      dimensions will never exceed the corresponding innerWidth/Height
      dimensions (only the document dimensions can do that, though they may
      not), and if a page is scrolled it is reasonable to assume that it has a
      scroll bar, which means that in that case the 'client' dimension inside
      the scroll bar must be smaller than the corresponding 'innner' value.

      The problem with this testing strategy is that you cannot always make a
      final decision as to which object is reporting the true 'client'
      dimensions as the result of one test. A provisional decision can be made
      and its result will be 'safe' (in that they will never be worse than the
      'inner' values). However, conditions might change. A page that was not
      scrolled might be scrolled, or the page might be re-sized, altering the
      'inner' values but not necessarily in the same way as the document
      dimensions. Those changes would allow the provisional decision to be
      reviewed and possibly a final decisions to be made at that point.

      This brings me to the progressively self re-configuring ("Russian doll")
      object/system that I said I would publish a few months back. That object
      was intended to address this particular problem. I still haven't had
      time to fully test it (at least to the extent that I would consider
      necessarily), it hasn't yet been shown to any Mac browsers, and I don't
      think Konqueror has seen this current version yet either. But here it is
      anyway:-


      /* The - getWindowState - function can be regarded a factory that
      returns a simple interface object, though that interface is in
      reality always a reference to the same object (a 'singleton
      class').

      var windowInterface = getWindowState( );

      NOTE: the first call to the - getWindowState - function should
      not happen until after the browser has passed the opening BODY
      tag (else the corresponding element will not be available in
      the DOM).

      Code is expected to retrieve a reference to the interface and
      store it locally for re-use.

      The interface has 4 methods that return pixel dimensions as
      numbers (or NaN if the browser does not support any mechanism
      for reading the corresponding information):-

      var clientWidth = windowInterface .getWidth();
      var clientHeight = windowInterface .getHeight();
      var verticalScroll = windowInterface .getScrollY();
      var horizontalScrol l = windowInterface .getScrollX();

      Wherever possible non-NaN returned values for width and height
      will be the vewport/client-region dimensions _not_ including
      the scroll bar thicknesses. They will always be equal to, or
      less than the innerWidth/Height values on browsers that support
      those properties.

      */
      function getWindowState( ){
      var global = this;
      var lastSt,lastSl,l astIW,lastIH,bo dyRank = null,docElRank = null;
      var twoTestCount = 0;
      /* When the system reports dimension and scroll values it is
      reading those values form one of a number of objects,
      depending on which the browser supports, and which seems
      to be providing the best information. When decisions are
      made about which object to read a reference to that abject
      is assigned to one of the following variables. The initial
      object assignments represent defaults and will result in
      the interface returning NaN values of the browser does not
      support any mechanism for reporting the relevant
      information:-
      */
      var readScroll = {scrollLeft:NaN ,scrollTop:NaN} ;
      var readSizeC = {clientWidth:Na N,clientHeight: NaN};
      var readSizeI = {innerWidth:NaN ,innerHeight:Na N};
      /* Default property names used when reading values form the
      object assigned to the - readScroll - variable. Their
      values are changed to - pageXOffset - and -pageYOffset -
      respectively whenever the global object is assigned to -
      readScroll -, which happens whenever it supports those
      properties as numeric values:-
      */
      var readScrollX = 'scrollLeft';
      var readScrollY = 'scrollTop';
      /* This object represents the interface to the scrolling and
      viewport/client-region dimensions. Calls to - getWindowState
      - always return a reference to this one object. Its methods
      are dynamically changed during the configuration of this
      system to provide the best information available in the
      shortest time possible:-
      */
      var theInterface = {
      getScrollX:getS crlXMain,
      getScrollY:getS crlYMain,
      getWidth:functi on(){return initWidthHeight ('getWidth');},
      getHeight:funct ion(){return initWidthHeight ('getHeight');}
      };
      /* When the system makes a provisional decision about which of
      - global -, - document.body - or - document.docume ntElement
      - it should be reporting dimensions from, but cannot entirely
      eliminate the other contenders, that provisional decision does
      not need to be reviewed until one of the criteria on which is
      was based is changed (as the code will draw the same conclusion
      otherwise). So these functions are used to monitor for changes
      in the scroll of the browser window and only re-examine the
      provisional decision if the window has changed scroll (as that
      may have altered the decisions making criteria in a way that
      allows a more final conclusion).

      The scroll values actually returned are not influenced by this
      testing, it is only done because it may allow the resolution of
      the viewpot/client-region dimension reporting issue:-
      */
      function getScrlXTest(){ hasChangedScrol l();return getScrlXMain(); }
      function getScrlYTest(){ hasChangedScrol l();return lastSl;}
      /* The following two functions are the final scroll position
      reporting functions. They read a value from the - readScroll -
      object. That object may be the NaN returning default (if no
      mechanism is available for reporting scroll positions on the
      current browser), It may have been assigned - document.body - or
      - document.docume ntElement -, or (and whenever - pageYOffset
      - and -pageXOffset - are available as numeric properties) a
      reference to the global object. The property names held in the
      variables - readScrollX - and - readScrollY - will be either
      scrollTop/Left or pageX/YOffset, depending on which object is
      being used to report the values.

      Once the viewport/client-region dimension reporting issues have
      been finalised these two functions are assigned as method of
      the interface. They are also the interface's default methods,
      only swapped for the testing method if the dimension reporting
      cannot be resolved at the first attempt:-
      */
      function getScrlXMain(){ return readScroll[readScrollX];}
      function getScrlYMain(){ return readScroll[readScrollY];}
      /* These two functions return the innerHeight/Width properties
      from the object referred to by - readSizeI -. That object is
      initially a NaN returning default but is replaced with a
      reference to the global object if that object is found to have
      numeric innerHeight/Width properties. In the event that this
      system decides that the innerHeight/Width properties of the
      global object are the most appropriate these two functions
      will be assigned to the - getWidth - and - getHeight - methods
      of the interface object. Otherwise they are employed in the
      decision making process to compare innerHeight/Width values
      with clientHeight/width values of the object being considered
      as the optimum candidate for returning browser window inner
      dimensions:-
      */
      function getWidthI(){ret urn readSizeI.inner Width;}
      function getHeightI(){re turn readSizeI.inner Height;}
      /* The - readSizeC - variable refers to one of - document.body -
      or - document.docume ntElement - (or the default), and these
      two method return clientWidth/Height values from that object.
      In the event that either the - body - or - documentElement -
      are settled upon as the best source for the
      viewport/client-region dimensions then these functions are
      assigned to the corresponding methods of the interface:-
      */
      function getWidthC(){ret urn readSizeC.clien tWidth;}
      function getHeightC(){re turn readSizeC.clien tHeight;}
      /* When the system makes a provisional decision about which of
      - global -, - document.body - or - document.docume ntElement
      - it should be reporting dimensions from, but cannot entirely
      eliminate the other contenders, that provisional decision does
      not need to be reviewed until one of the criteria on which is
      was based is changed (as the code will draw the same conclusion
      otherwise). So these functions are used to monitor for changes
      in the size of the browser window and only re-examine the
      provisional decision if the window has changed size (as that may
      have altered the decisions making criteria in a way that allows
      a more final conclusion):-
      */
      function getHeightSmart( ){
      return (hasChangedSize ()?theInterface .getHeight:getH eightC)();
      }
      function getWidthSmart() {
      return (hasChangedSize ()?theInterface .getWidth:getWi dthC)();
      }
      /* In the event that both - document.body - or -
      document.docume ntElement - can be eliminated from consideration
      (or are not available on the browsers (Net 4), the system
      resorts to using the innerHeight/Width functions for the
      interface methods (which may be returning default NaN values if
      they are also unsupported). This may happen in several places
      so the code that does the method swapping is wrapped in a single
      inner function:-
      */
      function setInnerWH(){
      theInterface.ge tWidth = getWidthI;
      theInterface.ge tHeight = getHeightI;
      }
      /* Whenever the client-region/viewport dimension reporting system
      is able to make its final decision changes in the scroll position
      of the window are not longer interesting and the interface
      methods
      that return scroll values can be swapped to the simplest and
      quickest versions available. This may happen in several places so
      the code that does the swapping is wrapped in a single inner
      function:-
      */
      function setMinimumScrol l(){
      theInterface.ge tScrollX = getScrlXMain;
      theInterface.ge tScrollY = getScrlYMain;
      }
      /* The next two functions check for changes in the dimensions of a
      window (as reported by innerHeight/width) or the scroll position
      of the window, and re-execute the viewport/client-region test
      function (as assigned to - threeObjectTest -) if those values
      have changed:-
      */
      function hasChangedSize( ){
      if(
      (lastIH != (lastIH = getHeightI()))| |
      (lastIW != (lastIW = getWidthI()))
      ){
      threeObjectTest ();
      return true;
      }
      return false;
      }
      function hasChangedScrol l(){
      if(
      (lastSl != (lastSl = getScrlYMain()) )||
      (lastSt != (lastSt = getScrlXMain()) )
      ){
      threeObjectTest ();
      }
      }
      /* The next function is the one that does the tests that decide
      whether one of - document.body - or - document.docume ntElement
      - can be eliminated form consideration as candidates for
      reporting the viewport/client-region dimensions, or it returns
      a value that is used to decide with of the two is providing the
      information most likely to be correct.

      The parameters are two objects: testObj - is one of -
      document.body - or document.docume ntElement - and - rankObj -
      is an object that holds information resulting form this test,
      or previous tests on the same - testObj - object.

      When this function returns NaN the corresponding - testObj -
      is eliminated from consideration as a candidate for
      viewport/client-region dimension reading. Otherwise the object
      with the _lowest_ - rank - value is used provisionally:-
      */
      function rankObj_inner(t estObj, rankObj){
      /* Variables that will hold vertical and horizontal differences
      between client and inner values:-
      */
      var dv,dh;
      /* If client dimensions exceed inner dimensions then this
      object cannot be reporting viewport/client-region
      dimensions. So values of either dv or dh that are less
      than zero result in this function returning NaN:-
      */
      if(
      ((dv = (global.innerHe ight - testObj.clientH eight)) >= 0)&&
      ((dh = (global.innerWi dth - testObj.clientW idth)) >= 0)&&

      /* If the page is scrolled - getScrlX/YMain() - will return
      a non-zero value. A scrolled page will have a
      corresponding scroll bar so a non-zero vertical scroll
      value implies a vertical scroll bar and so the - dh -
      value will be non-zero on an object reporting
      viewport/client-region dimensions. Similarly with
      horizontal scrolling. Objects are eliminated if a
      non-zero scroll value is not accompanied by a non-zero
      difference between inner and client values in the
      perpendicular axis:-
      */
      (!(getScrlXMain ()&&!dv))&&
      (!(getScrlYMain ()&&!dh))&&
      /* Non-zero values for - dh - and dv - will represent the
      thickness of the scroll bars. While scrollbar dimensions
      are user-configurable and OS dependent, it is unlikely
      that they will change while this script is running. The
      - rankObj - has - hDiff - and - vDiff - properties that
      are assigned non-zero values only once. If this is the
      second+ time that this object has been tested and it has
      non-zero dh/v values that are not identical to non-zero
      h/vDiff properties of the - rankObj - then those values
      are assumed to not represent scrollbar thickness and
      the - testObj - can be eliminated form consideration:-
      */
      (
      !(
      (
      dh&&(rankObj.hD iff||(rankObj.h Diff = dh))&&
      (dh != rankObj.hDiff)
      )||(
      dv&&(rankObj.vD iff||(rankObj.v Diff = dv))&&
      (dv != rankObj.vDiff)
      )
      )
      )
      ){
      /* If the - dv - and - dh - values are equal then either
      the browser is not displaying scroll bars at all or
      both the horizontal and vertical scroll bars are being
      displayed (or this object is not reporting the
      viewport/client-region dimensions and the values are
      pure coincidence):-
      */
      if(dh == dv){
      /* If both dh and dv are zero then the likelihood is
      very good that this object is reporting
      viewport/client-region dimensions (and if it is not
      then the values it is reporting can be used without
      trouble anyway), so a zero value is assigned to the
      - rank - property of - rankObj. If the differences
      are non-zero then the likelihood is that both scroll
      bars are showing and have the same dimensions.
      ***
      It is problematic to be assuming that vertical and
      horizontal scrollbars should have the same
      thickness, even though it appears to be true on all
      of the OSs and window managers examined to date
      (this assumption is a significant problem).
      ***
      However, this cannot give the same certainty as zero
      differences so the value of one is assigned.
      */
      rankObj.rank = Number(Boolean( dh));
      /* The assumption that scroll bars will be of the same
      thickens leads to the rule that if either is non-zero
      and dv and dh are not identical then the differences
      cannot represent scrollbars thicknesses and so the
      object cannot be reporting viewport/client-region
      dimensions:-
      */
      }else if((dh&&!dv)||( dv&&!dh)){
      /* When one of the values is zero the sum of the values
      will be the magnitude of the other. This value is
      assigned to the - rank - property of - rankObj -
      and the - testObj - with the smallest corresponding
      - rank - value will be provisionally preferred over
      the other:-
      */
      rankObj.rank = (dh+dv);
      }else{
      /* Otherwise NaN is returned and will result in -
      testObj - being eliminated form consideration as a
      candidate for reading the viewport/client-region
      dimensions:-
      */
      rankObj.rank = NaN;
      }
      }else{
      rankObj.rank = NaN;
      }
      return rankObj;
      }
      /* Provided with an object as its first parameter, and an
      indefinite number of following string arguments, this function
      returns true if all the string arguments represent numeric
      properties of the - testObj - object, and false otherwise.
      It is used to check whether various objects support relevant
      numeric properties before considering them as candidates for
      the reporting of the values of those properties:-
      */
      function propsAreNumbers (testObj){
      for(var c = arguments.lengt h;--c;){
      if(typeof testObj[arguments[c]] != 'number'){
      return false;
      }
      }
      return true;
      }
      /* Initially the following function wraps the preceding -
      rankObj_inner - function, testing that the - testObj -
      parameter supports the relevant properties. However, the -
      rankObj - identifier is assigned a reference to -
      rankObj_inner - after it has been called on each object of
      interest because if they support the relevant properties on
      the first call to - rankObj - they will still support the
      properties on any subsequent calls. There is no need to
      re-execute the code within this function:-
      */
      function rankObj(testObj , rankObj){
      if(
      testObj&&
      propsAreNumbers (testObj, 'clientWidth',' clientHeight')
      ){
      rankObj_inner(t estObj, rankObj)
      }
      return rankObj;
      }
      /* The default methods of the interface object uses functions that
      call this function as the default values of - getHeight - and -
      getWidth - but this function replaces those functions, with the
      effect that this function is only called once. It does the
      initial set-up for the testing that is used to determine which
      object the viewport/client-region dimensions should be read
      from. This strategy defers the configuration/set-up decisions
      until the first use of one of those methods:-
      */
      function initWidthHeight (callOn){
      lastIW = getWidthI();
      lastIH = getHeightI();
      lastSt = getScrlYMain();
      lastSl = getScrlXMain();
      /* The objects used to hold the decision making information
      that is used to decide between the use of - document.body
      - and - document.docume ntElement - have their initial -
      rank - property defaulted to NaN so that the corresponding
      object will be eliminated form consideration if it is either
      not implemented or does not support numeric
      clientheight/Width properties:-
      */
      bodyRank = {vDiff:0,hDiff: 0,rank:NaN};
      docElRank = {vDiff:0,hDiff: 0,rank:NaN};
      /* Replacing the dimension retrieval methods prevents this
      function from being re-called on subsequent uses of the
      interface methods. These replacement functions re-evaluate
      the decision making criteria whenever the browser window is
      innerHeight/Width values change:-
      */
      theInterface.ge tWidth = getWidthSmart;
      theInterface.ge tHeight = getHeightSmart;
      /* The scroll value reporting method are swapped for versions
      that test for changes in the scroll values as those changes
      allow an opportunity to re-evaluate the decision making
      criteria:-
      */
      theInterface.ge tScrollX = getScrlXTest;
      theInterface.ge tScrollY = getScrlYTest;
      /* The - threeObjectTest - function attempts to make the
      decision between reading the clientHeight/Width values form
      either the - document.body - or the -
      document.docume ntElement -, or the innnerHeight/Width
      properties from the global object:-
      */
      threeObjectTest ();
      /* The first use of - threeObjectTest - calls - rankObj -,
      which tests for the existence of - document.body - and -
      document.docume ntElement -. But if the objects are not
      available on the browser, or do not support the required
      properties they will be eliminated form future
      consideration. as a result it is unecessery to re-test
      their existence, and re-testing is avoided by swapping -
      rankObj - for the function that it calls to acquire the
      actual ranking values:-
      */
      rankObj = rankObj_inner;
      /* Having initialised the configuration process this function
      must return a value. It does this by calling whichever
      corresponding method has been assigned to the interface at
      this point:-
      */
      return theInterface[callOn]();
      }
      /* The strategy used to determine which object is to be used to
      report viewport/client-region dimensions is to generate a
      "ranking" for the body and the documentElement . If that ranking
      is NaN the object can immediately be removed form consideration.
      Otherwise the object with the _lowest_ ranking is used
      provisionally, and the tests repeated if the browser window is
      re-sized or scrolled (as that means that the decision making
      criteria have changed and it might have become possible to make
      a more final decision):-
      */
      function threeObjectTest (){
      /* Whichever function is currently assigned to - rankObj - is
      called and a boolean value set based on whether the - rank
      - property of the returned object (bodyRank or docElRank)
      is NaN:-
      */
      var bodyNaN = isNaN(rankObj(d ocument.body, bodyRank).rank) ;
      var docElNaN =
      isNaN(rankObj(d ocument.documen tElement, docElRank).rank );
      /* If either value is true (a - rank - was NaN) at least one of
      the objects can be removed from further consideration:-
      */
      if(bodyNaN||doc ElNaN){
      /* If both values were NaN then only reading the
      innerHeight/Width values of the global object is viable
      so the interface methods are re-assigned to functions
      that do that job directly an do no further testing:-
      */
      if(bodyNaN&&doc ElNaN){
      setMinimumScrol l();
      setInnerWH();
      /* Else only one object can be dropped from consideration
      (leaving that object and reading the innerHeight/Width
      from the global object as the only remaining options):-
      */
      }else{
      /* The non-NaN returning object is assigned to -
      readSizeC - and its corresponding 'ranking' object
      assigned to - bodyRank -:-
      */
      readSizeC = ((docElNaN)?doc ument.body:
      document.docume ntElement);
      bodyRank = ((docElNaN)?bod yRank:docElRank );
      docElRank = null;
      /* Having eliminated one of the objects it is only
      necessary to make decisions between the two
      remaining candidates. This is done by swapping the
      - threeObjectTest - function for one that only makes
      decisions between whichever object has been assigned
      to - readSizeC - and using innerHeight/Width
      values:-
      */
      threeObjectTest = twoObjectTest;
      }
      /* If neither object can be rejected at this stage one of them
      must be chosen provisionally to be used to return
      veiwport/client-region dimensions. The object with the
      lowest 'ranking' is used, and that decision re-evaluated
      whenever the browser has been re-sized or scrolled:-
      */
      }else{
      readSizeC = ((bodyRank.rank < docElRank.rank) ?
      document.body:
      document.docume ntElement);
      }
      }
      /* Once one object has been eliminated it is only necessary to test
      the remaining object to see if it possible to either eliminate
      it and use the innerHeight/width values of the global object, or
      to settle on that object as the best candidate and so stop
      further testing and remove the global object from consideration.
      This function does those tests:-
      */
      function twoObjectTest() {
      /* If the - rank - is Nan after this test then the remaining on
      of body or documentElement can be eliminated and only the
      innerHeight/Width values reported in future:-
      */
      if(isNaN(rankOb j(readSizeC, bodyRank).rank) ){
      bodyRank = null;
      setMinimumScrol l();
      setInnerWH();
      /* Else if the one remaining object has seen non-zero
      differences in clientWidth/Height and innerWidth/Height
      (scroll bar thicknesses) and has survived this test twice
      then it is a fair bet that it does represent the best object
      to be reading viewport/client-region dimensions from. So
      further consideration of the innerHeight/Width values is
      eliminated, along with any additional testing:-
      */
      }else if(
      (bodyRank.vDiff )&&(bodyRank.hD iff)&&
      (++twoTestCount > 2)
      ){
      bodyRank = null;
      theInterface.ge tWidth = getWidthC;
      theInterface.ge tHeight = getHeightC;
      setMinimumScrol l();
      }
      }
      /* The following code is executed when the outermost function is
      called. It is only executed once as its final act is to assign
      an inner function to - getWindowState -, that inner function
      then acts as the 'factory' function for the interface:-
      */
      /* If the global object does not support innerHeight/Width
      properties then the preceding decision making mechanism cannot
      be used. Instead a decision is made at this point based on the
      usual - document.compat Mode - tests that apply to IE browser:-
      */
      if(!propsAreNum bers(global, 'innerHeight', 'innerWidth')){
      readSizeC = compatModeTest( readSizeC);
      theInterface.ge tWidth = getWidthC;
      theInterface.ge tHeight = getHeightC;
      }else{
      /* As the global object does supports innerHeight/Width the
      default - readSizeI - object is replaced with a reference
      to the global object:-
      */
      readSizeI = global;
      }
      /* If the global object supports pageXYOffset properties then
      they are the simplest mechanism for reporting scroll values:-
      */
      if(propsAreNumb ers(global, 'pageYOffset', 'pageXOffset')) {
      readScroll = global;
      readScrollY = 'pageYOffset';
      readScrollX = 'pageXOffset';
      /* Else the - document.compat Mode - tests are used again:-
      */
      }else{
      readScroll = compatModeTest( readScroll);
      }
      /* The global reference to - getWindowState - is replaced with a
      reference to an inner function that just returns the interface
      object, and that inner function is called and its return value
      returned by this initial (and only) cal to the current -
      getWindowState - (outermost) function:-
      */
      return (getWindowState = function(){retu rn theInterface;}) ();
      }

      /* The preceding function is dependent upon this compatMode
      test function (at least in IE and IE-like browsers):-
      */
      function compatModeTest( obj){
      if(
      (document.compa tMode)&&
      (document.compa tMode.indexOf(' CSS') != -1)&&
      (document.docum entElement)
      ){
      return (compatModeTest = function(){
      return document.docume ntElement;
      })((obj = null));
      }else if(document.bod y){
      return (compatModeTest = function(){
      return document.body;
      })((obj = null));
      }else{
      return obj;
      }
      }

      OK that is a huge mass of (convoluted :) code, made worse by being
      extensively commented. However, properly minimised it reduces to <
      2.4Kb, and its complexity is internal, the public interface is small and
      simple, making it easy to use without any interest in its internal
      complexity.

      Comments/feedback/Improvements/etc welcome.

      Richard.


      Comment

      • Yann-Erwan Perio

        #4
        Re: Browser Height in IE? NOT document height

        Richard Cornford wrote:
        [color=blue]
        > Personally, I don't like the answer to 4.9 much anyway.[/color]

        After studying your script I can understand why indeed, the FAQ code
        uses too simplified a logic; I cannot tell to which extent this can be
        dangerous, though.
        [color=blue]
        > Unfortunately the very simple rules that apply to determining which
        > element should be read to retrieve the viewport/visible client-region
        > (inside any scroll bars) dimensions on IE browsers are not really
        > applicable to any other DOM browsers (except by coincidence on some).[/color]

        It had been time since I hadn't done extended browser testing, so I've
        written some test case and tried to watch all the properties which could
        be used in determining the client dimensions, with different compat
        modes; I have learnt things, especially with Opera, which I (naively)
        thought behaved the same way as Mozilla.
        [color=blue]
        > For example, the real viewport/client-region
        > dimensions will never exceed the corresponding innerWidth/Height
        > dimensions (only the document dimensions can do that, though they may
        > not), and if a page is scrolled it is reasonable to assume that it has a
        > scroll bar, which means that in that case the 'client' dimension inside
        > the scroll bar must be smaller than the corresponding 'innner' value.[/color]

        That's an excellent hypothesis, which permits, with the ranking process,
        a finer approach; at least it is much more satisfying than the pure
        compatMode-based one (which relates the value of a property 'compatMode'
        to another 'dimensions' - that goes against good feature detection).
        [color=blue]
        > This brings me to the progressively self re-configuring ("Russian doll")
        > object/system that I said I would publish a few months back. That object
        > was intended to address this particular problem.[/color]

        I'm starting to see the interest of the technique from a conception
        point of view, beyond the simple init/replace issue. The resulting
        structure and flow are elegant and attractive, however it can easily
        turn to something complicated (it took me some time to figure out why
        your smart size getting didn't recurse forever); I wonder to which
        extent the russian doll pattern could be formally structured, using
        objects and setters.
        [color=blue]
        > I still haven't had
        > time to fully test it (at least to the extent that I would consider
        > necessarily), it hasn't yet been shown to any Mac browsers, and I don't
        > think Konqueror has seen this current version yet either.[/color]

        I don't have Konqueror nor Mac browsers here, but I've tested it on
        'regular' browsers (IE4, IE5, IE5.5, IE6, NN4.8, Mozilla 1.8, Opera 6,
        Opera 7) and it gave the safest results for scripting; the logic behind
        the script is strong enough to make me confident it should behave
        correctly in other agents, provided they respect the inner/client
        hypothesis.
        [color=blue]
        > function getScrlXTest(){ hasChangedScrol l();return getScrlXMain(); }
        > function getScrlYTest(){ hasChangedScrol l();return lastSl;}[/color]

        One or the other is the same, lastSl is faster but getScrlYMain is
        easier to read.
        [color=blue]
        > OK that is a huge mass of (convoluted :) code, made worse by being
        > extensively commented.[/color]

        Ah I was thankful for these comments however! I've spent a few hours on
        the code, testing and reading and experimenting, and I'm still not
        satisfied with my study!
        [color=blue]
        > Comments/feedback/Improvements/etc welcome.[/color]

        A truly rich script, mixing an innovative approach to client dimensions
        measuring, and producing an advanced "russian doll" initialization; both
        areas definitely deserve further investigating.


        Cheers,
        Yep.

        Comment

        • Richard Cornford

          #5
          Re: Browser Height in IE? NOT document height

          Yann-Erwan Perio wrote:[color=blue]
          > Richard Cornford wrote:[color=green]
          >> Personally, I don't like the answer to 4.9 much anyway.[/color]
          >
          > After studying your script I can understand why indeed,
          > the FAQ code uses too simplified a logic; I cannot tell
          > to which extent this can be dangerous, though.[/color]

          Code that is logically the same as the example in the FAQ has given me
          the flickering scroll bar problem that I described. Clearly the FAQ code
          cannot be an issue for most of the people using it, else it would have
          attracted more comment in the past. But then it gives the
          viewport/client-region dimensions on IE so maybe that is down to limited
          cross-browser testing.

          <snip>[color=blue]
          > ... ; I have learnt things, especially with Opera, which
          > I (naively) thought behaved the same way as Mozilla.[/color]

          One of the problems with Opera 7 is that behaviour has changed with
          progressive versions. I am not sure whether they are migrating toward
          Mozilla-like, or IE-like, behaviour.
          [color=blue][color=green]
          >> For example, the real viewport/client-region dimensions
          >> will never exceed the corresponding innerWidth/Height
          >> dimensions (only the document dimensions can do that, though
          >> they may not), and if a page is scrolled it is reasonable to
          >> assume that it has a scroll bar, which means that in that
          >> case the 'client' dimension inside the scroll bar must be
          >> smaller than the corresponding 'innner' value.[/color]
          >
          > That's an excellent hypothesis,[/color]

          As it stands, the algorithm used is about the third variant that I have
          attempted to apply to the problem, and the most successful to date.
          There may still be room for improvement, though just throwing in
          additional test criteria may not be an improvement as that may slow down
          the reading/reporting of the values by the interface, and I want that to
          be as fast as possible.
          [color=blue]
          > which permits, with the ranking process, a finer approach;
          > at least it is much more satisfying than the pure
          > compatMode-based one (which relates the value of a property
          > 'compatMode' to another 'dimensions' - that goes against
          > good feature detection).[/color]

          The compatMode test is not good feature detection. It is almost 'object
          inference', except that the relationship is well documented for IE
          browsers so there it is not that much of an inference. Indeed the code
          in 4.9 doesn't use a compatMode test, though the code it does use makes
          assumptions about the values of clientWidth/Height that are true for IE
          but will fail horribly on some other browsers (which never execute that
          code branch as others seem to universally support innerWidth/Height).
          [color=blue][color=green]
          >> This brings me to the progressively self re-configuring
          >> ("Russian doll") object/system that I said I would
          >> publish a few months back. That object was intended to
          >> address this particular problem.[/color]
          >
          > I'm starting to see the interest of the technique from a
          > conception point of view, beyond the simple init/replace
          > issue. The resulting structure and flow are elegant and
          > attractive, however it can easily turn to something
          > complicated (it took me some time to figure out why your
          > smart size getting didn't recurse forever); I wonder to
          > which extent the russian doll pattern could be formally
          > structured, using objects and setters.[/color]

          Complexity is an issue, but I think that so long as it is internal to an
          object/function that has a simple, cohesive interface then it is less of
          a problem. At least so long as the code works as advertised and nobody
          has to go in and fix it. Well designed cross-browser code should satisfy
          that requirement as its logic should enable it to exhibit
          planned/designed behaviour in any environment.

          One of the reasons that I have been writing this type of functionality
          as independent low-level interface objects is that the test-case pages
          for a single interface can act as unit tests, and once properly tested I
          can be confident that I have a unit of reliable, re-usable code that
          _will_ exhibit planned/designed behaviour in any browser environment.
          (It also means that when I can be certain that precise
          viewport/client-region dimensions are not necessary, and
          innerWidth/Height will be good enough, I can use an alternative
          implementation of the same interface that employs the simpler
          configuration/testing. Without having to alter a line of any code using
          the interface.)

          As to formally structuring the "Russian doll" pattern; I haven't
          written/tested enough examples yet to be certain that I have a good
          handle on the issues. Another couple of generations and it might be
          worth writing up, and publishing, a description of the strategy.

          Though I don't think I will want to connect the pattern exclusively with
          objects and getters/setters, as a pattern where the global manifestation
          is always no more than an identifier referring to a function object
          (such as the compatModeTest function needed by getWindowState) seems
          like a reasonable application as well.

          I would encourage the use of low-level interface object, which mostly
          will have getters and setters, but that represents a line of thought
          that is simultaneous with (and will tend to employ) the "Russian doll"
          pattern, rather than an integral part of the strategy itself.

          <snip>[color=blue]
          > I don't have Konqueror nor Mac browsers here,[/color]

          If you have 4 or 5 hours use of a broadband connection (or better, for
          less time) and a CD burner, then you might like to look into Knoppix
          (<URL: http://knoppix.com >). A Linux version designed for use from a
          self-booting CD ROM (you download the ISO image of the disk (which is
          why it takes some time (640Mb)), including KDE with whatever is the
          latest version of Konqueror. The version I am using (3.6) has
          successfully booted about 3 out of 4 of the x86 desktop PCs that I have
          tried it on to date. I am also finding the when something works on
          Konqueror 3 then it also tends to work on Mac Safari (though the reverse
          probably isn't true).
          [color=blue]
          > but I've tested it on 'regular' browsers (IE4, IE5, IE5.5,
          > IE6, NN4.8, Mozilla 1.8, Opera 6, Opera 7) and it gave the
          > safest results for scripting; the logic behind the script
          > is strong enough to make me confident it should behave
          > correctly in other agents, provided they respect the
          > inner/client hypothesis.[/color]

          I am fairly sure that the logic is sound (I should have traced out all
          of the possibilities by now) but I have been caught being over-confident
          before so I am not going to claim it is safe to use until I have
          finished testing it.
          [color=blue][color=green]
          >> function getScrlXTest(){ hasChangedScrol l();return getScrlXMain(); }
          >> function getScrlYTest(){ hasChangedScrol l();return lastSl;}[/color]
          >
          > One or the other is the same, lastSl is faster but getScrlYMain
          > is easier to read.[/color]

          The hasChangedScrol l function is guaranteed to have called getScrlYMain
          and assigned the current value to lastSl. I am interested in having the
          interface methods return their results as quickly as possible so
          returning lastSt from getScrlYTest avoids re-calling getScrlYMain but
          the same cannot be done for getScrlXMain/lastSt as it might not have
          been updated in the call to hasChangedScrol l.

          However, there is a minor mistake in this code, and in -
          hasChangedScrol l -, as it was my intention that the 'l' at the end of
          lastSl represent 'left' (similarly the 't' in lastSt for 'top'), so the
          two variables are being used the wrong way around here and the right way
          around in the - initWidthHeight - function. That doesn't make much
          difference in practice (both X and Y scrolls are likely to be zero on
          first use anyway, and otherwise the error will just re-run the test
          functions once), but it is still wrong and those two lines should be:-

          function getScrlXTest(){ hasChangedScrol l();return getScrlXMain(); }
          function getScrlYTest(){ hasChangedScrol l();return lastSt;}

          - with the - hasChangedScrol l - function becoming:-

          function hasChangedScrol l(){
          if(
          (lastSt != (lastSt = getScrlYMain()) )||
          (lastSl != (lastSl = getScrlXMain()) )
          ){
          threeObjectTest ();
          }
          }

          (While writing this I was happy to observe that the algorithm for the
          not-equals comparison allows for the comparison of current and last
          values, along with the update to the single variable used, in one
          expression.)
          [color=blue][color=green]
          >> OK that is a huge mass of (convoluted :) code, made
          >> worse by being extensively commented.[/color]
          >
          > Ah I was thankful for these comments however! ...[/color]

          Yes, it would hardly have been fair to ask anyone to look at it without
          some comments. But ultimately the sensible way of dealing with the
          shortcomings in 4.9 will be to do what was done for 4.15 and provide an
          additional page which describes the issues and offers at least one
          example of avoiding them. For which I will need a fully (probably more
          fully) commented version.
          [color=blue][color=green]
          >> Comments/feedback/Improvements/etc welcome.[/color]
          >
          > A truly rich script, mixing an innovative approach to
          > client dimensions measuring, and producing an advanced
          > "russian doll" initialization; both areas definitely
          > deserve further investigating.[/color]

          Thank you, I look forward to seeing some implementations of self
          re-configuring functions/objects of yours.

          Richard.


          Comment

          • Yann-Erwan Perio

            #6
            Re: Browser Height in IE? NOT document height

            Richard Cornford wrote:
            [color=blue]
            > Complexity is an issue, but I think that so long as it is internal to an
            > object/function that has a simple, cohesive interface then it is less of
            > a problem. At least so long as the code works as advertised and nobody
            > has to go in and fix it. Well designed cross-browser code should satisfy
            > that requirement as its logic should enable it to exhibit
            > planned/designed behaviour in any environment.[/color]

            I had more in mind maintenance/study of the component itself by multiple
            programmers, however it's true that such a component, once written, is
            unlikely to be changed.
            [color=blue]
            > Though I don't think I will want to connect the pattern exclusively with
            > objects and getters/setters, as a pattern where the global manifestation
            > is always no more than an identifier referring to a function object
            > (such as the compatModeTest function needed by getWindowState) seems
            > like a reasonable application as well.[/color]

            That seems fair; since I haven't experimented much with the pattern I'm
            probably just being a bit overly prudent with the manipulation; I guess
            that building 2-3 components will give me a clearer vision.
            [color=blue]
            > If you have 4 or 5 hours use of a broadband connection (or better, for
            > less time) and a CD burner, then you might like to look into Knoppix
            > (<URL: http://knoppix.com >).[/color]

            Currently downloading; I've never used Linux before, so that'll be fun
            anyway - I'll just think about doing a full back-up before installing
            the thing:-)
            [color=blue]
            > The hasChangedScrol l function is guaranteed to have called getScrlYMain
            > and assigned the current value to lastSl. I am interested in having the
            > interface methods return their results as quickly as possible so
            > returning lastSt from getScrlYTest avoids re-calling getScrlYMain but
            > the same cannot be done for getScrlXMain/lastSt as it might not have
            > been updated in the call to hasChangedScrol l.[/color]

            I missed that, unfortunately - I'll have to review the code a bit more
            carefully. I appreciate the speed argument:-)
            [color=blue]
            > (While writing this I was happy to observe that the algorithm for the
            > not-equals comparison allows for the comparison of current and last
            > values, along with the update to the single variable used, in one
            > expression.)[/color]

            Well that's indeed a beautiful expression, a bit unexpected though (one
            would at first sight evaluate the inner assignment before the
            comparison, though ECMA262 evaluates the relational expression before
            the shift expression, as in 11-8).

            I myself love playing with expressions, the last one I enjoyed writing was

            if((function() { /*...*/ })()) {
            [color=blue]
            > Thank you, I look forward to seeing some implementations of self
            > re-configuring functions/objects of yours.[/color]

            I'll play with the Russian Doll for sure, and believe others (especially
            Mike) will as well.


            Regards,
            Yep.

            Comment

            • Michael Winter

              #7
              [OT] Knoppix (was Re: Browser Height in IE? NOT document height)

              On Mon, 13 Sep 2004 21:18:23 +0200, Yann-Erwan Perio
              <y-e.perio@em-lyon.com> wrote:
              [color=blue]
              > Richard Cornford wrote:
              >[color=green]
              >> If you have 4 or 5 hours use of a broadband connection (or better, for
              >> less time) and a CD burner, then you might like to look into Knoppix
              >> (<URL: http://knoppix.com >).[/color]
              >
              > Currently downloading; I've never used Linux before, so that'll be fun
              > anyway - I'll just think about doing a full back-up before installing
              > the thing:-)[/color]

              My impression of Knoppix was that there is no installation. In fact, I
              don't think it's possible to install it. Knoppix is a self-contained Linux
              distribution on a CD. The absence of disk space recommendations in the
              requirements list would imply that.

              Regarding the back-up, I don't think it would be necessary, but if you've
              got time to kill... However, one thing that you probably shouldn't try to
              do is write to an NTFS disk from Linux. The last time I checked, reading
              support was OK, but writing was experimental. I keep a FAT partition
              around in case I want to pass information between my OSs.

              [snip]
              [color=blue]
              > I'll play with the Russian Doll for sure, and believe others (especially
              > Mike) will as well.[/color]

              Me?

              Mike

              --
              Michael Winter
              Replace ".invalid" with ".uk" to reply by e-mail.

              Comment

              • Yann-Erwan Perio

                #8
                Re: [OT] Knoppix (was Re: Browser Height in IE? NOT document height)

                Michael Winter wrote:
                [color=blue]
                > Regarding the back-up, I don't think it would be necessary, but if
                > you've got time to kill[/color]

                Nah, just kidding, the computer here is regularly backed-up anyway, I
                was just "overly prudent" as with anything new:-)
                [color=blue]
                >... However, one thing that you probably
                > shouldn't try to do is write to an NTFS disk from Linux. The last time
                > I checked, reading support was OK, but writing was experimental. I keep
                > a FAT partition around in case I want to pass information between my OSs.[/color]

                Thanks for the info; luckily that happens to be the case there.
                [color=blue][color=green]
                >> I'll play with the Russian Doll for sure, and believe others
                >> (especially Mike) will as well.[/color][/color]
                [color=blue]
                > Me?[/color]

                I was indeed thinking of you based on my reading of your code; you're
                one of the few here to experiment with function expressions, and you've
                also demonstrated a certain interest for javascript 'expressiveness '
                (for instance you regularly use naturally 'inner assignments') - so I
                believe the Russian Doll should appeal to you (all the more it appears
                to be a javascript-specific pattern and not only a simple js technique).


                Regards,
                Yep.

                Comment

                • Richard Cornford

                  #9
                  Re: [OT] Knoppix (was Re: Browser Height in IE? NOT document height)

                  Michael Winter wrote:[color=blue]
                  > Yann-Erwan Perio wrote:[color=green]
                  >> Richard Cornford wrote:[color=darkred]
                  >>> ... , then you might like to look into
                  >>> Knoppix (<URL: http://knoppix.com >).[/color]
                  >>
                  >> Currently downloading; I've never used Linux before, so
                  >> that'll be fun anyway - I'll just think about doing a full
                  >> back-up before installing the thing:-)[/color]
                  >
                  > My impression of Knoppix was that there is no installation.[/color]

                  There is no installation. By default knoppix is self-contained on the
                  self-booting CD and uses a RAM disk for temporary storage.
                  [color=blue]
                  > In fact, I don't think it's possible to install it.[/color]

                  It was my impression that it could be installed, though it would
                  probably less effort to acquire a Linux version intended for PC
                  installation.
                  [color=blue]
                  > Knoppix is a self-contained Linux distribution on a CD.
                  > The absence of disk space recommendations
                  > in the requirements list would imply that.[/color]

                  Available RAM is probably the most significant consideration, though KDE
                  benefits form fast CPUs.
                  [color=blue]
                  > Regarding the back-up, I don't think it would be necessary,
                  > but if you've got time to kill... However, one thing that
                  > you probably shouldn't try to do is write to an NTFS disk
                  > from Linux. The last time I checked, reading support was
                  > OK, but writing was experimental. I keep a FAT partition
                  > around in case I want to pass information between my OSs.[/color]

                  By default Knoppix has read-only access to the local hard disks, so it
                  should be safe. There are options for allowing it write access, and for
                  arranging persistent storage (of configuration/set-up details, etc) on a
                  local hard disk. For testing with Konqueror alone that has not proved
                  necessary, though the reporting of javascript errors, and the javascript
                  debugger, are disabled by default on the 3.6 disk so it might be nice to
                  have the enabled settings persist between Linux sessions).
                  [color=blue]
                  > [snip]
                  >[color=green]
                  >> I'll play with the Russian Doll for sure, and believe
                  >> others (especially Mike) will as well.[/color]
                  >
                  > Me?[/color]

                  Why not you? ;-)

                  Richard.


                  Comment

                  • Richard Cornford

                    #10
                    Re: Browser Height in IE? NOT document height

                    Yann-Erwan Perio wrote:[color=blue]
                    > Richard Cornford wrote:[color=green]
                    >> Complexity is an issue, ...[/color][/color]
                    <snip>[color=blue]
                    > I had more in mind maintenance/study of the component
                    > itself by multiple programmers, however it's true that
                    > such a component, once written, is unlikely to be changed.[/color]

                    I had intended to mention that that example of the application of a
                    "Russian doll" pattern is probably among the most complex needed. The
                    progressive configuration that had to be applied to that problem is
                    unusual and most applications will be able to fully re-configure
                    themselves on their first use in one step.

                    I should comment and post a more direct application, but I don't have
                    time right now (maybe later in the week).

                    <snip>[color=blue][color=green]
                    >> (While writing this I was happy to observe that the algorithm
                    >> for the not-equals comparison allows for the comparison of
                    >> current and last values, along with the update to the single
                    >> variable used, in one expression.)[/color]
                    >
                    > Well that's indeed a beautiful expression, a bit unexpected
                    > though (one would at first sight evaluate the inner assignment
                    > before the comparison, though ECMA262 evaluates the relational
                    > expression before the shift expression, as in 11-8).[/color]
                    <snip>

                    Fortunately the ECMA algorithm seems to have been consistently
                    implemented in browsers (that was my main concern about the expression).

                    Richard.


                    Comment

                    • Michael Winter

                      #11
                      Re: [OT] Knoppix (was Re: Browser Height in IE? NOT document height)

                      On Tue, 14 Sep 2004 01:36:41 +0100, Richard Cornford
                      <Richard@litote s.demon.co.uk> wrote:

                      [snip]
                      [color=blue]
                      > It was my impression that [Knoppix] could be installed, though it would
                      > probably less effort to acquire a Linux version intended for PC
                      > installation.[/color]

                      You're right. It can be installed. Instructions are given in the last FAQ
                      entry. If it's not on the CD, you can read it on one of the mirrors. For
                      example, <URL:ftp://ftp.uni-kl.de/pub/linux/knoppix/KNOPPIX-FAQ-EN.txt>.

                      [snip]
                      [color=blue]
                      > By default Knoppix has read-only access to the local hard disks, so it
                      > should be safe. There are options for allowing it write access, and for
                      > arranging persistent storage (of configuration/set-up details, etc) on a
                      > local hard disk.[/color]

                      The FAQ mentions that, too. Including the warning I gave regarding NTFS
                      usage.
                      [color=blue]
                      > For testing with Konqueror alone that has not proved necessary, though
                      > the reporting of javascript errors, and the javascript debugger, are
                      > disabled by default on the 3.6 disk so it might be nice to have the
                      > enabled settings persist between Linux sessions).[/color]

                      It would probably be easier to save and script modifications, rather than
                      writing, printing, or remembering them, too.

                      That reminds me. I should really stop fiddling with Linux and just get it
                      up and running so I can use it again.

                      [Yep:]
                      [color=blue][color=green][color=darkred]
                      >>> I'll play with the Russian Doll for sure, and believe
                      >>> others (especially Mike) will as well.[/color]
                      >>
                      >> Me?[/color]
                      >
                      > Why not you? ;-)[/color]

                      Well, for one thing, I haven't read what you two have been writing about
                      yet. :P

                      I suppose I'm just surprised to be mentioned directly.

                      Mike

                      --
                      Michael Winter
                      Replace ".invalid" with ".uk" to reply by e-mail.

                      Comment

                      • Thomas 'PointedEars' Lahn

                        #12
                        Re: [OT] Knoppix

                        Richard Cornford wrote:
                        [color=blue]
                        > Michael Winter wrote:[color=green]
                        >> My impression of Knoppix was that there is no installation.[/color]
                        >
                        > There is no installation. By default knoppix is self-contained on the
                        > self-booting CD and uses a RAM disk for temporary storage.
                        >[color=green]
                        >> In fact, I don't think it's possible to install it.[/color]
                        >
                        > It was my impression that it could be installed, though it would
                        > probably less effort to acquire a Linux version intended for PC
                        > installation.[/color]

                        Firstly, AFAIS Knoppix is nothing but a Debian (<http://debian.org/>)
                        GNU/Linux based system using on-boot hardware detection to create the
                        necessary configuration files on the RAM disk. Besides saving
                        configuration files on a block device usually harddisk partition, e.g.)
                        and restoring them on boot as well as maintaining a home directory on any
                        block device, it can be installed on a harddisk and runs from there (see
                        <http://knopper.net/>). The difference is that further modifications in
                        system configuration files would be required to have the system use the
                        preconfigured files and skip the hardware detection.

                        Secondly, Knoppix (or any other so-called "Linux distribution") is not
                        a Linux version (the kernel) alone, it is the kernel and corresponding
                        software (like system commands and a command shell). That's why it is
                        correctly called "GNU/Linux", e.g., where GNU (GNU's Not Unix) is the
                        operating system and Linux is its kernel. There is no "Linux version
                        intended for PC installation", precompiled kernels aside (they were not
                        meant by posters in this discussion). See <http://www.gnu.org/>.


                        PointedEars
                        --
                        Every knee shall bend, every mouth open, when I unzip

                        Comment

                        • Richard Cornford

                          #13
                          Re: [OT] Knoppix (was Re: Browser Height in IE? NOT document height)

                          Michael Winter wrote:[color=blue]
                          > Richard Cornford wrote:[/color]
                          <snip>[color=blue][color=green]
                          >> For testing with Konqueror alone that has not proved
                          >> necessary, though the reporting of javascript errors,
                          >> and the javascript debugger, are disabled by default
                          >> on the 3.6 disk so it might be nice to have the
                          >> enabled settings persist between Linux sessions).[/color]
                          >
                          > It would probably be easier to save and script modifications,
                          > rather than writing, printing, or remembering them, too.[/color]

                          For small changes saving to a floppy disk is practical. I am usually not
                          running Knoppix on my own hardware so playing with local hard disks
                          would not necessarily be popular.

                          <snip>[color=blue][color=green][color=darkred]
                          >>>> I'll play with the Russian Doll for sure, and
                          >>>> believe others (especially Mike) will as well.
                          >>>
                          >>> Me?[/color]
                          >>
                          >> Why not you? ;-)[/color]
                          >
                          > Well, for one thing, I haven't read what you two
                          > have been writing about yet. :P[/color]
                          <snip>

                          We are talking about a strategy for maximising the efficiency of feature
                          detection tests by avoiding repeating test when they would produce the
                          same results on any subsequent use, and doing this by having the first
                          use of a function (or a method of an object) re-configure itself based
                          on the tests so that subsequent calls are able to directly use code
                          tailored to the browser environment in use.

                          So where a function might do:-

                          function getElementWithI d(id){
                          var obj = null;
                          if(document.get ElementById){
                          obj = document.getEle mentById(id);
                          }else if(document.all ){
                          obj = document.all[id];
                          }else if(document.lay ers){
                          obj = document.layers[id];
                          }
                          return obj;
                          }

                          - a self-reconfiguring alternative might go:-

                          function getElementWithI d(id){
                          var fnc = function(){retu rn null;};
                          if(document.get ElementById){
                          fnc = function(id){
                          return document.getEle mentById(id);
                          };
                          }else if(document.all ){
                          fnc = function(id){re turn document.all[id];};
                          }else if(document.lay ers){
                          fnc = function(id){re turn document.layers[id];};
                          }
                          return (getElementWith Id = fnc)(id);
                          }

                          - so the configuration is only done the first time the function is
                          called and form then on the public face of the function has been
                          replaced by one of its inner functions (hence the name "Russian doll")
                          and that inner function will be the one that is optimum for the current
                          browser environment.

                          In the case of this example it doesn't make much difference whether this
                          style is used or something more like:-

                          var getElementWithI d;
                          if(document.get ElementById){
                          getElementWithI d = function(id){
                          return document.getEle mentById(id);
                          }
                          }else if(document.all ){
                          getElementWithI d = function(id){
                          return document.all[id];
                          }
                          }else if(document.lay ers){
                          getElementWithI d = function(id){
                          return document.layers[id];
                          }
                          }else{
                          getElementWithI d = function(){
                          return null;
                          }
                          }

                          - or:-

                          var getElementWithI d = (function(){
                          if(document.get ElementById){
                          return (function(id){
                          return document.getEle mentById(id);
                          });
                          }else if(document.all ){
                          return (function(id){
                          return document.all[id];
                          });
                          }else if(document.lay ers){
                          return (function(id){
                          return document.layers[id];
                          });
                          }else{
                          return (function(){
                          return null;
                          });
                          }
                          })();

                          - because the decision making criteria are fixed and can be detected at
                          any point where it is possible to import a JS file. Though the
                          penultimate; test-inline and assign a function to a property of the
                          global object, source code seems less of a well-defined unit.

                          A function that re-configures itself is probably of most obvious use
                          when something needed to perform the test meaningfully is not always
                          available. The client-area dimension reading code, for example, needs
                          the document.body to be available in order to consider it as a source
                          for the required information. And the document.body element does not
                          exist until the opening BODY tag has been encountered by the HTML
                          parser. That would require inline configuration code to be physically
                          within the body. Deferring configuration until the first use of the
                          interface allows the code to be imported in the head of the document (so
                          appear in a single site-wide JS file) and arrange that it is just its
                          first use that doesn't happen until the BODY element exists.

                          It might be that the code needs to do its feature detection based on the
                          properties of an Element that would be provided to the function by
                          reference. The code can either branch internally, re-testing on each
                          use, or it can perform the tests the first time it is used and then
                          re-configure itself to expose an inner function that acts upon an
                          element argument without re-confirming the same features exist on
                          subsequent similar elements.

                          The deferring of the configuration also means that if the code that uses
                          the function decides that as a result of other testing it is not viable
                          it may never call the original outer function, and so the configuration
                          code will not be executed needlessly.

                          The downside to the example self-re-configuring function above is that
                          it will form a closure and so some work will be needed to ensure that
                          that closure does not trap references that may induce the memory leak
                          problem in IE (though mostly element references in such closures should
                          be one-way and so not cause any problems). However, because the
                          technique will produce a closure, whenever such a closure could be
                          directly exploited the design can consider an implementation that
                          follows this pattern. Many examples of the in-line execution of a
                          function expression that returns a function can be alternatively
                          implemented in this pattern. It lends itself to code that is using an
                          outer function to encapsulate related functionality, it just defers the
                          creation of the associated closure.

                          It also allows for the multi-stage configuration that the
                          dimension-reporting object uses, while keeping the resulting code in the
                          form of a self-contained unit.

                          Richard.


                          Comment

                          Working...