Loading ...
Sorry, an error occurred while loading the content.

Menus, XHTML and non validity

Expand Messages
  • Alex Leonard
    Hi there, I am working on my first use of YUI s menu system and have encountered a small problem. As a result of having script items in the I am failing
    Message 1 of 3 , Aug 28, 2007
    • 0 Attachment
      Hi there,

      I am working on my first use of YUI's menu system and have encountered a
      small problem.

      As a result of having script items in the <head> I am failing validation.

      I was going to go ahead and try and take those elements out of the head
      and place them in an external javascript file and use an addLoadEvent
      function as recommended by Simon Willison:
      http://simonwillison.net/2004/May/26/addLoadEvent/

      However I am unfamiliar with the methods used and thought I would ask
      advice first.

      The sample page in question is:

      http://www.pixelapes.com/devel/coral_leisure/testing/

      and the javascript in the head which seems to be causing a validation
      fail is listed below. The validator points specifically at the line "if
      (oAnim && oAnim.isAnimated()) {" where it picks up on the usage of the &
      symbol as causing an XML parsing error and being the first character of
      a delimiter where none exists.

      Is there a good way of taking these lines of script out of the head and
      replacing them with a short addLoadEvent? Or is this something that they
      are already doing? It does feel like these lines would be better off in
      an external .js file.

      I hope this all makes sense! If I can help explain the problem further,
      please let me know.

      Kind regards,

      Alex Leonard

      ******* Javascript Code that is causing the problem *************

      <script type="text/javascript">
      // Initialize and render the menu bar when it is available in the DOM

      YAHOO.util.Event.onContentReady("main-nav", function () {
      // Animation object
      var oAnim;
      // "beforeshow" event handler for each submenu of the menu bar
      function onMenuBeforeShow(p_sType, p_sArgs) {
      var oBody,
      oShadow,
      oUL;
      if (this.parent) {
      oShadow = this.element.lastChild;
      oShadow.style.height = "0px";
      if (oAnim && oAnim.isAnimated()) {
      oAnim.stop();
      oAnim = null;
      }
      oBody = this.body;
      oUL = oBody.getElementsByTagName("ul")[0];
      YAHOO.util.Dom.setStyle(oBody, "overflow", "hidden");
      YAHOO.util.Dom.setStyle(oUL, "marginTop", ("-" +
      oUL.offsetHeight + "px"));
      }
      }

      function onTween(p_sType, p_aArgs, p_oShadow) {
      if (this.cfg.getProperty("iframe")) {
      this.syncIframe();
      }
      if (p_oShadow) {
      p_oShadow.style.height = this.element.offsetHeight + "px";
      }
      }

      function onAnimationComplete(p_sType, p_aArgs, p_oShadow) {
      var oBody = this.body,
      oUL = oBody.getElementsByTagName("ul")[0];
      if (p_oShadow) {
      p_oShadow.style.height = this.element.offsetHeight + "px";
      }
      YAHOO.util.Dom.setStyle(oUL, "marginTop", "auto");
      YAHOO.util.Dom.setStyle(oBody, "overflow", "visible");
      if (YAHOO.env.ua.ie) {
      YAHOO.util.Dom.setStyle(oBody, "zoom", "1");
      }
      }
      // "show" event handler for each submenu of the menu bar
      function onMenuShow(p_sType, p_sArgs) {
      var oElement,
      oShadow,
      oUL;
      if (this.parent) {
      oElement = this.element;
      oShadow = oElement.lastChild;
      oUL = this.body.getElementsByTagName("ul")[0];
      oAnim = new YAHOO.util.Anim(oUL,
      { marginTop: { to: 0 } },
      .5, YAHOO.util.Easing.easeOut);
      oAnim.onStart.subscribe(function () {
      oShadow.style.height = "100%";
      });
      oAnim.animate();
      /*
      Refire the event handler for the "iframe"
      configuration property with each tween so that the
      size and position of the iframe shim remain in sync
      with the menu.
      */
      if (YAHOO.env.ua.ie) {
      oShadow.style.height = oElement.offsetHeight + "px";
      oAnim.onTween.subscribe(onTween, oShadow, this);
      }
      oAnim.onComplete.subscribe(onAnimationComplete, oShadow, this);
      }
      }
      // Instantiate and render the menu bar
      var oMenuBar = new YAHOO.widget.MenuBar("main-nav", {
      autosubmenudisplay: true, hidedelay: 500, lazyload: true });
      oMenuBar.subscribe("beforeShow", onMenuBeforeShow);
      oMenuBar.subscribe("show", onMenuShow);
      /*
      Call the "render" method with no arguments since the markup for
      this menu already exists in the DOM.
      */
      oMenuBar.render();
      });

      // NUMBER 2

      // Initialize and render the menu when it is available in the DOM

      YAHOO.util.Event.onContentReady("centres-nav", function () {

      /*
      Instantiate the menu. The first argument passed to the
      constructor is the id of the element in the DOM that
      represents the menu; the second is an object literal
      representing a set of configuration properties for
      the menu.
      */

      var oMenu = new YAHOO.widget.Menu("centres-nav", {position:
      "static", hidedelay: 500, lazyload: true, effect: {effect:
      YAHOO.widget.ContainerEffect.FADE, duration: 0.25} } );

      /*
      Call the "render" method with no arguments since the markup for
      this menu already exists in the DOM.
      */

      oMenu.render();

      });
      </script>
    • Todd Kloots
      Alex - You ll need to place the script inside a CDATA block in order for it to validate:
      Message 2 of 3 , Aug 30, 2007
      • 0 Attachment
        Alex -

        You'll need to place the script inside a CDATA block in order for it to
        validate:

        <script type="text/javascript">
        <![CDATA[

        <!-- YOUR JAVASCRIPT HERE -->

        ]]>
        </script>


        That said, as you are currently using the "onContentReady" method of the
        Event utility, there is no reason why you couldn't just take this script
        (as is) out of the head and place it in an external file.

        The Event utility's "onContentReady" method is one of three ways that
        the YUI Event utility facilitates the style of unobtrusive binding of
        DOM event handlers as mentioned in the blog entry by Simon Willison that
        you referenced. For more on this topic, check out these two sections of
        the Event Utility's landing page:

        http://developer.yahoo.com/yui/event/#onavailable
        http://developer.yahoo.com/yui/event/#ondomready

        - Todd

        Alex Leonard wrote:
        >
        > Hi there,
        >
        > I am working on my first use of YUI's menu system and have encountered a
        > small problem.
        >
        > As a result of having script items in the <head> I am failing validation.
        >
        > I was going to go ahead and try and take those elements out of the head
        > and place them in an external javascript file and use an addLoadEvent
        > function as recommended by Simon Willison:
        > http://simonwillison.net/2004/May/26/addLoadEvent/
        > <http://simonwillison.net/2004/May/26/addLoadEvent/>
        >
        > However I am unfamiliar with the methods used and thought I would ask
        > advice first.
        >
        > The sample page in question is:
        >
        > http://www.pixelapes.com/devel/coral_leisure/testing/
        > <http://www.pixelapes.com/devel/coral_leisure/testing/>
        >
        > and the javascript in the head which seems to be causing a validation
        > fail is listed below. The validator points specifically at the line "if
        > (oAnim && oAnim.isAnimated()) {" where it picks up on the usage of the &
        > symbol as causing an XML parsing error and being the first character of
        > a delimiter where none exists.
        >
        > Is there a good way of taking these lines of script out of the head and
        > replacing them with a short addLoadEvent? Or is this something that they
        > are already doing? It does feel like these lines would be better off in
        > an external .js file.
        >
        > I hope this all makes sense! If I can help explain the problem further,
        > please let me know.
        >
        > Kind regards,
        >
        > Alex Leonard
        >
        > ******* Javascript Code that is causing the problem *************
        >
        > <script type="text/javascript">
        > // Initialize and render the menu bar when it is available in the DOM
        >
        > YAHOO.util.Event.onContentReady("main-nav", function () {
        > // Animation object
        > var oAnim;
        > // "beforeshow" event handler for each submenu of the menu bar
        > function onMenuBeforeShow(p_sType, p_sArgs) {
        > var oBody,
        > oShadow,
        > oUL;
        > if (this.parent) {
        > oShadow = this.element.lastChild;
        > oShadow.style.height = "0px";
        > if (oAnim && oAnim.isAnimated()) {
        > oAnim.stop();
        > oAnim = null;
        > }
        > oBody = this.body;
        > oUL = oBody.getElementsByTagName("ul")[0];
        > YAHOO.util.Dom.setStyle(oBody, "overflow", "hidden");
        > YAHOO.util.Dom.setStyle(oUL, "marginTop", ("-" +
        > oUL.offsetHeight + "px"));
        > }
        > }
        >
        > function onTween(p_sType, p_aArgs, p_oShadow) {
        > if (this.cfg.getProperty("iframe")) {
        > this.syncIframe();
        > }
        > if (p_oShadow) {
        > p_oShadow.style.height = this.element.offsetHeight + "px";
        > }
        > }
        >
        > function onAnimationComplete(p_sType, p_aArgs, p_oShadow) {
        > var oBody = this.body,
        > oUL = oBody.getElementsByTagName("ul")[0];
        > if (p_oShadow) {
        > p_oShadow.style.height = this.element.offsetHeight + "px";
        > }
        > YAHOO.util.Dom.setStyle(oUL, "marginTop", "auto");
        > YAHOO.util.Dom.setStyle(oBody, "overflow", "visible");
        > if (YAHOO.env.ua.ie) {
        > YAHOO.util.Dom.setStyle(oBody, "zoom", "1");
        > }
        > }
        > // "show" event handler for each submenu of the menu bar
        > function onMenuShow(p_sType, p_sArgs) {
        > var oElement,
        > oShadow,
        > oUL;
        > if (this.parent) {
        > oElement = this.element;
        > oShadow = oElement.lastChild;
        > oUL = this.body.getElementsByTagName("ul")[0];
        > oAnim = new YAHOO.util.Anim(oUL,
        > { marginTop: { to: 0 } },
        > .5, YAHOO.util.Easing.easeOut);
        > oAnim.onStart.subscribe(function () {
        > oShadow.style.height = "100%";
        > });
        > oAnim.animate();
        > /*
        > Refire the event handler for the "iframe"
        > configuration property with each tween so that the
        > size and position of the iframe shim remain in sync
        > with the menu.
        > */
        > if (YAHOO.env.ua.ie) {
        > oShadow.style.height = oElement.offsetHeight + "px";
        > oAnim.onTween.subscribe(onTween, oShadow, this);
        > }
        > oAnim.onComplete.subscribe(onAnimationComplete, oShadow, this);
        > }
        > }
        > // Instantiate and render the menu bar
        > var oMenuBar = new YAHOO.widget.MenuBar("main-nav", {
        > autosubmenudisplay: true, hidedelay: 500, lazyload: true });
        > oMenuBar.subscribe("beforeShow", onMenuBeforeShow);
        > oMenuBar.subscribe("show", onMenuShow);
        > /*
        > Call the "render" method with no arguments since the markup for
        > this menu already exists in the DOM.
        > */
        > oMenuBar.render();
        > });
        >
        > // NUMBER 2
        >
        > // Initialize and render the menu when it is available in the DOM
        >
        > YAHOO.util.Event.onContentReady("centres-nav", function () {
        >
        > /*
        > Instantiate the menu. The first argument passed to the
        > constructor is the id of the element in the DOM that
        > represents the menu; the second is an object literal
        > representing a set of configuration properties for
        > the menu.
        > */
        >
        > var oMenu = new YAHOO.widget.Menu("centres-nav", {position:
        > "static", hidedelay: 500, lazyload: true, effect: {effect:
        > YAHOO.widget.ContainerEffect.FADE, duration: 0.25} } );
        >
        > /*
        > Call the "render" method with no arguments since the markup for
        > this menu already exists in the DOM.
        > */
        >
        > oMenu.render();
        >
        > });
        > </script>
        >
        >
      • Alex Leonard
        Brilliant.. I completely forgot about CDATA stuff - it s just something I ve read about but never actually needed to use. Thanks. I haven t had time to read
        Message 3 of 3 , Sep 1 3:07 AM
        • 0 Attachment
          Brilliant.. I completely forgot about CDATA stuff - it's just something I've read about but never actually needed to use. Thanks.

          I haven't had time to read through the event sections yet, but ultimately I'd probably prefer to have the javascript external.

          Cheers dude.
          Alex

          Todd Kloots wrote:
          Alex -

          You'll need to place the script inside a CDATA block in order for it to validate:

          <script type="text/javascript">
          <![CDATA[

          <!-- YOUR JAVASCRIPT HERE -->

          ]]>
          </script>


          That said, as you are currently using the "onContentReady" method of the Event utility, there is no reason why you couldn't just take this script (as is) out of the head and place it in an external file.

          The Event utility's "onContentReady" method is one of three ways that the YUI Event utility facilitates the style of unobtrusive binding of DOM event handlers as mentioned in the blog entry by Simon Willison that you referenced.  For more on this topic, check out these two sections of the Event Utility's landing page:

          http://developer.yahoo.com/yui/event/#onavailable
          http://developer.yahoo.com/yui/event/#ondomready

          - Todd

          Alex Leonard wrote:

          Hi there,

          I am working on my first use of YUI's menu system and have encountered a
          small problem.

          As a result of having script items in the <head> I am failing validation.

          I was going to go ahead and try and take those elements out of the head
          and place them in an external javascript file and use an addLoadEvent
          function as recommended by Simon Willison:
          http://simonwillison.net/2004/May/26/addLoadEvent/ <http://simonwillison.net/2004/May/26/addLoadEvent/>

          However I am unfamiliar with the methods used and thought I would ask
          advice first.

          The sample page in question is:

          http://www.pixelapes.com/devel/coral_leisure/testing/ <http://www.pixelapes.com/devel/coral_leisure/testing/>

          and the javascript in the head which seems to be causing a validation
          fail is listed below. The validator points specifically at the line "if
          (oAnim && oAnim.isAnimated()) {" where it picks up on the usage of the &
          symbol as causing an XML parsing error and being the first character of
          a delimiter where none exists.

          Is there a good way of taking these lines of script out of the head and
          replacing them with a short addLoadEvent? Or is this something that they
          are already doing? It does feel like these lines would be better off in
          an external .js file.

          I hope this all makes sense! If I can help explain the problem further,
          please let me know.

          Kind regards,

          Alex Leonard

          ******* Javascript Code that is causing the problem *************

          <script type="text/javascript">
          // Initialize and render the menu bar when it is available in the DOM

          YAHOO.util.Event.onContentReady("main-nav", function () {
          // Animation object
          var oAnim;
          // "beforeshow" event handler for each submenu of the menu bar
          function onMenuBeforeShow(p_sType, p_sArgs) {
          var oBody,
          oShadow,
          oUL;
          if (this.parent) {
          oShadow = this.element.lastChild;
          oShadow.style.height = "0px";
          if (oAnim && oAnim.isAnimated()) {
          oAnim.stop();
          oAnim = null;
          }
          oBody = this.body;
          oUL = oBody.getElementsByTagName("ul")[0];
          YAHOO.util.Dom.setStyle(oBody, "overflow", "hidden");
          YAHOO.util.Dom.setStyle(oUL, "marginTop", ("-" +
          oUL.offsetHeight + "px"));
          }
          }

          function onTween(p_sType, p_aArgs, p_oShadow) {
          if (this.cfg.getProperty("iframe")) {
          this.syncIframe();
          }
          if (p_oShadow) {
          p_oShadow.style.height = this.element.offsetHeight + "px";
          }
          }

          function onAnimationComplete(p_sType, p_aArgs, p_oShadow) {
          var oBody = this.body,
          oUL = oBody.getElementsByTagName("ul")[0];
          if (p_oShadow) {
          p_oShadow.style.height = this.element.offsetHeight + "px";
          }
          YAHOO.util.Dom.setStyle(oUL, "marginTop", "auto");
          YAHOO.util.Dom.setStyle(oBody, "overflow", "visible");
          if (YAHOO.env.ua.ie) {
          YAHOO.util.Dom.setStyle(oBody, "zoom", "1");
          }
          }
          // "show" event handler for each submenu of the menu bar
          function onMenuShow(p_sType, p_sArgs) {
          var oElement,
          oShadow,
          oUL;
          if (this.parent) {
          oElement = this.element;
          oShadow = oElement.lastChild;
          oUL = this.body.getElementsByTagName("ul")[0];
          oAnim = new YAHOO.util.Anim(oUL,
          { marginTop: { to: 0 } },
          .5, YAHOO.util.Easing.easeOut);
          oAnim.onStart.subscribe(function () {
          oShadow.style.height = "100%";
          });
          oAnim.animate();
          /*
          Refire the event handler for the "iframe"
          configuration property with each tween so that the
          size and position of the iframe shim remain in sync
          with the menu.
          */
          if (YAHOO.env.ua.ie) {
          oShadow.style.height = oElement.offsetHeight + "px";
          oAnim.onTween.subscribe(onTween, oShadow, this);
          }
          oAnim.onComplete.subscribe(onAnimationComplete, oShadow, this);
          }
          }
          // Instantiate and render the menu bar
          var oMenuBar = new YAHOO.widget.MenuBar("main-nav", {
          autosubmenudisplay: true, hidedelay: 500, lazyload: true });
          oMenuBar.subscribe("beforeShow", onMenuBeforeShow);
          oMenuBar.subscribe("show", onMenuShow);
          /*
          Call the "render" method with no arguments since the markup for
          this menu already exists in the DOM.
          */
          oMenuBar.render();
          });

          // NUMBER 2

          // Initialize and render the menu when it is available in the DOM

          YAHOO.util.Event.onContentReady("centres-nav", function () {

          /*
          Instantiate the menu. The first argument passed to the
          constructor is the id of the element in the DOM that
          represents the menu; the second is an object literal
          representing a set of configuration properties for
          the menu.
          */

          var oMenu = new YAHOO.widget.Menu("centres-nav", {position:
          "static", hidedelay: 500, lazyload: true, effect: {effect:
          YAHOO.widget.ContainerEffect.FADE, duration: 0.25} } );

          /*
          Call the "render" method with no arguments since the markup for
          this menu already exists in the DOM.
          */

          oMenu.render();

          });
          </script>



        Your message has been successfully submitted and would be delivered to recipients shortly.