Jquery Click () Ошибка - Недостаточно места в стеке - PullRequest
3 голосов
/ 26 марта 2012

Хорошо, я в тупике.У меня есть элемент управления, который состоит из таблицы.Я разрешаю пользователю щелкнуть гиперссылку в нижнем ряду, чтобы перейти непосредственно к связанному представлению.

С другой стороны, пользователь может щелкнуть в любом месте внутри таблицы и сделать выбор.Этот выбор активирует панель инструментов, которая позволяет пользователю выполнять некоторые задачи с выбранным элементом.Если пользователь снова щелкает выбранный элемент, я хочу программно щелкнуть гиперссылкуНо когда я запускаю jQuery для программного щелчка по гиперссылке, я получаю ошибку «Out of stack stack space».Я полностью осознаю, что событие click вызывается рекурсивно, но я не знаю, как его предотвратить!Вот мой код ...

<head runat="server">
<title></title>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

<style>
.mouseOver, .mouseOut, .selected
{
    width: 120px;
    height: 120px;
    text-align: center;
    vertical-align: top;
    display: inline-block;
    margin: 5px;
    cursor: pointer;

}
.mouseOver
{
    border: solid thin #99defd;
    background: #e9f8fe;
}
.mouseOut
{
    border: solid thin White;
}
.selected
{
    border: solid thin #e0a403;
    background: #f8f4de;
}
</style>

<script>
(function($) {
    $(document).ready(function() {
        var $items = $('.mouseOut');
        $items.mouseenter(function() {
            if ($(this).attr('class') != 'selected')
                $(this).attr('class', 'mouseOver');
        });
        $items.mouseleave(function() {
            if ($(this).attr('class') != 'selected')
                $(this).attr('class', 'mouseOut');
        });

        $items.click(function() {
            if ($(this).attr('class') == 'selected') {
                $(this).find('a').click();
            }
            else {
                $('.selected').attr('class', 'mouseOut');
                $(this).attr('class', 'selected');
            }
        });
    });
})(jQuery);
</script>
</head>
<body runat="server">
    <form id="form1" runat="server">
        <table cellpadding="5" class="mouseOut">
            <tr>
                <td>
                user module thumbnail...
                </td>
            </tr>
            <tr>
                <td>
                    <a id="A1" href="javascript:__doPostBack('ControlPanelHost1$cphCtrl0$lvCollectionView$ctrl0$lnkBtn','')">Users</a>
                </td>
            </tr>
        </table>

        <table cellpadding="5" class="mouseOut">
            <tr>
                <td>
                stats module thumbnail...
                </td>
            </tr>
            <tr>
                <td>
                    <a id="A2" href="javascript:__doPostBack('ControlPanelHost1$cphCtrl0$lvCollectionView$ctrl1$lnkBtn','')">Stats</a>
                </td>
            </tr>
        </table>
    </form>
</body>

Эта урезанная версия полностью продемонстрирует проблему.Спасибо всем, кто может помочь!

Ответы [ 3 ]

8 голосов
/ 26 марта 2012

Проблема в том, что запуск события click на потомке элемента также вызывает его на этом элементе, потому что событие всплывает в DOM-дереве.Поскольку ваш код вызывает событие click потомка при обработке того же самого события у его предка, возникает бесконечная рекурсия.

Чтобы обойти эту проблему, можно использовать stopPropagation () чтобы предотвратить всплывание событий click, вызванных вашими гиперссылками:

$(this).find("a").click(function(e) {
    e.stopPropagation();
});

РЕДАКТИРОВАТЬ: Однако приведенный выше код не будет работать должным образом, поскольку ваша логика также находитсяв обработчике событий предка.Мы можем переключить наш подход на проблему и использовать event.target с is () , чтобы инициировать событие click на нисходящей гиперссылке, только если событие, которое мы сейчас обрабатываем, былосрабатывает либо на элементе-предке, либо на потомке, который сам не является гиперссылкой:

$items.click(function(event) {
    if ($(this).attr('class') == 'selected' && !$(event.target).is("a")) {
        $(this).find('a').click();
    } else {
        $('.selected').attr('class', 'mouseOut');
        $(this).attr('class', 'selected');
    }
});
2 голосов
/ 27 марта 2012

По какой-то странной причине это решение работает.

Заменить:

$(this).find('a').click();

с:

window.location = $(this).find('a').attr('href');

Код, который предоставил Фредерик Хамиди, был великолепен, но функция click () никогда не отправлялась обратно на сервер.

0 голосов
/ 26 марта 2012

похоже, функция __doPostBack не определена, что может быть причиной вашей ошибки

...