Tiny
Tiny

Reputation: 27899

Uncaught RangeError : Maximum call stack size exceeded

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

Answers (4)

Niet the Dark Absol
Niet the Dark Absol

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

Karl-Andr&#233; Gagnon
Karl-Andr&#233; Gagnon

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

juvian
juvian

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

Wilmer
Wilmer

Reputation: 2511

Trigger the click with javascript it will bypass the handler:

$(this).closest("a").attr("href", "www.google.com")[0].click();

Upvotes: 2

Related Questions