2014-10-10 2 views
2

Я пытаюсь изменить форму работы плагина Jira Tempo. Таким образом, на странице временного листа у меня есть кнопка, у которой есть 2 действия с привязкой, один - действие щелчка, а одно - фокус. действие click открывает всплывающее окно. и фокус проверяет форму во всплывающем окне. Мне нужно, чтобы действие клика выполнялось первым, а затем фокус.Как переопределить event.stopPropagation(), preventDefault(). StopImmediatePropagation()

Проблема заключается в том, когда всплывающее окно открывается, есть вызов для всех трех функций. event.stopPropagation().preventDefault().stopImmediatePropagation(); поэтому фокус не срабатывает в хромированном состоянии.

В IE10 и Firefox отлично работает.

Могу ли я переопределить основную функцию jQuery event.stopPropagation().preventDefault().stopImmediatePropagation(), чтобы не применять эту кнопку? все три, может быть?

Я попытался это:

(function() { 
jQuery.Event.prototype = { 
    isDefaultPrevented: returnFalse, 
isPropagationStopped: returnFalse, 
isImmediatePropagationStopped: returnFalse, 
    stopPropagation: function() { 
     if (jQuery('#tempo-plan-button').hasClass(this.currentTarget.className)) { 

     } else { 
      var e = this.originalEvent; 

      this.isPropagationStopped = returnTrue; 

      if (e && e.stopPropagation) { 
       e.stopPropagation(); 
      } 
     } 
    }, 
    preventDefault: function() { 
     if (jQuery('#tempo-plan-button').hasClass(this.currentTarget.className)) { 

     } else { 
      var e = this.originalEvent; 

      this.isDefaultPrevented = returnTrue; 

      if (e && e.preventDefault) { 
       e.preventDefault(); 
      } 
     } 
    }, 
    stopImmediatePropagation: function() { 
     if (jQuery('#tempo-plan-button').hasClass(this.currentTarget.className)) { 

     } else { 
      var e = this.originalEvent; 

      this.isImmediatePropagationStopped = returnTrue; 

      if (e && e.stopImmediatePropagation) { 
       e.stopImmediatePropagation(); 
      } 

      this.stopPropagation(); 
     } 
    } 

}; 
function returnFalse() { 
    return false; 
} 
function returnTrue() { 
    return true; 
} 
})(); 

UPDATE:

У меня нет контроля над что функция делает щелчок, но у меня есть контроль над фокусом, я сделал некоторые испытания, и я похоже, что Chrome не видит фокусное событие, потому что элемент скрыт до того, как произойдет фокус (это кнопка всплывающего окна). Мне удалось вызвать мои функции с помощью мыши, но это не работает в IE, поэтому мне нужно связать отдельный прослушиватель событий для IE и Chrome, Firefox, Safari. Можете ли вы помочь с некоторыми примерами обнаружения браузера.

UPDATE 2:

Моя проблема решена с другим слушателем на всплывающей элемента. ex:

