473,703 Members | 2,333 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Assigning dynamically declared event handlers to an object

Hello

I am new to creating objects in javascript, so please no flames about my
coding style. =) I am trying to create an object that will represent a "div"
element as a menu. I have written several methods that are working fine. The
problem is if I want to dynamically assign an event handler to the object,
the event handler is not called. What am I doing wrong? Below is a sample
HTML doc with everything in place.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">

<html>

<head>
<title>Menu Manager Test</title>
<script>
function testMenu (id)
{
this.addAttribu tes = addProperty;
this.addEvents = addProperty;

this.id = (id || 'mainMenu');
this.element = document.getEle mentById(this.i d);
if (this.element == null)
{
this.element = document.create Element("<div id='" + this.id +
"'>Some Text</div>");
document.body.a ppendChild(this .element);
}
this.element.st yle.display = 'none';
}

function addProperty(pro pertyName,keyVa lue)
{
// this is a standalone property like an event or innerHTML
if (propertyName.i ndexOf("=") >= 0)
{
for (var i=0;i<addProper ty.arguments.le ngth;i++)
{
var arg = addProperty.arg uments[i].split("=");
this.element[arg[0]] = arg[1];
}
}
// this adds style elements
else
{
// args should be in the form of propertyname=va lue.
for (var i=1;i<addProper ty.arguments.le ngth;i++)
{
var arg = addProperty.arg uments[i].split("=");
this.element[addProperty.arg uments[0]][arg[0]] = arg[1];
}
}
}

// Sample implementation in the HTML page

// Test function to check for use.
function testFunc()
{alert("here in testFunc.");}

var menuObj;
function setMenu(id)
{
// Create a new menu
menuObj = new testMenu(id);
// Adding a style works
menuObj.addAttr ibutes("style", "width=200" );
menuObj.addAttr ibutes("style", "backgroundColo r=green");
menuObj.addAttr ibutes("style", "color=whit e");
menuObj.addAttr ibutes("style", "border=1px solid black");
menuObj.addAttr ibutes("style", "textAlign=cent er");
menuObj.addAttr ibutes("style", "position=absol ute");
menuObj.addAttr ibutes("style", "zindex=100 0");
menuObj.addAttr ibutes("style", "top=200");
menuObj.addAttr ibutes("style", "left=300") ;
menuObj.addAttr ibutes("innerHT ML=A ball of string");
menuObj.addAttr ibutes("style", "display=") ;
// Dynamically assigning an event handler does not work.
menuObj.addEven ts("onmouseover =testFunc()");
menuObj.addEven ts("onmouseout= testFunc()");
}
</script>
</head>

<body onLoad="setMenu ('mainMenu');">
</body>
</html>

Peace in Christ -
Ron Goral
Nov 17 '06 #1
7 2529
Daz

Ron Goral wrote:
Hello

I am new to creating objects in javascript, so please no flames about my
coding style. =) I am trying to create an object that will represent a "div"
element as a menu. I have written several methods that are working fine. The
problem is if I want to dynamically assign an event handler to the object,
the event handler is not called. What am I doing wrong? Below is a sample
HTML doc with everything in place.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">

<html>

<head>
<title>Menu Manager Test</title>
<script>
function testMenu (id)
{
this.addAttribu tes = addProperty;
this.addEvents = addProperty;

this.id = (id || 'mainMenu');
this.element = document.getEle mentById(this.i d);
if (this.element == null)
{
this.element = document.create Element("<div id='" + this.id +
"'>Some Text</div>");
document.body.a ppendChild(this .element);
}
this.element.st yle.display = 'none';
}

function addProperty(pro pertyName,keyVa lue)
{
// this is a standalone property like an event or innerHTML
if (propertyName.i ndexOf("=") >= 0)
{
for (var i=0;i<addProper ty.arguments.le ngth;i++)
{
var arg = addProperty.arg uments[i].split("=");
this.element[arg[0]] = arg[1];
}
}
// this adds style elements
else
{
// args should be in the form of propertyname=va lue.
for (var i=1;i<addProper ty.arguments.le ngth;i++)
{
var arg = addProperty.arg uments[i].split("=");
this.element[addProperty.arg uments[0]][arg[0]] = arg[1];
}
}
}

// Sample implementation in the HTML page

// Test function to check for use.
function testFunc()
{alert("here in testFunc.");}

