views:

226

answers:

5

I am trying to follow tecnhique of unobtrusive JavaScript / graceful degradation. I'd like to serve page with different links when JavaScript is turned on, and when JavaScript is turned off.

For example when JavaScript is turned off the link would be

<a href="script.cgi?a=action">

and when JavaScript is turned on

<a href="script.cgi?a=action;js=1">

(or something like that).

Both versions (with JavaScript and without JavaScript) of link lead to server side script, but with different parameters. The version that is meant to be called when JavaScript is turned off performs more on server, therefore it would be unproductive to detect JavaScript there (e.g. redirecting from server script for non-JavaScript to the other version via window.location).

Note: I would prefer solution without using JavaScript libraries / frameworks like jQuery.

+1  A: 

Start with the non-Javascript-enabled link, then simply use some Javascript code to modify the link to its Javascript-enabled value. This ensures that the link will always be the correct version. For example:

<a id="link_to_change" href="script.cgi?a=action">

<script type="text/javascript">
    window.onload = function(){
        document.getElementById("link_to_change").href += ";js=1";
    }
</script>
Eli Courtwright
As long as they don't click the link before onload fires
Greg
A: 

If you're just doing one link, this should be enough:

<a href="script.cgi?a=action" onclick="this.href += ';js=1';">
Greg
Unfortunately there are (usually) many such links
Jakub Narębski
+6  A: 

Well, the answer is to render the page as normal with the non-Javascript links. Then get the Javascript to replace the links with the JS=1 versions.

var links = document.getElementsByTagName('a');
for (var i=0;i<links.length;i++) {
    links[i].href += ";js=1";
}
Daniel Roseman
+1 for not giving your answer in jquery
tj111
+1  A: 

A simple solution that intelligently handles links with no existing querystring.

// Get array of all links
var links = document.getElementsByTagName('a');

for (var i=0; i<links.length; i++){
    // Add a question mark if link does not already have a querystring.
    links[i].href += (/\?/.test(links[i].href)) ? '' : '?';
    links[i].href += ';js=1';
}
Triptych
A: 

On my site, I develop a totally non-javascript version of the site. I develop in Django and pass down the data for the page as Django template variables. I render a page in a tag, and then I JSONify the variables and render the javascript.

For example, here's the Django template for a mapview on my site:

{% extends "new-base.html" %} {% load markup %} {% load tb_tags %}

{% block headcontent %}
  <script type="text/javascript">
    var mapData = {{map|jsonify}};
  </script> 
{% endblock %}


{% block content %}
  {% include "noscript/mapview.html" %}
{% endblock %}

And here's the the noscript template that gets used. This is what people without JS and search engines use:

{% load tb_tags %}
<noscript>
  <link rel="stylesheet" type="text/css" href="/site_media/css/no-js.css"> 
  <style type="text/css"> div.content { padding:10px } </style>
  <div class=JSWhite>
    <h1 class=noJS>
      {% ifequal map.target.id map.places.0.node.id %}
        <a href="{{map.places.0.pages.0.url}}">{{map.target.name}}</a></h1>
      {% else %}
        <a href="{{map.target.url}}">{{map.target.name}}</a></h1>
      {% endifequal %}
    {% ifequal map.target.type 'node' %}
      &nbsp;- {{map.target.ele}} meters <BR>
    {% endifequal %}
    <span style ='color:gray; font-size:.8em; font-style:italic'>
      ({{map.target.la}},{{map.target.lo}})&nbsp;
    </span>
    <a class=JSAd target=_blank href=http://www.mytopo.com/searchgeo.cfm?lat={{map.target.la}}&amp;lon={{map.target.lo}}&amp;pid=trailbehind&gt;Buy Topo Map</a> &nbsp;-&nbsp;
    <a style='font-size:.8em;color:#CC5500' target=_blank href='http://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q={{map.target.name}}'&gt;Get Directions</a>
    {% if map.target.dist %}
      <BR>{{map.target.dist}}
    {% endif %}
    {% if map.target.ascent %}
      <BR>{{map.target.ascent}}
    {% endif %}

    {% for r in map.places %}
      {% ifequal r.node.id map.target.id %} 
        <BR>
        {% if r.pages.0 %}
          {{r.pages.0.summary}}
        {% endif %}
        <UL style='list-style:none;margin-left:0; padding-left:0'>
          {% for key in r.pages %}
            {% ifnotequal forloop.counter 1 %}
              <LI><a href={{key.url}}>{{key.title}}</a><BR>
                  {{key.snippet}}
              </LI>
            {% endifnotequal %}
          {% endfor %}
        </UL>
     {% endifequal %}
   {% endfor %}
   <HR>
   <strong>(<a href="{{map.target.url}}">All</a> -
     <a href="{{map.target.url}}hiking/">Hiking</a> -
     <a href="{{map.target.url}}camping/">Camping</a> - 
     <a href="{{map.target.url}}climbing/">Climbing</a> - 
     <a href="{{map.target.url}}biking/">Biking</a>)</strong><BR>
  <p>
  {% if map.places %}
    <h1>Nearby Adventures</h1>
    <UL style='list-style:none;margin:0; margin-top:10px;padding-left:0'>
      {% for r in map.places %}
        {% ifnotequal r.node.id map.target.id %} 
          <LI><h1>
      {% if r.node.trip_id %}
        <a href="{{r.node.url}}">{{r.pages.0.title}}</a></h1>
      {% else %}
       <a href="{{r.node.url}}{{activity}}">{{r.pages.0.title}}</a></h1>
          {% endif %}
      {% if r.pages.0 %}
            {% if r.pages.0.activity %}
          <strong>{{r.pages.0.activity}}</strong> -
            {% endif %}
            {{r.pages.0.snippet}}
     {% endif %}
   {% endifnotequal %}
     {% endfor %}
   {% endif %}
   </UL>
   </p>
  </div>
</noscript>
Andrew Johnson