jQuery(document).ready(function ($) { 
var currentUser = null; 
var selected = null; 
var opened = null; 
var formOpened = null; 
var activityField = null; 
var activitySelected = null; 
var popupBody = null; 
var formOpened = null; 
var periodCheckbox = null; 
var dateField = null; 
var endDateField = null; 
var plannedHours = null; 
var periodselected = null; 
var days = 1; 
var startdate = 0; 
var enddate = 0; 
var planButton = $('#tempo-plan-button'); 
//this is the default LM-Holiday activity ID set this 
value to corespond with the value on jira tempo form. 
var holidayid = "10100"; 
var holidaysLeft = 21; /* 
$('#tempo-plan-button').click(function() { 
alert("click event"); 
}); 
$('#tempo-plan-button').focusin(function() { 
alert("focus event"); 
}); 
$('#tempo-plan-button').hover(function() { 
alert("hover event"); 

}); 
$('#tempo-plan-button').mouseleave(function() { 
alert("mouse leave event"); 

}); 
$('#tempo-plan-button').mouseout(function() { 
alert("mouse out event"); 

}); */ 
$('body').one('focus', 'div[class="aui-popup aui-dialog"]', function (event) { 
    $('div[class="aui-popup aui-dialog"]').each(function() { 
     popupBody = $(this).find(".dialog-components"); 
     if ($(this).find(".dialog-title").hasClass("tempo-add-button") === false) { 
      i = 0; 
      j = 0; 
      $(popupBody).find(".dialog-page-menu li").each(function() { 
       if ($(this).attr("class") === "page-menu-item selected") { 
        button = $(this).find('.item-button'); 
        if ((button).text() === "Internal") { 
         selected = i; 
        } 
       } 
       i++; 
      }); 
      $(popupBody).find(".dialog-panel-body").each(function() { 
       if ($(this).is(":visible")) { 
        opened = j; 
        formOpened = $(this).find('form'); 
       } 
       j++; 
      }); 
      if (selected === null) { 
       i = 0; 
       j = 0; 
       $(popupBody).find(".dialog-page-menu li").click(function() { 
        $(popupBody).find(".dialog-page-menu li").each(function() { 
         if ($(this).attr("class") === "page-menu-item selected") { 
          button = $(this).find('.item-button'); 
          if ((button).text() === "Internal") { 
           selected = i; 
          } 
         } 
         i++; 
        }); 
        $(popupBody).find(".dialog-panel-body").each(function() { 
         if ($(this).is(":visible")) { 
          opened = j; 
          formOpened = $(this).find('form'); 
         } 
         j++; 
        }); 
        if (selected === opened) { 
         activityField = $(formOpened).find('.tempo-activity-picker.select'); 
         periodCheckbox = $(formOpened).find('.showperiod.tempo-show-period'); 
         dateField = $(formOpened).find(' input[name="date"]'); 
         endDateField = $(formOpened).find('input[name="enddate"]'); 
         plannedHours = $(formOpened).find('input[name="time"]'); 
         days = 1; 
         $(activityField).change(function() { 
          activitySelected = $(this).val(); 
         }); 

         $(periodCheckbox).change(function() { 
          if ($(this).prop("checked")) { 
           periodselected = true; 
          } 
          else 
          { 
           periodselected = false; 

          } 
         }); 
         $(dateField).change(function() { 
          if (periodselected) { 
           startdate = parseDate($(this).val()); 
           enddate = parseDate($(endDateField).val()); 
          } else { 
           days = 1; 
          } 
          ; 
         }); 
         $(endDateField).change(function() { 
          startdatestring = $(dateField).val(); 
          enddatestring = $(this).val(); 
          startdate = parseDate(startdatestring); 
          enddate = parseDate(enddatestring); 
         }); 
         $(plannedHours).off("focusin"); 
         $(plannedHours).focusin(function() { 
          if (activitySelected === holidayid) { 
           if (periodselected) { 
            days = calcBusinessDays(startdate, enddate); 

            if (holidaysLeft >= days) { 
             holidaysLeft = holidaysLeft - days; 
         alert("Mai ai " + holidaysLeft + " zile de concediu ramase!"); 
         $(popupBody).find('button[accesskey="s"]').removeAttr('disabled'); 
            } 
            else { 
     $(popupBody).find('button[accesskey="s"]').attr('disabled', 'disabled'); 
     alert('trebuie sa selectezi o perioada mai mica de' + holidaysLeft + 'de zile'); 
            } 
           } else 
           { 
            if (holidaysLeft >= days) { 
             holidaysLeft = holidaysLeft - days; 
           alert("Mai ai " + holidaysLeft + " zile de concediu ramase!"); 
         $(popupBody).find('button[accesskey="s"]').removeAttr('disabled'); 
            } 
            else { 
       $(popupBody).find('button[accesskey="s"]').attr('disabled', 'disabled'); 
       alert('trebuie sa selectezi o perioada mai mica de' + holidaysLeft + 'de zile'); 
            } 
           } 
          } 
         }); 
        } 
       }); 
      } else { 
       j = 0; 
       $(popupBody).find(".dialog-panel-body").each(function() { 
        if ($(this).is(":visible")) { 
         opened = j; 
         formOpened = $(this).find('form'); 
        } 
        j++; 
       }); 
       if (selected === opened) { 
        activityField = $(formOpened).find('.tempo-activity-picker.select'); 
        periodCheckbox = $(formOpened).find('.showperiod.tempo-show-period'); 
        dateField = $(formOpened).find(' input[name="date"]'); 
        endDateField = $(formOpened).find('input[name="enddate"]'); 
        plannedHours = $(formOpened).find('input[name="time"]'); 
        days = 1; 
        $(activityField).change(function() { 
         activitySelected = $(this).val(); 
        }); 

        $(periodCheckbox).change(function() { 
         if ($(this).prop("checked")) { 
          periodselected = true; 
         } 
         else 
         { 
          periodselected = false; 

         } 
        }); 
        $(dateField).change(function() { 
         if (periodselected) { 
          startdate = parseDate($(this).val()); 
          enddate = parseDate($(endDateField).val()); 
         } else { 
          days = 1; 
         } 
         ; 
        }); 
        $(endDateField).change(function() { 
         startdatestring = $(dateField).val(); 
         enddatestring = $(this).val(); 
         startdate = parseDate(startdatestring); 
         enddate = parseDate(enddatestring); 
        }); 
        $(plannedHours).off("focusin"); 
        $(plannedHours).focusin(function() { 
         if (activitySelected === holidayid) { 
          if (periodselected) { 
           days = calcBusinessDays(startdate, enddate); 

           if (holidaysLeft >= days) { 
            holidaysLeft = holidaysLeft - days; 
       alert("Mai ai " + holidaysLeft + " zile de concediu ramase!"); 
       $(popupBody).find('button[accesskey="s"]').removeAttr('disabled'); 
           } 
           else { 
         $(popupBody).find('button[accesskey="s"]').attr('disabled', 'disabled'); 
       alert('trebuie sa selectezi o perioada mai mica de' + holidaysLeft + 'de zile'); 
           } 
          } else 
          { 
           if (holidaysLeft >= days) { 
            holidaysLeft = holidaysLeft - days; 
           alert("Mai ai " + holidaysLeft + " zile de concediu ramase!"); 
         $(popupBody).find('button[accesskey="s"]').removeAttr('disabled'); 
           } 
           else { 
        $(popupBody).find('button[accesskey="s"]').attr('disabled', 'disabled'); 
      alert('trebuie sa selectezi o perioada mai mica de' + holidaysLeft + 'de zile'); 
           } 
          } 
         } 
        }); 
       } 
      } 
      ; 
     } 
     ; 
     return false; 
    }); 

    $.ajax({ 
     type: "GET", 
     url: location.protocol + '//' + location.host + "/rest/api/2/myself", 
     success: function (response) { 
      currentUser = $.parseJSON(response); 
     }, 
     error: function (response) { 
      alert("Eroare" + response.result); 
     } 
    }); 
    return false; 
}); 
}); 
function calcBusinessDays(dDate1, dDate2) { // input given as Date objects 
var iWeeks, iDateDiff, iAdjust = 0; 
if (dDate2 < dDate1) 
    return -1; // error code if dates transposed 
var iWeekday1 = dDate1.getDay(); // day of week 
var iWeekday2 = dDate2.getDay(); 
iWeekday1 = (iWeekday1 === 0) ? 7 : iWeekday1; // change Sunday from 0 to 7 
iWeekday2 = (iWeekday2 === 0) ? 7 : iWeekday2; 
if ((iWeekday1 > 5) && (iWeekday2 > 5)) 
    iAdjust = 1; // adjustment if both days on weekend 
iWeekday1 = (iWeekday1 > 5) ? 5 : iWeekday1; // only count weekdays 
iWeekday2 = (iWeekday2 > 5) ? 5 : iWeekday2; 

// calculate differnece in weeks (1000mS * 60sec * 60min * 24hrs * 7 days = 604800000) 
iWeeks = Math.floor((dDate2.getTime() - dDate1.getTime())/604800000); 

if (iWeekday1 <= iWeekday2) { 
    iDateDiff = (iWeeks * 5) + (iWeekday2 - iWeekday1); 
} else { 
    iDateDiff = ((iWeeks + 1) * 5) - (iWeekday1 - iWeekday2); 
} 

iDateDiff -= iAdjust // take into account both days on weekend 

return (iDateDiff + 1); // add 1 because dates are inclusive 
} 
function parseDate(s) { 
var lastSlash = s.lastIndexOf("/"); 
var years = s.substring(lastSlash + 1); 
years = "20" + years; 
s = s.replaceAt(lastSlash + 1, years); 
var pattern = /(.*?)\/(.*?)\/(.*?)$/; 
var result = s.replace(pattern, function (match, p1, p2, p3) { 
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 
'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; 
    return (months.indexOf(p2) + 1) + "/" + (p1) + "/" + p3; 
}); 
return new Date(result); 
} 
String.prototype.replaceAt = function (index, character) { 
return this.substr(0, index) + character + this.substr(index + character.length); 
}; 
function propStopped(event) { 
var msg = ""; 
if (event.isPropagationStopped()) { 
    msg = "called"; 
} else { 
    msg = "not called"; 
} 
alert(msg); 
} 

