Link to home
Start Free TrialLog in
Avatar of Tony Pearce
Tony PearceFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Javascript error : TypeError: Cannot read property 'append' of undefined

Hi, I have a javascript countdown clock that throws this error:
TypeError: Cannot read property 'append' of undefined
 /micore/core/info/content_headlines.asp:832

Code:
    <script language="javascript" type="text/javascript">   
    var ringer = {
  countdown_to: "04/01/2019",
  rings: {
    'DAYS': { 
      s: 86400000, // mseconds in a day,
      max: 365
    },
    'HOURS': {
      s: 3600000, // mseconds per hour,
      max: 24
    },
    'MINUTES': {
      s: 60000, // mseconds per minute
      max: 60
    },
    'SECONDS': {
      s: 1000,
      max: 60
    }
   },
  r_count: 4,
  r_spacing: 20, // px
  r_size: 82, // px
  r_thickness: 10, // px
  update_interval: 11, // ms
    
    
  init: function(){
   
    $r = ringer;
    $r.cvs = document.createElement('canvas'); 
    
    $r.size = { 
      w: ($r.r_size + $r.r_thickness) * $r.r_count + ($r.r_spacing*($r.r_count-1)), 
      h: ($r.r_size + $r.r_thickness) 
    };
    


    $r.cvs.setAttribute('width',$r.size.w);           
    $r.cvs.setAttribute('height',$r.size.h);
    $r.ctx = $r.cvs.getContext('2d');
    $(".countdownwrap").append($r.cvs);
    $r.cvs = $($r.cvs);    
    $r.ctx.textAlign = 'center';
    $r.actual_size = $r.r_size + $r.r_thickness;
    $r.countdown_to_time = new Date($r.countdown_to).getTime();
    $r.cvs.css({ width: $r.size.w+"px", height: $r.size.h+"px" });
    $r.go();
  },
  ctx: null,
  go: function(){
    var idx=0;
    
    $r.time = (new Date().getTime()) - $r.countdown_to_time;
    
    
    for(var r_key in $r.rings) $r.unit(idx++,r_key,$r.rings[r_key]);      
    
    setTimeout($r.go,$r.update_interval);
  },
  unit: function(idx,label,ring) {
    var x,y, value, ring_secs = ring.s;
    value = parseFloat($r.time/ring_secs);
    $r.time-=Math.round(parseInt(value)) * ring_secs;
    value = Math.abs(value);
    
    x = ($r.r_size*.5 + $r.r_thickness*.5);
    x +=+(idx*($r.r_size+$r.r_spacing+$r.r_thickness));
    y = $r.r_size*.5;
    y += $r.r_thickness*.5;

    
    // calculate arc end angle
    var degrees = 360-(value / ring.max) * 360.0;
    var endAngle = degrees * (Math.PI / 180);
    
    $r.ctx.save();

    $r.ctx.translate(x,y);
    $r.ctx.clearRect($r.actual_size*-0.5,$r.actual_size*-0.5,$r.actual_size,$r.actual_size);

    // first circle
    $r.ctx.strokeStyle = "rgba(89,89,89,0.3)";
    $r.ctx.beginPath();
    $r.ctx.arc(0,0,$r.r_size/2,0,2 * Math.PI, 2);
    $r.ctx.lineWidth =$r.r_thickness;
    $r.ctx.stroke();
   
    // second circle
    $r.ctx.strokeStyle = "rgba(242, 9, 56, 0.9)";
    $r.ctx.beginPath();
    $r.ctx.arc(0,0,$r.r_size/2,0,endAngle, 1);
    $r.ctx.lineWidth =$r.r_thickness;
    $r.ctx.stroke();
    
    // label
    $r.ctx.fillStyle = "#5e5c5c";
   
    $r.ctx.font = '10px Helvetica';
    $r.ctx.fillText(label, 0, 23);
    $r.ctx.fillText(label, 0, 23);   
    
    $r.ctx.font = 'bold 35px Helvetica';
    $r.ctx.fillText(Math.floor(value), 0, 10);
    
    $r.ctx.restore();
  }
}

ringer.init();
 </script> 

Open in new window



Called by:
<link href='https://fonts.googleapis.com/css?family=Roboto+Condensed' rel='stylesheet' type='text/css'>
<div style="    border: 0px;
    padding: 6px;
    border-color: lightgrey;
    border-style: solid;">
<div style="float: right;    font-size: 20px;
    margin-top: 20px;
    font-family: sans-serif;
    margin-right: 12px;
    color: darkgray;">Countdown to MTDfV deadline <br>&nbsp;&nbsp; Are your clients compliant?</div>
<div style=" display: in-line" class="countdownwrap"></div>
</div>

Open in new window

Avatar of Swatantra Bhargava
Swatantra Bhargava
Flag of India image

Change below Line and see result

<div style=" display: in-line" class="countdownwrap"></div>

To

<div style=" display: in-line" id="countdownwrap"></div>
The above solution is misleading

countdownwrap is a class not an id and you are accessing it by it's class name
 $(".countdownwrap").append($r.cvs);

Open in new window



