Graceful degradation with Dijit

2019-09-06 07:29发布

问题:

I've been a dojo (core) user for a few years now. Building my own widgets atop the dojo space; neglecting dijit and dojox. Working in my own world. That had it's advantages, but I kept having the feeling that I'm reinventing the wheel while building yet another tabbed panel, carousel or dialog box. So I've decided to use dijit.

With my own widgets, I've set some basic rules:

  1. A widget must degrade gracefully [when no js is loaded] for accessibility and SEO
  2. There should be no redraws after the js is loaded (which is always included on the page after all html, just before the body end-tag)
  3. No inline JS (scripts must be separate from HTML)

Problem:

Dijit has two ways of being instantiated: declaratively and programmatically. Either way seems to break one of the rules.

a. Declarative instantiation:

Looks either something like:

<div dojoType="MyFirstWidget">
  <ul>
    <li dojoAttachPoint="counter">0</li>
    <li><a dojoAttachEvent="_updateCounter" href="#">Update</a></li>
  </ul>

  <script type="dojo/connect" event="onClick" args="evt">
    console.log("This will execute after of the Button dijit's onClick method has been called.");
  </script>
</div>

As you can see, this clearly breaks the 3rd rule (no inline js).

b. Programmatic instantiation:

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");

dojo.declare("MyFirstWidget", [dijit._Widget, dijit._Templated], {
  templateString: "<div class='awesome'>0</div>",

  postCreate: function() {
    console.log("postCreate");
  }
});

(new MyFirstWidget()).placeAt(dojo.body());

And this way, rules 1 & 2 are broken. (1) No accessibility or SEO value (2) Once the template is set, the browser will need to redraw the entire page.

Question: is it possible (and practical) to use dijit, and still follow the rules?

回答1:

Yes, it is both possible and practical. However, your rule #2 makes it pretty difficult to use any pre-built Dijits out of the box since they are designed to attach to a node and rebuild it with a "Dojo style". You could get around that by styling the node to look like the final result - but that may seem to be more trouble than it's worth, but it would be the only way to follow this rule and still use some of the necessary compnents (that are hard to do yourself) like FilteringSelect.

Mainly because of #2, I would recommend that you not use *dijit._Templated*. Just use *dijit._Widget*, and instead of having internal HTML, just attach to the existing HTML in your document.

Maybe you can bend #2, and allow it to be modifed and restyled, but not so much that it changes what the DOM looks like to a search engine or a speech reader.

I never do #3 myself, so hopefully that shouldn't be hard.

For #1 it depends on the widget. You can use a standard browser select and upgrade that with Dojo to a FilteringSelect.