Спасибо.

+2

Я думаю, что это плохая практика, и ваш 'returnTrue' /' false' не имеет никакого смысла. –

+0

@Andreas Furster Я добавил те из библиотеки jQuery. Итак, эти три метода уже вызывается в событии on click, но я не могу его изменить. вместо этого я хочу переопределить их, чтобы не относиться к моему элементу # tempo-plan-Button. Спасибо. –

ответ

2

Вы имели в виду это?

Event.prototype.stopPropagation = function(){ alert('123') } 
 
$('input').on('click',function(e){ 
 
    e.stopPropagation(); 
 
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<input type='button' value='click' />

+0

Да @aleha, что-то в этом роде, но я не хочу, чтобы его исполняли. и у меня нет доступа к сценарию события клика. поэтому я не могу это изменить. а также все три метода вызывают в событии click. поэтому я должен пропустить все три для этой кнопки. –

+0

просто переопределить эти методы, используя объект Event.prototype для пустой функции, не поможет? 'Event.prototype.stopPropagation = function() {}' – aleha

+0

Нет, ничего не изменилось. –

1

От вопроса, то неясно, какой код вы контролируете. Я читаю строки, которые, возможно, вы контролируете функцию, связанную с событием клика для кнопки, но вы не контролируете функцию, связанную с событием фокуса, поэтому вам нужно обойти эти вызовы.

Если вы хотите контролировать выполнение событий и убедиться, что ваше первое произошло, это возможно сделать с чем-то вроде jQuery.bindUp, только если события одного типа. Таким образом, вас не волнует, пытается ли другой обработчик вызова stopPropagation и т. Д., Потому что ваш обработчик в любом случае сможет выполнить его.

Учитывая, что возможно ли реструктурировать ваш код так, чтобы контролируемая вами логика (часть, которая должна произойти первой!) Имеет тот же тип события, что и существующий обработчик событий, а затем использовать jQuery.bindUp для обеспечения что он выполняется перед обработчиком событий, который вы не контролируете? Вы можете по-прежнему привязываться к событию клика, если вам это нужно, только до тех пор, пока зависимая бизнес-логика перемещается в событие фокуса.

(Если мои предположения неверны, было бы полезно, если бы вы могли обновить вопрос для более подробного описания проблемных ограничений.)

+0

спасибо за ответ, но на самом деле моя проблема заключалась в том, что фокус не был обнаружен хром, и теперь мне нужно связать различный прослушиватель событий для каждого браузера. есть ли у вас пример, как обнаружить браузер и в соответствии с ним связывать разные прослушиватели событий? –

+0

@AlexRobert, людям было бы проще помочь вам, если вы изолируете проблему и, скажем, соедините jsfiddle, который демонстрирует точную проблему. Этот процесс может также привести вас к обнаружению проблемы самостоятельно! –

+0

Я могу только поместить мой код whitch вставлен в этот вопрос, другой код находится в платформе Atlassian Jira. и не может получить к нему доступ. Я решил проблему, используя другой прослушиватель событий. –

Смежные вопросы