The problem appears to be related to page load issues - the JavaScript is running before the element it refers to exist. Try putting your code inside a document ready, or locate it at the end of the your document before the </body> tag.
Please find herein below working solution:

<html>
<body>

 
 	<link href='https://fonts.googleapis.com/css?family=Roboto+Condensed' rel='stylesheet' type='text/css'>
<div style="border: 0px;
    padding: 6px;
    border-color: lightgrey;
    border-style: solid;">
<div style="float: right;    font-size: 20px;
    margin-top: 20px;
    font-family: sans-serif;
    margin-right: 12px;
    color: darkgray;">Countdown to MTDfV deadline <br>&nbsp;&nbsp; Are your clients compliant?</div>
</div>
<div id="countdownwrap"></div>

<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
    <script type="text/javascript">   
    var ringer = {
  countdown_to: "04/01/2019",
  rings: {
    'DAYS': { 
      s: 86400000, // mseconds in a day,
      max: 365
    },
    'HOURS': {
      s: 3600000, // mseconds per hour,
      max: 24
    },
    'MINUTES': {
      s: 60000, // mseconds per minute
      max: 60
    },
    'SECONDS': {
      s: 1000,
      max: 60
    }
   },
  r_count: 4,
  r_spacing: 20, // px
  r_size: 82, // px
  r_thickness: 10, // px
  update_interval: 11, // ms
  init: function(){
   
    $r = ringer;
    $r.cvs = document.createElement('canvas'); 
    
    $r.size = { 
      w: ($r.r_size + $r.r_thickness) * $r.r_count + ($r.r_spacing*($r.r_count-1)), 
      h: ($r.r_size + $r.r_thickness) 
    };
    


    $r.cvs.setAttribute('width',$r.size.w);           
    $r.cvs.setAttribute('height',$r.size.h);
    $r.ctx = $r.cvs.getContext('2d');
    $("#countdownwrap").append($r.cvs);
	
	alert($("#countdownwrap").html());
	
    $r.cvs = $($r.cvs);    
    $r.ctx.textAlign = 'center';
    $r.actual_size = $r.r_size + $r.r_thickness;
    $r.countdown_to_time = new Date($r.countdown_to).getTime();
    $r.cvs.css({ width: $r.size.w+"px", height: $r.size.h+"px" });
    $r.go();
  },
  ctx: null,
  go: function(){
    var idx=0;
    
    $r.time = (new Date().getTime()) - $r.countdown_to_time;
    
    
    for(var r_key in $r.rings) $r.unit(idx++,r_key,$r.rings[r_key]);      
    
    setTimeout($r.go,$r.update_interval);
  },
  unit: function(idx,label,ring) {
    var x,y, value, ring_secs = ring.s;
    value = parseFloat($r.time/ring_secs);
    $r.time-=Math.round(parseInt(value)) * ring_secs;
    value = Math.abs(value);
    
    x = ($r.r_size*.5 + $r.r_thickness*.5);
    x +=+(idx*($r.r_size+$r.r_spacing+$r.r_thickness));
    y = $r.r_size*.5;
    y += $r.r_thickness*.5;

    
    // calculate arc end angle
    var degrees = 360-(value / ring.max) * 360.0;
    var endAngle = degrees * (Math.PI / 180);
    
    $r.ctx.save();

    $r.ctx.translate(x,y);
    $r.ctx.clearRect($r.actual_size*-0.5,$r.actual_size*-0.5,$r.actual_size,$r.actual_size);

    // first circle
    $r.ctx.strokeStyle = "rgba(89,89,89,0.3)";
    $r.ctx.beginPath();
    $r.ctx.arc(0,0,$r.r_size/2,0,2 * Math.PI, 2);
    $r.ctx.lineWidth =$r.r_thickness;
    $r.ctx.stroke();
   
    // second circle
    $r.ctx.strokeStyle = "rgba(242, 9, 56, 0.9)";
    $r.ctx.beginPath();
    $r.ctx.arc(0,0,$r.r_size/2,0,endAngle, 1);
    $r.ctx.lineWidth =$r.r_thickness;
    $r.ctx.stroke();
    
    // label
    $r.ctx.fillStyle = "#5e5c5c";
   
    $r.ctx.font = '10px Helvetica';
    $r.ctx.fillText(label, 0, 23);
    $r.ctx.fillText(label, 0, 23);   
    
    $r.ctx.font = 'bold 35px Helvetica';
    $r.ctx.fillText(Math.floor(value), 0, 10);
    
    $r.ctx.restore();
  }
}

$( document ).ready(function() {
    ringer.init();
});

 </script> 
</body>
</html>

Open in new window

Avatar of Tony Pearce

ASKER

Great that shows, thanks very much, but page won't complete load until you click a notification box that states:

websrv says
<canvas width="428" height="92"></canvas>

the above shows in Chrome, in IE it just fails without box
Remove

      alert($("#countdownwrap").html()); from the code.

What is your IE version? it's working fine in Microsoft Edge 42.17134.1.0
Hi, this was on IE11

I can't see that line in the code

Thanks again
Tony
I don't have IE 11. Please check your browser console and see if there are any errors.
User generated image
This is from IE11

