event.preventDefault() не работает

у меня есть эта строка кода, на мой взгляд, с помощью Telerik Grid:

      columns.Bound(o => o.URI).Width(10).Sortable(false)
                .ClientTemplate("<A class='btnGrid' id=source<#= ID #> onclick=GridSelection.addItem('<#= ID #>') >Add</A>").Title("").Width(50);

JS-коды функций GridSelection addItem и disableSelected:

  GridSelection = {
      addItem: function (value) {

         var anchorOption = $("a[id=source" + value + "]");

         anchorOption.click(function (e) { // variable name changed from "event"
               e.preventDefault();
               return false;    // as suggested by mr. Hamdi
               });

         anchorOption.fadeTo("slow", .5);

         GridSelection.disableSelected(anchorOption, true);

         var data = $("#GridSource").data('tGrid').data;
         var selectedObject;
         for (var item in data) {
            if (data[item].ID == value) {
               selectedObject = data[item];
               break;
            }
         }

          var grid = $("#GridSelected").data('tGrid');
          var newData = $("#GridSelected").data('tGrid').dataSource._data;
          newData.push(selectedObject);
          grid.dataBind(newData);
          grid.sort("");
          anchorOption.fadeTo("slow", .5);
      },

      disableSelected: function (element, disable) {
              //false on IEs 6, 7 and 8
              if (!$.support.leadingWhitespace) {
                  if (disable) {
                      $(element).attr('disabled', 'disabled');
                  } else {
                      $(element).removeAttr('disabled');
                  }
              }
     },
         // other GridSelection subfunctions here...

Когда я запускаю веб-приложение MVC3 в IE, оно работает хорошо благодаря функции GridSelection.disableSelected, но в Chrome и Mozilla Firefox event.preventDefault(); не работает. Якорная ссылка по-прежнему добавляет элемент данных даже после того, как пользователь уже добавил его туда.

Можно ли использовать метод preventDefault внутри функции GridSelection.addItem, которая блокировалась?

Какой атрибут запрещен preventDefault , это href или onclick?

Что не так с этим? Как я могу исправить эту ошибку? Любой, кто может помочь?


person ideAvi    schedule 24.02.2012    source источник
comment
Насколько вы уверены, что обработчик кликов вообще вызывается? anchorOption.fadeTo("slow", .5); работает?   -  person nnnnnn    schedule 24.02.2012
comment
Это тоже один из моих импульсов. У меня есть приложение Developer Tools, которое я использую при отладке своего приложения. Я добавил точки останова на строки кода скриптов, чтобы знать, проходит ли он эти строки, и это так.   -  person ideAvi    schedule 24.02.2012
comment
@nnnnnn: пожалуйста, смотрите мои добавленные вопросы в моем отредактированном посте. Благодарность   -  person ideAvi    schedule 24.02.2012
comment
Вы проверили консоль ошибок в Mozilla? Есть ли ошибка? Можете ли вы добавить строку предупреждения перед e.preventDefault();, чтобы убедиться, что функция вызывается.   -  person Hamdi    schedule 24.02.2012
comment
Вы забыли поставить точку с запятой после return false. Это не должно выдавать ошибки, но стоит попробовать.   -  person Hamdi    schedule 24.02.2012
comment
извините за это, это опечатка здесь в моем посте, но не в моем коде;)   -  person ideAvi    schedule 24.02.2012
comment
@Hamdi: спасибо за хороший совет по отладке, я добавил предупреждение (Foo) до и после вызова функции, а также до и после .preventDefault(). Все они выскочили, поэтому каждая строка была прочитана, но функция, которую нужно предотвратить, не предотвратила.   -  person ideAvi    schedule 24.02.2012
comment
Ну теперь я как-то понял вашу проблему. Что произойдет, если вы удалите оператор if if (!$.support.leadingWhitespace) в функции disableSelected. Вы просто будете иметь тело этого состояния   -  person Hamdi    schedule 24.02.2012
comment
Я печатал свой ответ, пока вы редактировали свой пост, и чисто случайно я думаю, что ответил на ваши дополнительные вопросы. Но я не уверен, что мой ответ действительно решит вашу проблему - пожалуйста, уточните, как на самом деле вызывается ваша функция GridSelection.addItem() (и как она связана с функцией .verify() в разметке).   -  person nnnnnn    schedule 24.02.2012
comment
Я очень извиняюсь за эту опечатку. Мое приложение должно предотвращать .addItem(), а не .verify(). .verify() было одним из моих предыдущих решений, то есть создать отдельную функцию, которая будет вызываться в onclick. Но я удалил его и решил не иметь его. Мои извинения еще раз.   -  person ideAvi    schedule 24.02.2012


