Prevent Events from OnClick Event

Hello all

I am trying to get some JavaScript to work where I am passing an object as the function parameter. This part of the code works well. Now what I am trying to do is prevent other events from firing once this href is clicked. My situation is I have a table row that has an onlick event. Part of the data in the table row contains an href. If the user clicks this href, I do not want to table rows onclick event to fire.
In the past, if I included the few lines of code below, it would prevent other events from firing. I tried adding this code to a condition where I am dynamically building the onclick event for the href but it is not working. Both events fire but I only want the events from the Test1 and Test2 links to fire. I do not want the TR event that displays “Display Message” to alert the user.

Any feedback on what I am doing wrong here? Attached is an example.

Thank you in advance for your time.


<html>
<head>
    <title>Test</title>
    <script type="text/javascript">
	
	function objectX() {
		var foo = "";
		
		this.setFoo = function( newFoo ) {
			foo = newFoo;
		};
   	
		this.getFoo = function() {
			return foo;
		};
	}

	function testObj() {
		var content = document.getElementById('content');
		content.innerHTML = '<table><tr onClick="javascript:displayMessage();"><td><a href="#" id="Test1">Test 1</a></td><td><a href="#" id="Test2">Test 2</a></td></tr></table>';
		
		for( var i = 1; i < 3; i++ ) {
			var obj = new objectX();
			obj.setFoo( "Test " + i );

			// pass obj as an argument and receive it as a parameter
			// in order to keep a private reference to its current value
			document.getElementById("Test" + i).onclick = createTestClickHandler( "href", obj );
		}
	}
	
	function createTestClickHandler( event, obj ) {
		return function () {
			//-- Cross browser way to get event
			var evt = event || window.event;
			//-- Causes events to buggle up, a href goes first
			evt.stopPropagation ? evt.stopPropagation() : evt.cancelBubble = true;
			//-- Prevents other events from firing
			evt.preventDefault ? evt.preventDefault() : evt.returnValue = false;
			
			alert( "event: " + evt );
			
			testPassObj(obj);
		};
	}
	
	function testPassObj( obj ) {
		alert( "object: " + obj.getFoo() );
	}
	
	function displayMessage() {
		alert( "Display Message" );
	}

    </script>
</head>
<body onLoad="testObj();">
	<div id="content"></div>
</body>
</html>

Hi there,

You are very nearly there, just a simple matter of four brackets.

Change this:

function createTestClickHandler( event, obj ) {
  return function () {
    //-- Cross browser way to get event
    var evt = event || window.event;
    //-- Causes events to buggle up, a href goes first
    evt.stopPropagation ? evt.stopPropagation() : evt.cancelBubble = true;
    //-- Prevents other events from firing
    evt.preventDefault ? evt.preventDefault() : evt.returnValue = false;
    alert( "event: " + evt );
    testPassObj(obj);
  };
}

into this:

function createTestClickHandler( event, obj ) {
  return function () {
    //-- Cross browser way to get event
    var evt = event || window.event;
    //-- Causes events to buggle up, a href goes first
    evt.stopPropagation() ? evt.stopPropagation() : evt.cancelBubble = true;
    //-- Prevents other events from firing
    evt.preventDefault() ? evt.preventDefault() : evt.returnValue = false;
    alert( "event: " + evt );
    testPassObj(obj);
  };
}

Notice the brackets after evt.stopPropagation and evt.preventDefault in the ternary conditionals.

HTH

Thank you for the response… when I add brackets to evt.stopPropagation() and evt.preventDefault(), I get a JavaScript error stating evt.stopPropagation is not a function. I am using FireFox to test. I will continue researching but appreciate feedback if someone sees a silly mistake that I am making.

Oh, I didn’t test on FF, but would be surprised if it didn’t work. I’ll check it out in a bit.

Hi,

Just tested on Firefox (latest version).
When I click on either “Test 1” or “Test 2”, I see a “Display Message” alert which is fired by this <tr onClick="javascript:displayMessage();">.
Which is what I was thinking was meant to happen due to this line here: evt.preventDefault() ? evt.preventDefault() : evt.returnValue = false;

No, I do not want to TR onclick event to fire. With this example, I know it looks weird. I have a multi row TR and some of the data in the TR are HREFs so if the user clicks on the HREF, I do not want the TR onclick event to fire. So I only want the Test1 or Test2 messages to display, not Display Message. Sorry I made this confusing.

