Ninja杀死了一个Rogue JavaScript事件

时间:2014-01-21 22:23:06

标签: javascript jquery javascript-events

所以这是情节,这是一个真实的故事(一个真实的人存在的问题,就是 - 我):

您正在开发一个大型企业站点,其中包含大量JavaScript,特别是您无法控制的jQuery代码,并且无法更改(祝您好运甚至找不到谁编写,或者为什么) 。涉及到身份验证和权限的层次,所以只是假装它是用石头写的,你不能触摸它。

在此代码的某处,有一个事件在加载后将文档滚动到页面顶部。 “好吧,这听起来无害”人们可能会想到 - 但现在你的任务是根据查询字符串或锚点将页面滚动到特定项目。

一切正常,但当你点击一个链接到example.com/list#item11时,浏览器按预期工作,你直接进入你要链接的项目...然后,whammo ,页面立即跳回页面顶部。

现在,你可能会说“嗯,这就是document.ready()的用途!”......令你恐惧的是,你发现无论如何都会发生流氓事件。

在StackOverflow搜索甚至更晚的事件后,你会找到这个gem:

$(document).ready(function(e) {
  $(window).load(function(e){ });
}

当然,这肯定会奏效!只是,它没有。您尝试return falsee.preventDefault(),但这对您没有任何帮助。

所有你可以肯定的是,这个流氓滚动事件发生在你的代码运行之后,在DOM准备好之后,并且肯定在window.load()事件之后。你肯定没别的。

你可以暗杀这个流氓事件吗?是否有一些拦截滚动事件并防止它们发生的机制?你可以链接到一些事件以后的事件,比如“DOM准备就绪,窗口加载,页面安定,孩子们在床上,所有其他事件都在处理.... event()”?< / p>

我现在可以想象的唯一解决方案是“放弃 - 页面加载时的滚动行为在你的场景中不起作用”,“使用计时器等待!然后提交seppuku这样一个肮脏的黑客!”,和“忍者暗杀任务!” (因为我不知道是谁写了有问题的代码,我不得不满足于杀死他们的代码而不是他们 - 我确信他们有他们的理由,或者已经被暗杀......或者至少等待传递和做我的事情的代码。)

是否有一些更好的方法,一些难以找到的功能,一些最后的手段调用神秘的黑暗反射之王,或者是时候放弃并以另一种方式解决问题了?

TLDR;

1)当你无法更改导致它的代码时,如何阻止破坏性脚本事件(如滚动)?可接受的答案包括如何确保您的代码运行 - 不使用计时器黑客! - 和/或如果你的代码总是首先运行,你如何防止后来的代码弄乱你的?

2)了解事件的定义方式以及触发事件可能会有所帮助,但我觉得这是一个单独的问题,可能不一定需要修复这种情况。出于说明目的,假设有数千个活动事件和监听器分布在数十个缩小的脚本文件中。可能只是很难缩小究竟发生的事情,甚至尝试都太麻烦。

3 个答案:

答案 0 :(得分:2)

最好的解决方案是编辑宣布就绪事件的源代码。

如果你不能,你可以在其他地方复制这段代码并进行编辑。

如果它完全不可能,那么

你无法取消绑定就绪事件,因为这可能会导致问题。

你可以通过原型

覆盖window.scrollTop()函数
window.prototype.scrollTo2 = window.prototype.scrollTo;
window.prototype.scrollTo = function(){

  /*Look in the url if you have an hash tab*/
  // if yes return false
  //if not 
  window.prototype.scrollTo2()
};

答案 1 :(得分:1)

如果其他一切都失败,用计时器砸它们:

$(document).ready(function() {
    window.setTimeout(function() {
        document.location = "#bottom";
    }, 200);
});

Live test case

丑陋,但工作。

答案 2 :(得分:1)

我会挂钩window.scrollTo原型试图抓住行动中的窃贼。如果你知道它是如何完成的,那么摆脱它就更容易了。

如果这个流氓电话没有嵌入太大的JQuery goo中,它甚至可以追踪对最初罪魁祸首的召唤,这个罪魁祸首很快会被极大的报复和愤怒的愤怒所打击。