var menuObj;
function setMenu(id)
{
// Create a new menu
menuObj = new testMenu(id);
// Adding a style works
menuObj.addAttr ibutes("style", "width=200" );
menuObj.addAttr ibutes("style", "backgroundColo r=green");
menuObj.addAttr ibutes("style", "color=whit e");
menuObj.addAttr ibutes("style", "border=1px solid black");
menuObj.addAttr ibutes("style", "textAlign=cent er");
menuObj.addAttr ibutes("style", "position=absol ute");
menuObj.addAttr ibutes("style", "zindex=100 0");
menuObj.addAttr ibutes("style", "top=200");
menuObj.addAttr ibutes("style", "left=300") ;
menuObj.addAttr ibutes("innerHT ML=A ball of string");
menuObj.addAttr ibutes("style", "display=") ;
// Dynamically assigning an event handler does not work.
menuObj.addEven ts("onmouseover =testFunc()");
menuObj.addEven ts("onmouseout= testFunc()");
}
</script>
</head>

<body onLoad="setMenu ('mainMenu');">
</body>
</html>

Peace in Christ -
Ron Goral
Hi Ron.

I am a complete novice, but I will give you my 2 cents anyway.

First of all, I would recommend you save yourself a little bit of
bandwidth, and consider using CSS as opposed to:
menuObj.addAttr ibutes("style", "width=200" );
menuObj.addAttr ibutes("style", "backgroundColo r=green");
menuObj.addAttr ibutes("style", "color=whit e");
menuObj.addAttr ibutes("style", "border=1px solid black");
menuObj.addAttr ibutes("style", "textAlign=cent er");
menuObj.addAttr ibutes("style", "position=absol ute");
menuObj.addAttr ibutes("style", "zindex=100 0");
menuObj.addAttr ibutes("style", "top=200");
menuObj.addAttr ibutes("style", "left=300") ;
(This is not a flame, just a suggestion that might make life a little
easier).

As for the mouse events...

I can think of two mthods (which I cannot vouch for), that you may wish
to consider trying.
Firstly:
menuObj.addEven ts("onmouseover =function() { testFunc(); }");
menuObj.addEven ts("onmouseout= function() { testFunc(); }");

Secondly you could try:
menuObj.onmouse over=function() { testFunc(); }
menuObj.onmouse out=function() { testFunc(); }

Again, I can't stress enough how much of a beginner I am, but I think
it's worth a try.

I think the second one is most likely to work, but I can't be sure.
Please note, I have enclosed the function you wish to use within a
function(){} statement. I believe that if this isn't done, then the
function will be called as the script is loaded, and not actually
assigned to the event.

Best of luck.

Daz.

Nov 17 '06 #2

"Daz" <cu********@gma il.comwrote in message
news:11******** **************@ j44g2000cwa.goo glegroups.com.. .
Hi Ron.

I am a complete novice, but I will give you my 2 cents anyway.

First of all, I would recommend you save yourself a little bit of
bandwidth, and consider using CSS as opposed to:
menuObj.addAttr ibutes("style", "width=200" );
menuObj.addAttr ibutes("style", "backgroundColo r=green");
menuObj.addAttr ibutes("style", "color=whit e");
menuObj.addAttr ibutes("style", "border=1px solid black");
menuObj.addAttr ibutes("style", "textAlign=cent er");
menuObj.addAttr ibutes("style", "position=absol ute");
menuObj.addAttr ibutes("style", "zindex=100 0");
menuObj.addAttr ibutes("style", "top=200");
menuObj.addAttr ibutes("style", "left=300") ;
(This is not a flame, just a suggestion that might make life a little
easier).
I appreciate the suggestion. The idea of the addAttributes and addEvents
functions is to allow a person to define the menu in an HTML page without
accessing the .js file (where this will finally reside).
>
As for the mouse events...

I can think of two mthods (which I cannot vouch for), that you may wish
to consider trying.
Firstly:
menuObj.addEven ts("onmouseover =function() { testFunc(); }");
menuObj.addEven ts("onmouseout= function() { testFunc(); }");
This ^ does not work.
Secondly you could try:
menuObj.onmouse over=function() { testFunc(); }
menuObj.onmouse out=function() { testFunc(); }
This ^ does work.
Unfortunately, when the object code resides in a .js file, this is not going
to be feasible as I want the HTML author to be able to define the event in a
"<script></script>" block in his code.
Again, I can't stress enough how much of a beginner I am, but I think
it's worth a try.

