superhero superhero - 6 months ago 10
Javascript Question

How to include js files in header of wordpress pages that are activated on-click

I am attempting to use wordpress to build a website that integrates google maps. I am doing some overlays with the maps and use the google developers API and Python to make the appropriate javascript. I have successfully written the js files and Python necessary to accomplish this.

My website is built in Worpress and I would like add a page (not the home page) that has n links and each one would populate a box with the corresponding map. I can take care of the layout and design issues but I am at a loss on how to:

a) Include the javascript as a file that

b) gets called upon clicking the link and thus populates that map without calling a new page

That is, the javascript is HUGE because it may include thousands of lat/lon points. Therefore including n of these written into the header is unreasonable. I want to simply call it from filename.js when the link is clicked.

There is a plugin that allows me to include whatever I want in the header. So, if I can find out where to put the *.js files (or txt file) in the directory tree and how to have the corresponding file activated upon click I should be good. Thanks!

This Display different maps with onClick event - Google Maps V3. kind of helps with doing an on-click display but everyone's solution was to make one map. I cannot do that. I am overlaying vast amounts of data.

Answer

Here is a way you can get that done. (Jump down to the get started part of the script.)

For brevity, I've included a bunch of scripts in one 'file', but you'll want to break them in to individual files.

You may also need to try the html and js in jsbin js bin example, b/c SO may or may not allow the dynamic loading of js.

(function(undefined) {
  /**
   * @author (@colecmc)
   * @method turn collection into an array
   * @param {object} collection - NodeList, HTMLCollection, etc. Should have an "item" method and/or a "length" property
   */
  ToArray = collection => Array.prototype.slice.call(collection);

  /** \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ **/


  Observer = (function(undefined) {
    /**
     * pub sub
     */
    'use strict';

    var subUid = -1;
    return {
      topics: {},

      subscribe: function(topic, func) {
        /**
         * @param {string} topic
         * @param {function} func
         * @returns {string} - a token such as '3'
         * @example Observer.subscribe('any-valid-string',function(name,resp){
                console.log(resp.prop);
            });
         */
        if (!Observer.topics[topic]) {
          Observer.topics[topic] = [];
        }

        var token = (++subUid).toString();
        Observer.topics[topic].push({
          token: token,
          func: func
        });

        return token;
      },

      publish: function publish(topic, args) {
        /**
         * @param {string} topic
         * @param {object} args
         * @returns {boolean} - true if topic is valid, false otherwise
         * @example Observer.publish('any-valid-string',{
                prop: 'this is a test'
            });
         */
        if (!Observer.topics[topic]) {
          return false;
        }

        setTimeout(function() {
          var subscribers = Observer.topics[topic],
            len = subscribers ? subscribers.length : 0;

          while (len--) {
            subscribers[len].func(topic, args);
          }
        }, 0);

        return true;
      },

      unsubscribe: function unsubscribe(token) {
        /**
         * @param {string} token - value should be saved from the original subscription
         * @example Observer.unsubscribe('2');
         * @example Observer.unsubscribe(member); - where member is the value returned by Observer.subscribe();
         */
        var m,
          forEachTopic = function(i) {
            if (Observer.topics[m][i].token === token) {
              Observer.topics[m].splice(i, 1);
              return token;
            }
          };

        for (m in Observer.topics) {
          if (Observer.topics.hasOwnProperty(m)) {
            Observer.topics[m].forEach(forEachTopic);
          }
        }

        return false;
      }
    };
  }(undefined));
  /** \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ **/

  SetAttributes = function(el, attrs) {
    /**
     * @author (@colecmc)
     * @method simple for in loop to help with creating elements programmatically
     * @param {object} el - HTMLElement attributes are getting added to
     * @param {object} attrs - object literal with key/values for desired attributes
     * @example SetAttributes(info,{
     *    'id' : 'utswFormInfo'
     *    'class' : 'my-class-name'
     * });
     */

    'use strict';
    var key;

    for (key in attrs) {
      if (attrs.hasOwnProperty(key)) {
        el.setAttribute(key, attrs[key]);
      }
    }

    return el;
  };

  /** \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ **/


  GetScript = function(url, fullPath) {
    /**
     * @author (@colecmc)
     * @version 1.0.4
     * @requires Swlxws.SetAttributes, Swlxws.Observer
     * @method dynamically add script tags to the page.
     * @param {string} url - relative path and file name - do not include extension
     * @param {string} fullPath - absolute path
     * @example GetScript('myLocalScript');
     * @example GetScript('','https://www.google-analytics.com/analytics.js');
     */

    'use strict';

    function onLoad(event) {
      var result;

      if (event.type === 'load') {
        result = 1;
      } else {
        result = -1;
      }

      Observer.publish('get-script-onload-complete', {
        successful: result,
        eventData: event
      });
    }

    var JSPATH = '/js/',
      /* or where ever you keep js files */
      el = document.createElement('script'),
      attrs = {
        defer: true,
        src: null,
        type: 'text/javascript'
      };

    /** look for a string based, protocol agnostic, js file url */
    if (typeof fullPath === 'string' && fullPath.indexOf('http') === 0) {
      attrs.src = fullPath;
    }

    /** look for any string with at least 1 character and prefix our root js dir, then append extension */
    if (typeof url === 'string' && url.length >= 1) {
      attrs.src = JSPATH + url + '.js';
    }

    SetAttributes(el, attrs);

    el.addEventListener('load', onLoad);
    el.addEventListener('error', onLoad);

    document.body.appendChild(el);

    return el;
  };

  /** \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ **/

  /**
   * Get Started
   */
  function onClick(event) {
    GetScript('', event.target.dataset.namespaceUrl);
  }

  Observer.subscribe('get-script-onload-complete', function(name, resp) {
    /** check to make resp is what you expect, ie: the correct script loaded */
    /** then it is safe to use */
  });

  ToArray(document.querySelectorAll('.load-scripts')).map(script => script.addEventListener('click', onClick, false));

}(undefined));
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>How to include js files in header of wordpress pages that are activated on-click</title>
</head>

<body>

  <a href="#load" class="load-scripts" data-namespace-url="https://www.google-analytics.com/analytics.js">Load Google Analytics</a>

</body>

</html>

Comments