Reputation: 27899
Given the following jQuery function.
$(document).on("click", ".subMenu>a", function(event) {
$(this).closest("a").attr("href", "../public_resources/Category.jsf?id=5").trigger('click');
});
This function is called, when a <span>
inside an <li>
like as follows is clicked.
<li class="ui-widget ui-menuitem ui-corner-all ui-menu-parent subMenu" role="menuitem" aria-haspopup="true">
<a href="../public_resources/Category.jsf?id=5" class="ui-menuitem-link ui-submenu-link ui-corner-all" tabindex="-1">
<span class="ui-menuitem-icon ui-icon ui-icon-contact"></span><span class="ui-menuitem-text">Occassion</span>
</a>
</li>
As can be seen, the given jQuery function is mapped by a CSS class subMenu
(in <li>
). When this function is called (it is called, when an area enclosed by the <li>
tag is clicked), the anchor tag is given a desired URL in this function which in turn, triggers a click event which causes the same function to be invoked once again - ultimately causing an infinite recursion with the following error.
Uncaught RangeError: Maximum call stack size exceeded
Is there any way to avoid this recursion, probably by rewriting the function somehow?
The HTML code given here is generated by a UI framework and it is very unlikely to touch it.
I could use window.location
instead of using .trigger('click')
but when a user click a sub menu by holding the ctrl key, for example, the page should be opened in a new tab. This does not happen by using window.location
.
Upvotes: 0
Views: 2543
Reputation: 324650
This function is called, when a
<span>
inside an<li>
like as follows is clicked.
No it isn't, and that's the fatal flaw in your code.
$(document).on("click", ".subMenu>a", function(event) {
Your code is called when the <a>
is clicked, not the <span>
. And since you're triggering a click on the link, the event handler is called again. And again. And again, until you run out of stack space. Stack overflow!
To fix, just fix your selector: .subMenu>a>span
Upvotes: 1
Reputation: 33870
With .trigger
, you can pass an argument. Try something like this :
$(document).on("click", ".subMenu>a", function(event, _ISTRIGGER_) {
if(_ISTRIGGER_) return;
$(this).closest("a").attr("href", "../public_resources/Category.jsf?id=5").trigger('click', true);
});
But be aware, .trigger
doesnt active the default behavior. Doing
$(this).closest("a").attr("href", "../public_resources/Category.jsf?id=5")[0].click();
will active it.
Upvotes: 0
Reputation: 16068
Try using this:
var a=0;
$(document).on("click", ".subMenu>a", function(event) {
a++;
if(a<=1){
$(this).closest("a").attr("href", "../public_resources/Category.jsf?id=5").trigger('click');
}else{
a--;
}
});
If you do not want to involve global variables, you can use:
$(document).on("click", ".subMenu>a", function(event) {
if($(this).attr('data-clicked')) return true;
$(this).closest("a").attr("href", "../public_resources/Category.jsf?id=5").attr('data-clicked',true).trigger('click');
});
Upvotes: 0
Reputation: 2511
Trigger the click with javascript it will bypass the handler:
$(this).closest("a").attr("href", "www.google.com")[0].click();
Upvotes: 2