Ответы (4)


В разметке вашей ссылки есть встроенный обработчик кликов и нет href:

<A class='btnGrid' id=source<#= ID #> onclick=GridSelection.verify('<#= ID #>') >Add</A>

Если вы пытаетесь предотвратить GridSelection.verify(), обратите внимание на следующее:

  1. Встроенный обработчик кликов, вероятно, вызывается до вашего другого обработчика событий, что означает, что уже слишком поздно отменять его из вашего другого обработчика, и в любом случае
  2. e.preventDefault() не останавливает запуск других обработчиков, он останавливает действие по умолчанию для события, которое для ссылки заключается в переходе к URL-адресу, указанному в атрибуте href. И вы не указываете href.

Если вы хотите иметь несколько обработчиков для одного и того же события в одном и том же элементе, вы должны назначить их все с помощью jQuery в том порядке, в котором вы хотите, чтобы они вызывались, а затем использовать event.stopImmediatePropagation() method в одном из обработчиков, если вы хотите остановить выполнение остальных.

Я не знаю, как вписать это в код, который вы показали, учитывая, что вы не показываете часть кода, которую хотите предотвратить, но общий принцип таков:

<a id="myLink" href="someURL">My link</a>

<script>
$("#myLink").click(function(e) {
    // some processing
    if (someCondition)
       e.stopImmediatePropagation();
    // some other processing
});

$("#myLink").click(function(e) {
    // some processing
});
</script>

Сказав все это, если функция .verify() вызывает вашу функцию .addItem(), и вы намерены предотвратить работу будущих событий щелчка по той же ссылке, потому что первый щелчок должен подтвердить/добавить, а затем вы не хотите иметь возможность добавлять снова, тогда в вашей функции .addItem() сделайте что-то вроде этого:

anchorOption.removeAttr("onclick");
// or
anchorOption[0].onclick = null;
person nnnnnn    schedule 24.02.2012
comment
Это было точно. Но где я должен поставить preventDefault() ? я должен поместить это в .addItem()still? или я должен поместить его в другой обработчик событий за пределами .addItem()? - person ideAvi; 24.02.2012
comment
С обновленной версией вопроса я бы сказал, что вы вообще не хотите preventDefault() или stopImmediatePropagation(), и вам не следует создавать обработчик click внутри addItem(), как вы делаете сейчас, потому что это не поможет. Попробуйте код из самого конца моего ответа и посмотрите, что произойдет — идея состоит в том, чтобы отключить существующий обработчик кликов, который был установлен с помощью встроенного атрибута onclick в вашем html. - person nnnnnn; 24.02.2012

Вы пытались добавить return false; вместо event.preventDefault();

person Hamdi    schedule 24.02.2012
comment
На самом деле вы можете добавить оператор return false; после event.preventDefault();. Вам не нужно удалять event.preventDefault(); - person Hamdi; 24.02.2012
comment
Спасибо, я пытался добавить его в свой код, но все равно это ничего не меняет. - person ideAvi; 24.02.2012
comment
Это действительно странно. Раньше я сталкивался с той же проблемой и возвращал false; работал на меня. - person Hamdi; 24.02.2012
comment
пожалуйста, смотрите мой обновленный пост. Я добавил несколько вопросов, которые меня беспокоят, возможно, вы могли бы помочь мне ответить на них. - person ideAvi; 24.02.2012

Вы пытались переименовать переменную события? назовите меня сумасшедшим, но я, кажется, помню, что у меня были проблемы, просто попробуйте function(e) {e.preventDefault();} и посмотрите, что произойдет

person Mike L.    schedule 24.02.2012
comment
Ты сумасшедший. (Если серьезно, это тоже был мой первый порыв.) - person nnnnnn; 24.02.2012
comment
да. Спасибо, но это было первое имя, которое я использовал для переменной события, и оно все еще не работало. - person ideAvi; 24.02.2012

Если якорь имеет id, используйте селектор идентификатора вместо использования его в качестве селектора атрибута.

Изменять

$("a[id=source" + value + "]")

To

$("#source" + value)

Я не говорю, что это проблема, но вы можете попробовать изменить это.

Обновление:

event.preventDefault() останавливает браузер для перехода по ссылке, установленной в атрибуте href элемента привязки. Это не предотвратит и не остановит событие click.

person ShankarSangoli    schedule 24.02.2012
comment
Спасибо, но это не проблема, потому что я использовал этот синтаксис и в других своих функциях, и он просто работает с ним. - person ideAvi; 24.02.2012