Tuesday, 11 August 2015

Brute forcing my way Javascript, CSS etc

This is not a topic which will promote good design pattern or coding style. Instead this is about getting something done.

 

Detecting some change in page with Javascript


Many a times I need to get the size of an HTML element which is loaded dynamically through Javascript and do something as soon as it has changed it's size. Due to not understanding the code or poor design of it I have to brute force my way. To do it, I simply repeat the a timed function till the event occurs. Take a look at the following code:
var maxLoopTime = 4000;//milli seconds
var startTime = new Date().getTime();
var myInterval = setInterval(function () {
 try {
  var timeExceeded = new Date().getTime() - startTime > maxLoopTime;
  var detected = isChangeDetected();
  
  if(timeExceeded || detected) {
   clearInterval(myInterval);
   doSomething();
  }
 } catch(err) {
  clearInterval(myInterval);
  doSomething();
 }
}, 300);

function isChangeDetected () {
 //check for the condition
}

function doSomething () {
 //do something once even occurs
} 
isChangeDetected looks for the change, in my case it's the height change of an HTML element.
doSomething is the function which I want to call when the HTML element has taken the final size.

CSS in a dynamically created element:

Sometimes when loading some HTML elements dynamically we need to apply some properties to other part of the web page or to the element itself.
One way of doing it is to monitor the page waiting for the element to appear. I don't know how I would achieve it, may be by using some third party library.
However how about simplest brute solutions below:
  1. Add the CSS <style> element as the part of the dynamically loaded HTML element. As soon as the element is loaded it web page will apply the style and when it's unloaded page will again revert the changes.
  2. Add a Javascript <script> tag to this element
    <div id="myElement">
        <style>
            body: {
                background-color: red;
            }
        </style&gt
        <!-- or !-->
        <script>
                console.log("finally loaded");
        </script>
    </div>
Off course in Case 1 you have to make sure that when element unloads it's deleted entirely otherwise effects of the <style> tag will remain even after the dynamically loaded element has disappeared (visibility: none or display:none).
By adding the <style> or <script> tag to the element here means is adding these tags to the template or the html content of the loaded element.

I'm fully aware of the fact that both of these actions will lead to a reflow and redrawing of the DOM and webpage, that's why title here is brute force.

Detecting Flash Plugin with JavaScript

It's nothing fancy. It certainly will not work for Internet Explorer's old versions.
I simply needed something to disable certain functionality if Flash was not installed on Tablets/iPads.
If you need to detect an iPad or you're looking for a robust plugin to detect Flash you're better off using media queries or some JavaScript Flash library.

Here it is:

CoffeeScript version

isFlashInstalled = ->
      try
        flashPlugin = _.filter(navigator.plugins, (el) -> return el.description.match(/.*shockwave flash*/i))
        flashPlugin != null && flashPlugin.length != 0
      catch err
        console.log("error in detecting flash")
      flashPlugin != null and flashPlugin.length != 0

JavaScript translated version

var isFlashInstalled = function() {

        var err, flashPlugin;
        try {
          flashPlugin = _.filter(navigator.plugins, function(el) {
            return el.description.match(/.*shockwave flash*/i);
          });
          flashPlugin !== null && flashPlugin.length !== 0;
        } catch (_error) {
          err = _error;
          console.log("error in detecting flash");
        }
        return flashPlugin !== null && flashPlugin.length !== 0;
      }

Here I'm using underscore js for the array filtering, you can off course use a plain for loop or array forEach method.