<tr onClick="javascript:displayMessage();">.

Is there some particular reason why onclick has been spelt incorrectly with an uppercase C and why there is a JavaScript label that never gets referenced from anywhere in front of the actual JavaScript command.

If you are going to jumble the JavaScript in with the HTML instead of placing it all together in a separate JavaScript file then at least write it properly:

<tr onclick="displayMessage();">

Also the code to prevent other events firing is more likely to work if you attach the events from within the JavaScript as event listeners rather than hard coding them in the HTML as event handlers.

Hi,

I know I’m probably missing some use case in your application, but the following code would do what you want.

function objectX() {
  var foo = "";
  
  this.setFoo = function( newFoo ) {
    foo = newFoo; 
  };
  
  this.getFoo = function() {
    return foo;
  };
}

function testObj() {
  var content = document.getElementById('content');
  content.innerHTML = '<table><tr onclick="javascript:displayMessage();"><td><a href="#" id="Test1">Test 1</a></td><td><a href="#" id="Test2">Test 2</a></td></tr></table>';
  
  for( var i = 1; i < 3; i++ ) {
    var obj = new objectX();
    obj.setFoo( "Test " + i );
  
    document.getElementById("Test" + i).onclick = function(e){
      testPassObj(obj);
      if(e && e.stopPropagation) {
        e.stopPropagation();
      } else {
        e = window.event;
        e.cancelBubble = true;
      }
    }
  }
}

function testPassObj( obj ) {
  alert( "object: " + obj.getFoo() ); 
}

function displayMessage() {
  alert( "Display Message" );
}

As far as I could see, the trouble was coming from passing in “href” as a parameter to the ‘createTestClickHandler’ method.
This is a string and does not respond to stopPropagation

It works!!! Your post triggered a thought in my mind and I was misplacing where to include the event parameter. The code I posted is calling a function to return the code for another function. Event needed to be added in the function that was being called by the onclick event.

Thank you for the feedback!!!

Here is what I mean (notice event was added as a parameter for the function):


return function (event) {
//-- Cross browser way to get event
	var evt = event || window.event;
	alert( "event: " + evt );
			
	//-- Causes events to buggle up, a href goes first
        evt.stopPropagation() ? evt.stopPropagation() : evt.cancelBubble = true;
	//-- Prevents other events from firing
	evt.preventDefault() ? evt.preventDefault() : evt.returnValue = false;
			
	testPassObj(obj);
};

Here is the complete code.


<html>
<head>
    <title>Test</title>
    <script type="text/javascript">
	
	function objectX() {
		var foo = "";
		
		this.setFoo = function( newFoo ) {
			foo = newFoo;
		};
   	
		this.getFoo = function() {
			return foo;
		};
	}

	function testObj() {
		var content = document.getElementById('content');
		content.innerHTML = '<table><tr onClick="javascript:displayMessage();"><td><a href="#" id="Test1">Test 1</a></td><td><a href="#" id="Test2">Test 2</a></td></tr></table>';
		
		for( var i = 1; i < 3; i++ ) {
			var obj = new objectX();
			obj.setFoo( "Test " + i );

			// pass obj as an argument and receive it as a parameter
			// in order to keep a private reference to its current value
			document.getElementById("Test" + i).onclick = createTestClickHandler( obj );
		}
	}
	
	function createTestClickHandler( obj ) {
		return function (event) {
			//-- Cross browser way to get event
			var evt = event || window.event;
			alert( "event: " + evt );
			
			//-- Causes events to buggle up, a href goes first
			evt.stopPropagation() ? evt.stopPropagation() : evt.cancelBubble = true;
			//-- Prevents other events from firing
			evt.preventDefault() ? evt.preventDefault() : evt.returnValue = false;
			
			testPassObj(obj);
		};
	}
	
	function testPassObj( obj ) {
		alert( "object: " + obj.getFoo() );
	}
	
	function displayMessage() {
		alert( "Do not display this message" );
	}

    </script>
</head>
<body onLoad="testObj();">
	<div id="content"></div>
</body>
</html>

Hey, cool!
I’m glad you got things working.
Thanks, too, for taking the time to follow up.

Felgall, I am sorry I missed your comment earlier. I was hoping you could expand on your comments in regards to attaching the events within the JavaScript as event listeners rather than hard coding them in the HTML as event handlers. How would I do that?