The a11yhcm.js file

The first thing we will do is define the API. Before building a plugin, it is wise to figure out how you want developers to interact with it. By doing this, you will be able to understand exactly what you are trying to build before writing a single line of code.

The fundamental functionality of our plugin is to enable a style sheet to be dynamically loaded and removed from a page based on the occurrence of a specific event. So, we need two things:

  • An event to trigger the JS
  • The path to the style sheet that is to be loaded

We can use a data-attribute to act as the trigger, just as we did with the other plugins, and use it to pass the path of a CSS file. We want the data-attribute to be unique to our plugin, so we must use an appropriate data-attribute postfix. Let's try something like the following:

    <div class="allyhcm" data-a11yhcm="path/to/css">High Contrast Mode
    </div>

That's nice and succinct. There isn't anything else we need right now, so we will get to writing our JavaScript. Our plugin's JavaScript code will live in js/a11yhcm.js. Let's set up our skeleton; just like we saw earlier, we want it immediately invoked and added to our page's jQuery object. We want to create an on-click listener for any element with the data-a11yhcm attribute, but we need to declare which function it triggers. As we want this plugin to dynamically load and remove a style sheet, we will call our function toggle as it toggles HCM on and off. We also want to add a VERSION constant:

    +function ($) {
        'use strict';
        // A11YHCM CLASS DEFINITION
        // ======================
        var A11yHCM = function (element, options) {
        $(element).on('click', '[data-a11yhcm]', this.toggle)
        }
    A11yHCM.VERSION = '1.0.0'
    }(jQuery);

Next, we want to add the plugin definition. As explained earlier, the plugin definition creates an instance of the plugin for each DOM element with the a11yhcm class. Observe the following code:

    // A11YHCM PLUGIN DEFINITION
    // =======================
    function Plugin(option) {
    return this.each(function () {
        var $this = $(this)
        var data = $this.data('bs.a11yhcm')
        if (!data) $this.data('bs.a11yhcm', (data = new A11yHCM(this)))
        if (typeof option == 'string') data[option].call($this)
        })
    }
    var old = $.fn.a11yhcm
    $.fn.a11yhcm = Plugin
    $.fn.a11yhcm.Constructor = A11yHCM  

We'd better not forget the noConflict function to help resolve namespace collisions:

    // A11YHCM NO CONFLICT
    // =================
    $.fn.a11yhcm.noConflict = function () {
        $.fn.a11yhcm = old
        return this
    }

Now we're getting to the fun part. Before we get into coding the functionality, we must declare our API. We know we want to use the data-a11yhcm attribute as our trigger (and to pass data to our plugin) and to use the toggle function that we declared in the constructor. Observe the following code:

    // A11YHCM DATA-API
    // ==============
    $(document).on('click.bs.allyhcm.data-api', '[data-a11yhcm]', 
    A11yHCM.prototype.toggle)

We also want to ensure that our plugin definition is called for all elements with the data-a11yhcm attributes. Add this to the data API:

    $(window).on('load', function () {
        $('[data-a11yhcm]').each(function () {
            var $a11yhcm = $(this)
            Plugin.call($a11yhcm, $a11yhcm.data())
        })
    })

Okay, now all we need to do is write the toggle function! Let's discuss our approach. The first thing we need to do is get the reference to the style sheet to be loaded from the data-a11yhcm attribute. Observe the following code:

    A11yHCM.prototype.toggle = function (e) {
        var $this = $(this)
        var styleSheet = $this.attr('data-a11yhcm')
    }

That's easy. Then, we need to figure out the current state. Are we in HCM or not? We can separate the functionality into on and off functions, hiding and showing the options in the UI as appropriate, much like our alert, expand, and minimize customizations. However, let's try to keep the API and DOM manipulation to a minimum. Instead, we can simply check to see whether the link tag with the high contrast style sheet is present in the DOM. To do that, we need a way of being able to select the link tag. We will do this by adding the link tag with a unique ID—bs-a11yhcm. Let's update toggle with a check to see whether the element exists. If it does, use jQuery to remove it; if it doesn't, we will use jQuery to append it to the head of the DOM:

    if(document.getElementById('bs-a11yhcm'))
        $('#' + $this.styleSheetID).remove()
    else {
        var styleSheetLink = '<link href="' + styleSheet + '" 
      rel="stylesheet" id="bs-a11yhcm"/>'
        $('head').append(styleSheetLink)
    }

That's pretty much it! Let's do one more thing. What if, by some chance, there is already another element on the page, unrelated to A11yHCM, with the id value of bs-a11yhcm? Rather than forcing a developer to change their page to suit the plugin, we will do the right thing and allow the developer to pass in a custom value for the id. The toggle function will check to see whether an a11yhcm-id attribute exists; if it does, A11yHCM will use that value as the id for the link tag. In that case, an element using A11yHCM can look like this:

    <div class="allyhcm" data-a11yhcm="path/to/css" a11yhcm-
    id="customId">High Contrast Mode</div>

Let's update the toggle function to reflect this. We will add the default value for the id as a property of A11yHCM:

    var A11yHCM = function (element) {
        this.$element = $(element)
    }
    A11yHCM.VERSION = '1.0.0'
    A11yHCM.DEFAULTS = {
        styleSheetID : 'bs-a11yhcm'
    }
    A11yHCM.prototype.toggle = function (e) {
        var $this = $(this)
        var styleSheet = $this.attr('data-a11yhcm')
    if ($this.attr('a11yhcm-id'))
        $this.styleSheetID = $this.attr('a11yhcm-id')
      else
        $this.styleSheetID = A11yHCM.DEFAULTS.styleSheetID
      if (document.getElementById($this.styleSheetID))
        $('#' + $this.styleSheetID).remove()
    else {
       var styleSheetLink = '<link href="' + styleSheet + '"
       rel="stylesheet" id="' + $this.styleSheetID + '"/>'
       $('head').append(styleSheetLink)
    }
}

Okay, that's it. That looks like all the JavaScript we'll need to make A11yHCM work the way we envisaged. Now, let's put it into practice by adding the markup.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.238.171