Thanks
Tony
Made the below change and see it's working or not in IE 11

<body onload="ringer.init()">
Got the error twice:
<canvas width="428" height="92" style="width: 428px; height: 92px;"></canvas><canvas width="428" height="92"></canvas>
Made the below change and see it's working or not in IE 11

<body onload="ringer.init()">

and remove

$( document ).ready(function() {
    ringer.init();
});
Thanks I will try, the chap doing changes is out for an hour...
First test as the Previous comment if that will not work replace the function with below

 
var ringer = {
  countdown_to: "04/01/2019",
  rings: {
    'DAYS': { 
      s: 86400000, // mseconds in a day,
      max: 365
    },
    'HOURS': {
      s: 3600000, // mseconds per hour,
      max: 24
    },
    'MINUTES': {
      s: 60000, // mseconds per minute
      max: 60
    },
    'SECONDS': {
      s: 1000,
      max: 60
    }
   },
  r_count: 4,
  r_spacing: 20, // px
  r_size: 82, // px
  r_thickness: 10, // px
  update_interval: 11, // ms
  init: function(){
   
    $r = ringer;
    $r.cvs = document.createElement('canvas'); 
    
	if ($r.cvs.getContext) {
	
		$r.size = { 
		  w: ($r.r_size + $r.r_thickness) * $r.r_count + ($r.r_spacing*($r.r_count-1)), 
		  h: ($r.r_size + $r.r_thickness) 
		};
		


		$r.cvs.setAttribute('width',$r.size.w);           
		$r.cvs.setAttribute('height',$r.size.h);
		$r.ctx = $r.cvs.getContext('2d');
		$("#countdownwrap").append($r.cvs);
	}

    $r.cvs = $($r.cvs);    
    $r.ctx.textAlign = 'center';
    $r.actual_size = $r.r_size + $r.r_thickness;
    $r.countdown_to_time = new Date($r.countdown_to).getTime();
    $r.cvs.css({ width: $r.size.w+"px", height: $r.size.h+"px" });
    $r.go();
  },
  ctx: null,
  go: function(){
    var idx=0;
    
    $r.time = (new Date().getTime()) - $r.countdown_to_time;
    
    
    for(var r_key in $r.rings) $r.unit(idx++,r_key,$r.rings[r_key]);      
    
    setTimeout($r.go,$r.update_interval);
  },
  unit: function(idx,label,ring) {
    var x,y, value, ring_secs = ring.s;
    value = parseFloat($r.time/ring_secs);
    $r.time-=Math.round(parseInt(value)) * ring_secs;
    value = Math.abs(value);
    
    x = ($r.r_size*.5 + $r.r_thickness*.5);
    x +=+(idx*($r.r_size+$r.r_spacing+$r.r_thickness));
    y = $r.r_size*.5;
    y += $r.r_thickness*.5;

    
    // calculate arc end angle
    var degrees = 360-(value / ring.max) * 360.0;
    var endAngle = degrees * (Math.PI / 180);
    
    $r.ctx.save();

    $r.ctx.translate(x,y);
    $r.ctx.clearRect($r.actual_size*-0.5,$r.actual_size*-0.5,$r.actual_size,$r.actual_size);

    // first circle
    $r.ctx.strokeStyle = "rgba(89,89,89,0.3)";
    $r.ctx.beginPath();
    $r.ctx.arc(0,0,$r.r_size/2,0,2 * Math.PI, 2);
    $r.ctx.lineWidth =$r.r_thickness;
    $r.ctx.stroke();
   
    // second circle
    $r.ctx.strokeStyle = "rgba(242, 9, 56, 0.9)";
    $r.ctx.beginPath();
    $r.ctx.arc(0,0,$r.r_size/2,0,endAngle, 1);
    $r.ctx.lineWidth =$r.r_thickness;
    $r.ctx.stroke();
    
    // label
    $r.ctx.fillStyle = "#5e5c5c";
   
    $r.ctx.font = '10px Helvetica';
    $r.ctx.fillText(label, 0, 23);
    $r.ctx.fillText(label, 0, 23);   
    
    $r.ctx.font = 'bold 35px Helvetica';
    $r.ctx.fillText(Math.floor(value), 0, 10);
    
    $r.ctx.restore();
  }
}

Open in new window

If <body onload="ringer.init()">  is not working than change to

<body onload="ringer.init"> and check result.
Hi,
User generated image
On IE11

on chrome no error but fails to load the countdown
If you are testing on IE 11 then don't test on Chrome.

Add following line above your script tag

<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>

CTRL+F5 to test again on IE 11 only
Hi, OK have done all as described and also tries the <body onload="ringer.init"> variants.
The one above give no error, but no countdown either
Any Error on browser console?
None on the above, if:

<body onload="ringer.init()">
User generated image
Change

$r.ctx = $r.cvs.getContext('2d');
$r.ctx.textAlign = 'center';

To

$r.cvs = $r.cvs.getContext('2d');
$r.cvs .textAlign = 'center';

and see the result. This is a typo mistake, I think done by your Champ.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.