Javascript Stop TR Click Event On Dropdown Selection
Solution 1:
You need to capture click
event on <select>
and prevent its propagation:
function onSelectClick(ev) {
ev.stopPropagation();
}
<select onclick="onSelectClick">
or you can try to simply return false
for click
event for <select>
:
<select onclick="return false;">
Solution 2:
You can just check what element triggered the click, and if it was the drop down, ignore the event:
function check1(e) {
if (typeof e == "undefined")
e = window.event;
if (e.srcElement.id != "drop_down") {
alert("TR clicked");
}
}
If you want the JS to be more generic and not check for specific ID of elements, you can also change its logic to look for elements having a custom attribute defined:
function check1(e) {
if (typeof e == "undefined")
e = window.event;
if (e) {
var sourceElement = e.srcElement || e.target;
if (sourceElement) {
if (sourceElement.getAttribute("data-stop-propagation")) {
//element being clicked asked to ignore the event, abort
return;
}
}
}
alert("TR clicked");
}
To make it work with your code, change the HTML to this: (the value of the attribute doesn't matter)
<select name="" id="drop_down" onchange="check2();" data-stop-propagation="1">
Solution 3:
one more thing you can do is get event target,
function check1() {
if(this.event.target.nodeName!=='SELECT'){
alert("TR clicked");
}
}
to support in all browsers just capture event and pass it as param
<tr onclick=check1(event)>....</tr>
//in js
function check1(event) {
if(event.target.nodeName!=='SELECT'){
alert("TR clicked");
}
}
Solution 4:
Use addEventListener()
instead of inline attribute eventHandlers. At the end of the eventListener()
, or at the end of callback, add e.stopPropagation()
so the event never bubbles thereby never reaching <tr>
.
<tr>
will need to be referenced as it is relative to another table component such as <table>
or <td>
. Although inline attribute events stick to anything (including a <tr>
tag), it will become detrimental to maintaining such a layout (as I suspect it is already occurring). This is why it has been strongly suggested that addEventListener()
be used instead of inline events.
In the following demo:
If
<select>
is clicked the console logs its value.If a
<td>
is clicked then it logs a generic 'click'It will not log both at click event
All modern browsers are supported
Details commented in demo
Demo
var table = document.querySelector('table');
function chk() {
var drop = document.getElementById('drop');
var val = drop.value
console.log(val);
}
function rowLog() {
console.log('Clicked');
}
table.addEventListener('click', function(e) {
/* if the clicked element (e.target) is NOT
|| the element registered to listen for
|| click event (table) then...
*/
if (e.target !== e.currentTarget) {
/* if clicked element's #id is drop
|| call function chk()
*/
if (e.target.id === 'drop') {
chk();
/* Stop the event from bubbling (thereby
|| event never reaches TR if #drop is clicked)
*/
e.stopPropagation();
}
/* TR is tightly integrated with TD so
|| target TD or spicify TBODY or TABLE
|| to reference TR.
|| Note e.stopPropagation() is not invoked
|| in this function so click event will
|| bubble to <tr>
*/
else if(e.target.tagName === 'TD') {
rowLog();
}
}
}, false);
<table border=1>
<tr>
<td>My Options</td>
<td>
<select name="" id="drop">
<option></option>
<option value="A">A</option>
<option value="B">B</option>
</select>
</td>
</tr>
</table>
Solution 5:
I found this solution to work best for me:
<html>
<script>
function check1(event) {
// check if the event path contains the select element
// Not checking null values for simplicity
var preventFlag = event.path.filter(obj =>
obj.id.include('select')).length > 0
if(!preventFlag) {
// triggered only when preventFlag is false
alert("TR clicked");
}
}
function check2() {
alert("drop_down clicked");
}
</script>
<table border=1>
<tr onclick="check1(event);">
<td>My Options</td>
<td>
<select name="" id="drop_down" onchange="check2();">
<option value="A">A</option>
<option value="B">B</option>
</select>
</td>
</tr>
</table>
The good thing about this solution is that it works for all child elements inside the desired target element. For e.g, this logic works when a select element is clicked and it also works when any of the options inside the select element are clicked.
Downside: the path array needs to be looped through.
Post a Comment for "Javascript Stop TR Click Event On Dropdown Selection"