I think the second one is most likely to work, but I can't be sure.
Please note, I have enclosed the function you wish to use within a
function(){} statement. I believe that if this isn't done, then the
function will be called as the script is loaded, and not actually
assigned to the event.
This does indeed happen.

Thank you for the suggestions. I am further along the road of understanding,
however, I am certain there must be a way to do this. I can't be the first
or only person to ever want to do this sort of thing. Am I? ;P

Peace -
Ron
Nov 17 '06 #3

"Daz" <cu********@gma il.comwrote in message
news:11******** **************@ j44g2000cwa.goo glegroups.com.. .
>
As for the mouse events...

I can think of two mthods (which I cannot vouch for), that you may wish
to consider trying.
Firstly:
menuObj.addEven ts("onmouseover =function() { testFunc(); }");
menuObj.addEven ts("onmouseout= function() { testFunc(); }");

Secondly you could try:
menuObj.onmouse over=function() { testFunc(); }
menuObj.onmouse out=function() { testFunc(); }

Again, I can't stress enough how much of a beginner I am, but I think
it's worth a try.

I think the second one is most likely to work, but I can't be sure.
Please note, I have enclosed the function you wish to use within a
function(){} statement. I believe that if this isn't done, then the
function will be called as the script is loaded, and not actually
assigned to the event.
eval() is the key. =)
The code considered the arguments being passed as strings. Of course, a
string cannot be executed, unless you use eval().

Using these modified calls:

menuObj.addEven ts("event","onm ouseover=functi on() { testFunc(); }");
menuObj.addEven ts("event","onm ouseout=functio n() { testFunc(); }");

And (greatly) modifying the addProperty function to be this:

function addProperty(pro pertyName,keyVa lue)
{
var type = (propertyName.i ndexOf("=") >= 0)?'standalone' :propertyName;
for (var i=0;i<addProper ty.arguments.le ngth;i++)
{
var arg = addProperty.arg uments[i].split("=");
// something like innerHTML
if (type == 'standalone'){t his.element[arg[0]] = arg[1];}
// an event property
else if (type == 'event'){this.e lement[arg[0]] = eval("function( ){"
+ arg[1] + "}");}
// style and other named attributes
else {this.element[addProperty.arg uments[0]][arg[0]] = arg[1];}
}
}

Produces the desired results. =)

Thanks for the help Daz.
Peace -
Ron
Nov 17 '06 #4

"Ron Goral" <ne**@uponthemo untain.comwrote in message
news:qx******** *********@newss vr25.news.prodi gy.net...

This:

this.element[arg[0]] = eval("function( ){"+arg[1]+"}");

Should be this:

this.element[arg[0]] = function(){eval (arg[1]);};
Nov 17 '06 #5
Daz

Ron Goral wrote:
"Ron Goral" <ne**@uponthemo untain.comwrote in message
news:qx******** *********@newss vr25.news.prodi gy.net...

This:

this.element[arg[0]] = eval("function( ){"+arg[1]+"}");

Should be this:

this.element[arg[0]] = function(){eval (arg[1]);};
Yes indeed. Does that mean it's working now?

Nov 18 '06 #6
Daz

Ron Goral wrote:
"Daz" <cu********@gma il.comwrote in message
news:11******** **************@ j44g2000cwa.goo glegroups.com.. .

As for the mouse events...

I can think of two mthods (which I cannot vouch for), that you may wish
to consider trying.
Firstly:
menuObj.addEven ts("onmouseover =function() { testFunc(); }");
menuObj.addEven ts("onmouseout= function() { testFunc(); }");

Secondly you could try:
menuObj.onmouse over=function() { testFunc(); }
menuObj.onmouse out=function() { testFunc(); }

Again, I can't stress enough how much of a beginner I am, but I think
it's worth a try.

I think the second one is most likely to work, but I can't be sure.
Please note, I have enclosed the function you wish to use within a
function(){} statement. I believe that if this isn't done, then the
function will be called as the script is loaded, and not actually
assigned to the event.

eval() is the key. =)
The code considered the arguments being passed as strings. Of course, a
string cannot be executed, unless you use eval().

Using these modified calls:

menuObj.addEven ts("event","onm ouseover=functi on() { testFunc(); }");
menuObj.addEven ts("event","onm ouseout=functio n() { testFunc(); }");

And (greatly) modifying the addProperty function to be this:

function addProperty(pro pertyName,keyVa lue)
{
var type = (propertyName.i ndexOf("=") >= 0)?'standalone' :propertyName;
for (var i=0;i<addProper ty.arguments.le ngth;i++)
{
var arg = addProperty.arg uments[i].split("=");
// something like innerHTML
if (type == 'standalone'){t his.element[arg[0]] = arg[1];}
// an event property
else if (type == 'event'){this.e lement[arg[0]] = eval("function( ){"
+ arg[1] + "}");}
// style and other named attributes
else {this.element[addProperty.arg uments[0]][arg[0]] = arg[1];}
}
}

Produces the desired results. =)

Thanks for the help Daz.
Peace -
Ron
Glad to have helped. Well done for figuring it out. :D

Nov 18 '06 #7
I wish to share this routine (for which I must lookup the source...)

function addEvent(obj, evType, fn){
var res;
if (obj.addEventLi stener) {
obj.addEventLis tener(evType, fn, false);
res = true;
} else if (obj.attachEven t) {
var r = obj.attachEvent ("on"+evType , fn);
res = r;
} else {
res = false;
}
return res;
}

obj is an HTMLElement; evType is a string like "click"; fn is a function
reference.

Let me elaborate on that last remark. This is a function definition:

function doWork(arg) {
alert(arg);
}

This is a corresponding function call:

doWork("'ello") ;

and this is the function reference:

doWork;

If you want to assign any function to a property like onclick, you must
assign the reference to the property:

thatDiv.onclick = doWork;

Alas, you cannot pass parameters to the function this way. Built-in
behaviour, nonetheless, is for the browser to pass the current event to
the function. Any event handling function should accept an event object
(unless you absolutely want to ignore the identity of the event, or do
not need its information). There is a little cross-browserity on it.
Microsofts browser does not pass the event, but has a global variable
'event' which carries the current event.

Lumping this together, your event handler function could look like

function doWork(e) {
if (!e) e = window.event;
// now you can be sure that e points to the current event object

// do whatever is necessary here
}

If you would put this:

thatDiv.onclick = doWork(argument );

doWork would be evaluated/executed, and its *result* is assigned to
onclick. Needless to say this will produce no effect when you actually
would click the element...

I have one other remark. When I create objects (classes, I like to call
them), I always include a private variable 'self' that is a copy of
'this'. It saves a lot of confusion as to what exactly this refers to,
when you are inside an object's functions.

function myObject() {
var self = this;

self.value = 0; // public member

// not really necessary here:
self.someMethod = functionname;

// nor here:
self.otherMetho d = function(arg) {
// function body
self.value = 23; // 'this' would point to the function otherMethod!
}
}

This style may save you several "this.metho d is not a function" errors.

Ron Goral schreef:
Hello

I am new to creating objects in javascript, so please no flames about my
coding style. =) I am trying to create an object that will represent a "div"
element as a menu. I have written several methods that are working fine. The
problem is if I want to dynamically assign an event handler to the object,
the event handler is not called. What am I doing wrong? Below is a sample
HTML doc with everything in place.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">

<html>

<head>
<title>Menu Manager Test</title>
<script>
function testMenu (id)
{
this.addAttribu tes = addProperty;
this.addEvents = addProperty;

this.id = (id || 'mainMenu');
this.element = document.getEle mentById(this.i d);
if (this.element == null)
{
this.element = document.create Element("<div id='" + this.id +
"'>Some Text</div>");
document.body.a ppendChild(this .element);
}
this.element.st yle.display = 'none';
}

function addProperty(pro pertyName,keyVa lue)
{
// this is a standalone property like an event or innerHTML
if (propertyName.i ndexOf("=") >= 0)
{
for (var i=0;i<addProper ty.arguments.le ngth;i++)
{
var arg = addProperty.arg uments[i].split("=");
this.element[arg[0]] = arg[1];
}
}
// this adds style elements
else
{
// args should be in the form of propertyname=va lue.
for (var i=1;i<addProper ty.arguments.le ngth;i++)
{
var arg = addProperty.arg uments[i].split("=");
this.element[addProperty.arg uments[0]][arg[0]] = arg[1];
}
}
}

// Sample implementation in the HTML page

// Test function to check for use.
function testFunc()
{alert("here in testFunc.");}

var menuObj;
function setMenu(id)
{
// Create a new menu
menuObj = new testMenu(id);
// Adding a style works
menuObj.addAttr ibutes("style", "width=200" );
menuObj.addAttr ibutes("style", "backgroundColo r=green");
menuObj.addAttr ibutes("style", "color=whit e");
menuObj.addAttr ibutes("style", "border=1px solid black");
menuObj.addAttr ibutes("style", "textAlign=cent er");
menuObj.addAttr ibutes("style", "position=absol ute");
menuObj.addAttr ibutes("style", "zindex=100 0");
menuObj.addAttr ibutes("style", "top=200");
menuObj.addAttr ibutes("style", "left=300") ;
menuObj.addAttr ibutes("innerHT ML=A ball of string");
menuObj.addAttr ibutes("style", "display=") ;
// Dynamically assigning an event handler does not work.
menuObj.addEven ts("onmouseover =testFunc()");
menuObj.addEven ts("onmouseout= testFunc()");
}
</script>
</head>

<body onLoad="setMenu ('mainMenu');">
</body>
</html>

Peace in Christ -
Ron Goral

--
Bas Cost Budde
Holland
www.heuveltop.nl/BasCB/msac_index.html
Nov 18 '06 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
3327
by: Thomas | last post by:
Hi, I'm having a problem with the dynamically created inputfields in Internet Explorer. The situation is the following: - I have a dynamically created table with a textbox in each Cell. - It is possible to Add and Delete rows - Some cells have special attributes (readonly and events) Here's a snippet of the code:
9
3085
by: Christopher Weaver | last post by:
Can anyone tell me how I could iterate through a collection of controls on a form while assigning their event handlers to another identical collection of controls on the same form. So far, thanks to another programmer, I've got this working out quite nicely for the properties: Type ctrlType = subject.GetType(); ConstructorInfo cInfo = ctrlType.GetConstructor(Type.EmptyTypes); Control retControl = (Control)cInfo.Invoke(null);
1
8161
by: Earl Teigrob | last post by:
PROBLEM: When a user control is loaded into a PlaceHolder control more than once, the events do not fire on the first click of a control on the dynamically loaded user control. In other words, the first time the control is dynamically loaded, everything works fine. After that, if the control is loaded again from the page button event handler, the user controls events fail to fire on the first click NOTE: I (believe I) am rebuilding all...
1
1664
by: Greg | last post by:
In my ASP.NET application I have a button that when pressed, data needs to be saved based on what the user typed in. I have other controls on the same page that should be updated as a result of the save, which are all dynamically created in the code behind and have event handlers registered. In the page life cycle, event handlers are called after the page is loaded. The problem is, the save is done after the controls are loaded, so the...
2
5203
by: Nathan Sokalski | last post by:
I would like to access variables and functions that I declare in the Global.asax.vb file. However, I am having trouble doing that. What does the declaration have to look like in the Global.asax.vb file, and what would I do to access it? (I am using VB.NET for my code) Thanks. -- Nathan Sokalski njsokalski@hotmail.com http://www.nathansokalski.com/
15
6625
by: Iced Crow | last post by:
In C# I know that you can use delegates to assing multiple addresses of sub and functions to a delegate and have it fire multiple procedures... How do I do this in VB? I only know of assigning a single method to a delegate in VB.NET. I want to use it as in C#... to fire multiple events. Thanks in advance!
2
3290
by: MLS | last post by:
The documentation on dynamic handlers comes across as abiguous. Perhaps somebody could help set me straight? I have a situation where I need to dynamically create several usercontrols of the same type within a form. This usercontrol has some events associated with it. For example: Private Sub NewThingy()
13
3506
by: Charles Law | last post by:
Mr "yEaH rIgHt" posted the following link about a week ago in answer to my question about removing event handlers. > http://www.vbinfozine.com/t_bindevt.shtml Following on from that post, the following issues still exist. The article shows how to find methods on a receiver that match the pattern OnXXXX given the sender. It loops through the sender events and tries to get methods from the receiver that match the pattern. For each one...
4
2881
by: bjjnova | last post by:
I need help dynamically resetting an event handler. I have a form with several buttons. I have intialized the Click event of a particular button thus on the form: _button_3.Click += new EventHandler(the_controller.onButton3Click_NewEE); On the same form, I am establishing a property so that I can reset the Click event from another class (first part of my question: how do I
0
8758
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9121
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9017
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8962
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6588
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5922
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4432
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4687
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3123
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.