代码之家  ›  专栏  ›  技术社区  ›  Jhong

javascript如何稍后触发本机单击操作(重播事件)?

  •  3
  • Jhong  · 技术社区  · 14 年前

    我使用jquery绑定到页面上的所有链接(我使用的是“click”事件,但是尝试了“mousedown”和“mouseup”的各种组合,以及bind()和live()都没有用)。

    我可以截取点击没有问题(用以上所有方法)。我要做的是通过GET请求发送一些数据,当它完成时,允许默认的单击操作继续。

    由于我正在跨域通信,所以必须使用get而不是post,因此不能进行同步调用。

    因此,我必须从截获的click事件返回“false”,将事件存储起来以备将来使用,然后在通信完成后再次手动触发它。如果我返回true,那么当页面位置更改时,通信将在中途中断。

    问题是,我找不到一种方法可以稍后触发本机单击事件。

    var storedEvent;
    $("#wrapper a").bind('click', function(event, processed) {
        $(event.target).unbind('click'); // temporary to make code branching easier
        storedEvent = event.target;
        event.stopPropagation();
    
        $.ajax({
            dataType: 'jsonp',
            data: linkData,
            jsonp: 'cb',
            url: 'xxx',
            cache: false,
            complete: function(response) {
                // How do I now go back and fire the native click event here?
                $(storedEvent).click();
            }
        });
        return false;
    }
    

    我试过在指定的地方使用click()和trigger(),但都不起作用。

    我知道提交是成功的,代码正确地进行了分支——到目前为止我已经调试过了。我好像不能重播这件事。

    注意,我不能做一些简单的事情,比如稍后存储href和set window.location——一些链接有自己的onclicks集,而其他链接则指定了不同的目标。理想情况下,我只想重播我之前停止的活动。

    我开始在live()中使用事件委托,除此之外一切都正常工作——我已经将其简化为bind(),以便简化问题。

    3 回复  |  直到 7 年前
        1
  •  0
  •   redsquare    14 年前

    您不能在锚上触发一个单击事件并让它跟随href cross browser。

        2
  •  1
  •   Diego V    7 年前

    最新答案: 是的,你可以 (假设您不再支持IE8)。

    使用 dispatchEvent() 开火 原始事件的副本 .

    首先,您需要一个实用程序函数来克隆事件(由于安全原因,浏览器只允许调度一次事件):

    var cloneNativeMouseEvent = function (original) {
        var copy;
        try {
            copy = new MouseEvent(original.type, original);
        } catch (stupidInternetExplorer) {
            copy = document.createEvent('MouseEvent');
            copy.initMouseEvent(original.type, original.bubbles, original.cancelable, original.view,
                original.detail, original.screenX, original.screenY, original.clientX, original.clientY,
                original.ctrlKey, original.altKey, original.shiftKey, original.metaKey, original.button,
                original.relatedTarget)
        }
        return copy;
    };
    

    在您的单击处理程序中,存储对jquery事件的引用以供以后重播:

    $("#wrapper a").bind('click', function (event) {
        event.preventDefault();
        storedEvent = event;
        ...
    }
    

    最后,在要再次触发单击的回调中,执行以下操作:

    var originalEventClone = cloneNativeMouseEvent(storedEvent.originalEvent);
    storedEvent.target.dispatchEvent(originalEventClone);
    

    请注意,通常,由javascript创建或修改的事件被用户代理标记为“不受信任”,因此它们无法触发默认操作。幸运地 点击 事件是唯一的例外。 (1)

        3
  •  0
  •   Community CDub    8 年前

    事实证明,红夸尔基本上是正确的——如果不把你的头发扯下来,它就不起作用。

    是问题所在。DispatchEvent()在Firefox中工作正常。在IE中,您可以选择FireEvent来触发任何关联的事件(但不是单击),或者选择Click()(对于单击,但不是事件),但不能同时正确地执行这两个操作。

    我临时更改链接的href和目标,以便在iframe中加载空白页,从而“几乎可以工作”。然后我监听iframe“加载”事件,以确定链接的默认操作是否发生。在IE中,如果需要的话,我可以启动“click”,或者在更改完href和target后,启动“fireevent”。

    然而,这是一个太多的黑客——如果其中一个链接有一个绑定的事件依赖于存在的href属性呢?(Thickbox似乎继续工作,但我认为这是一种比赛条件)。

    最后我根本不需要这么做( JavaScript/jQuery: How to make sure cross-domain click tracking event succeeds before the user leaves the page? )所以我松了一口气。事实证明,在这种情况下,我不得不使用post。