SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    SitePoint Member
    Join Date
    May 2007
    Location
    Enon, OH
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Standards Compliant?

    I found the following script (albeit, 3 yrs old), on this site (http://www.sitepoint.com/article/sta...mpliant-world). The intent of the script is to use XHTML in a standards compliant way to open a new window using javascript. This is in lieu of the deprecated target attribute. My problem is the script seems to work only in Opera. Under IE and Gecko-based browsers, the script does not generate an error, it simply doesn't work.

    **********************************

    function externalLinks() {
    if (!document.getElementsByTagName) return;
    var anchors = document.getElementsByTagName("a");
    for (var i=0; i<anchors.length; i++) {
    var anchor = anchors[i];
    if (anchor.getAttribute("href") &&
    anchor.getAttribute("rel") == "external")
    anchor.target = "_blank";
    }
    }
    window.onload = externalLinks;

    **********************************

    I used the above as inspiration to clean-up inline event-handlers in a tooltip script I've been using for years. The script is listed below and includes a couple of 'troubleshooting' lines that indicate the script is running through. I then took a page with my original tooltip script so that I know it works in IE/Opera/Gecko. I modified the page using both of the above scripts. It has the same problem; works in Opera only while causing no errors in IE or Gecko-derivatives.

    **********************************

    function tips()
    {
    if (!document.getElementsByTagName) return;
    var anchors = document.getElementsByTagName("a");
    var j=0;
    for (var i=0; i<anchors.length; i++)
    {
    var tips = anchors[i];
    if (tips.className == "tip")
    {
    j++;
    var tipwin = "tipWin" + String(j);
    tips.onmouseout = "tipDown('"+tipwin+"')";
    tips.onmouseover = "toolTips(event,'"+tipwin+"',10);return true";
    document.getElementsByTagName("a")[j].onclick = "alert('Hello')"; //troubleshooter
    }
    }
    document.getElementById('test').value=tipwin; //troubleshooter
    }
    window.onload = tips;

    **********************************
    Oddly enough, if one installs these scripts and use the Gecko DOM inspector to see what's happening, the eventhandlers will appear where they are suppose to, but apparently do not fire.

    Any comments/help?

    RKM

  2. #2
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,786
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    target is just as deprecated if added from JavaScript as it is if you hard code it. You should not be using JavaScript to add deprecated tags to a page with a strict doctype, if you want to use deprecated tags use a transitional doctype. If you want a strict doctype and to open links in a new window then use the JavaScript window.open() command which is the right way of performing this behaviour.

    HTML for content, JavaScript for behaviour.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  3. #3
    SitePoint Member
    Join Date
    May 2007
    Location
    Enon, OH
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I know all of that, but it's not my question. I tend to agree with what you said, and I have used onclick/onkeypress=window.open() for quite a number of years now; and probably more frequently than I should. But my question remains unanswered, why does the above script not work?

    I did rework the script and got the .target part of it to work by combining the two into a single script as follows.


    ********************************************
    function externalLinks()
    {
    if (!document.getElementsByTagName) return;
    var anchors = document.getElementsByTagName("a");
    var j=0;
    for (var i=0; i<anchors.length; i++)
    {
    var anchor = anchors[i];

    if (anchor.className == "tip")
    {
    j++;
    var tips = "tipWin" + String(j);
    anchor.onmouseout = "tipDown('" + tips + "');";
    anchor.onmouseover = "toolTips(event,'" + tips + "',10);return true;";
    }

    if (anchor.getAttribute("href") && anchor.getAttribute("rel") == "external")
    {anchor.target = "_blank";}
    }
    }
    window.onload = externalLinks;

    ******************************************
    I would still like to know how to dynamically assign/change an an event handler.
    I still cannot get any browser other than Opera to recognize and perform the first if statement properly, despite the fact I've shown the assignment to the event handler to exist...at least from my point of view

    RKM

  4. #4
    SitePoint Guru
    Join Date
    Apr 2006
    Posts
    802
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    anchor.onmouseout = "tipDown('" + tips + "');";
    anchor.onmouseover = "toolTips(event,'" + tips + "',10);return true;";
    you are assigning strings, not functions to the event types

  5. #5
    SitePoint Member
    Join Date
    May 2007
    Location
    Enon, OH
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks.

    I was kind of headed in that direction of thought, but was distracted by the fact that Opera evaluated the string as a function. For some reason, I thought the other browsers should do the same. Silly me!

    I've applied the eval() and call() functions and all now works as it should.


    RKM

  6. #6
    SitePoint Guru Ize's Avatar
    Join Date
    Nov 2005
    Location
    The Netherlands
    Posts
    808
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You don't need eval() for this, just use

    Code:
    anchor.onmouseout = function() { tipDown(tips); }
    anchor.onmouseover = function() { toolTips(event,tips,10); return true; }

  7. #7
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,786
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Just remember that as you are setting a target that you must use a transitional doctype as strict doctypes do not allow you to use target (and usuing JavaScript to add the invalid attribute so that the validator doesn't see it doesn't mean that the page is valid, it just means that you are not validating the final version of the page).
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  8. #8
    CSS & JS/DOM Adept bronze trophy
    Join Date
    Mar 2005
    Location
    USA
    Posts
    5,482
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    IIRC, the target attribute works in more situations than window.open() though or is at least a whole lot simpler than completely replicating it's behavior with window.open() and other JavaScript/DOM code. Unfortunately I don't remember the specifics from when I was working on this last year.
    We miss you, Dan Schulz.
    Learn CSS. | X/HTML Validator | CSS validator
    Dynamic Site Solutions
    Code for Firefox, Chrome, Safari, & Opera, then add fixes for IE, not vice versa.

  9. #9
    SitePoint Guru
    Join Date
    Mar 2004
    Location
    Earth
    Posts
    406
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    FYI, we don't use quite that technique on sitepoint.com anymore - I replaced it with this more generic approach:

    Code JavaScript:
    /* NEW POPUP INITIALISATION CODE based on document click handler to bypass load dependency
       This code uses an unencapsulated document.onclick handler, which is necessary
       because it's the only way to suppress the default action in bloody Safari */
    document.onclick = function(e)
    {
    	//ignore button presses that aren't left button in Firefox
    	if(typeof e != 'undefined' && typeof e.which != 'undefined' && e.which != 1) { return true; }
     
    	//get event node reference
    	var node = e ? e.target : window.event.srcElement;
     
    	//iterate upwards from event node until we find a link
    	//but abandon iteration and return true on the link
    	//if we run out of nodes (because we're already at the body) or reach the body
    	while(node.nodeName.toLowerCase() != 'a')
    	{
    		if(!node.parentNode) { return true; }
    		else if(node.nodeName.toLowerCase() == 'body') { return true; }
    		else { node = node.parentNode; }
    	}
     
    	//if we got this far we have a link reference
    	//so look for a rel attribute 
    	if(node.getAttribute('rel'))
    	{
    		//there's no such thing as an XHTML compliant target attribute
    		//but ho hum, better preserve the functionality anyway [for now ;)]
    		if (node.rel == 'external')
    		{
    			node.target = '_blank';
    			return true;
    		}
    	}
     
    	//if we got this far we don't have rel information
    	//so just follow the link as normal
    	return true;
    };

    Which bypasses the dependency on window.onload, and removes the need for an iterative process at page load.
    Last edited by brothercake; May 28, 2007 at 17:01.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •