Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-9085] iOS: "this" value in event listener is set to child component when child component is clicked

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2012-09-12T04:07:28.000+0000
Affected Version/sRelease 2.1.0
Fix Version/sSprint 2012-15 Core, Release 3.0.0
ComponentsiOS
Labelscore, module_view, qe-review, qe-testadded
ReporterFederico Casali
AssigneeNeeraj Gupta
Created2012-04-27T13:27:46.000+0000
Updated2013-11-07T05:52:33.000+0000

Description

Problem

"this" value in event listener is set to child component when child component is clicked.

Steps to reproduce

var win = Ti.UI.createWindow({
    backgroundColor: '#000',
    navBarHidden: true
});
 
var view = Ti.UI.createView({ width: '100%', height: '100%', backgroundColor: '#f00' });
 
view.addEventListener('click', function(e){
    Ti.API.info('View click');
    Ti.API.info(this);
});
var button = Ti.UI.createButton({width:150, height:150, title: 'Click me!' });

view.add(button);
win.add(view);

win.open();
Result: Click on the button and see the output. "this" value produces "[object TiUIButton]". Expected result: "this" inside event listener should point to UI object to which that listener is attached (the output should produce "[object TiUIView]"). This works as expected on Android.

Comments

  1. Stephen Tramer 2012-07-17

    Technically both of these behaviors are incorrect according to the JavaScript standard. The this object in a callback should always refer to the callback function itself.
  2. Ivan Skugor 2012-07-18

    Hi Stephen. I don't think that is true. "this" inside function depends on a context from which function is called (if it is not called as a constructor). I don't think it can ever be a function itself. Detailed explanation of "this" value inside function code can be found here: http://dmitrysoshnikov.com/ecmascript/chapter-3-this/#this-value-in-the-function-code Things can get tricky when host objects are involved because nothing is specified. But, if we check how things are implemented in DOM environment, we can see that behavior is exact as this ticket describes:
       <html>
       
       	<head>
       		<title>Test</title>
       		<script type="text/javascript">
       			window.onload = function() {
       
       				var btn = document.getElementById("btn");
       
       				btn.addEventListener('click', function() {
       					alert(this);
       				}, false);
       
       			}
       		</script>
       	</head>
       
       	<body id="main">
       		<button id="btn">Click me!</button>
       	</body>
       
       </html>
       
    If you run this in some browser (except older IEs :D ) and you click on a button, you'll get alert dialog with message: [object HTMLButtonElement] If event is attached to the "body" of HTML document (change to this: var btn = document.getElementById("main"); ) and button is clicked, alert dialog message is: [object HTMLBodyElement] I tested in latest Chrome. That seems like the case this ticket describes. Logically, event listener should be attached to host object and "this" value inside that listener should always reference that host object.
  3. Max Stepanov 2012-07-19

    PR merged https://github.com/appcelerator/titanium_mobile/pull/2593
  4. Anshu Mittal 2012-09-12

    Reopening to update labels
  5. Shameer Jan 2013-11-07

    Anvil testcase PR https://github.com/appcelerator/titanium_mobile/pull/4887

JSON Source