jQuery .click() works on every browser but Safari

2019-01-13 15:32发布

问题:

I have a piece of JavaScript that dynamically creates an A tag inside of an existing div and then calls the jQuery function "click" on it. This works as intended in all browsers except Safari.

Safari returns the following error:

'undefined' is not a function (evaluating '$('.shell a')[0].click()')

Any ideas on what I'm doing wrong or why this doesn't work in Safari and how to get it to work (or one piece of code that works in all browsers) I've tried using .trigger("click") as well and it gives the same error.

JavaScript

function writeAndClickLink(url) {

    $('.shell').html('<a href="' + url + '"></a>');
    $('.shell a')[0].click();
}

and in the HTML:

<div class="shell"></div>

The reason I'm doing it this weird way is the function is called from a Flash site to open a twitter window where I am giving a reward for tweeting. This so far has been the only way I could get the "tweet" event to bind to the window. If I open the window any other way (window.open for example) it doesn't capture the bound event that lets me know they actually completed the tweet.

The flow is something like:

  • User clicks tweet button in flash
  • Flash calls javascript function to dynamically write href and "click" it
  • Twitter window opens
  • User successfully tweets
  • Tweet event is captured and updates flash with success
  • Content is unlocked in flash

回答1:

var a = $('.shell a')[0];
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent('click', true, true, window);
a.dispatchEvent(evObj);

See http://www.howtocreate.co.uk/tutorials/javascript/domevents (search for "Manually firing events").



回答2:

Trevor Dixon's answer does fix Safari, but breaks in even the latest Firefox:

TypeError: Not enough arguments to MouseEvent.initMouseEvent

The best way to support Safari—without breaking Firefox—would be using initEvent instead of initMouseEvent like so:

var element = document.getElementById('your_id_here');
if(element.click)
    element.click();
else if(document.createEvent)
{
    var eventObj = document.createEvent('MouseEvents');
    eventObj.initEvent('click',true,true);
    element.dispatchEvent(eventObj);
}

To update for 2016, MouseEvent should be used instead of initMouseEvent which is deprecated:

var eventObj = new MouseEvent("click", {
    bubbles: true,
    cancelable: true
});
element.dispatchEvent(eventObj);


回答3:

$('.shell a')[0] gets a DOM object out of the jQuery object. That DOM object only has DOM methods (not jQuery methods) and there is no industry standard .click() method on an <a> element until HTML5 and it is not yet implemented in every browser - thus you will see incomplete implementation across difference browsers.

You have a couple choices. The first option gets a jQuery object and uses the .click() method on the jQuery object. This will only work reliably if you are triggering jQuery click handlers, not if you just want the default click for the <a> tag.

function writeAndClickLink(url) {

    $('.shell').html('<a href="' + url + '"></a>');
    $('.shell a').eq(0).click();
}

Or, if clicking the URL is just going to go to a new web page, don't even bother modifying the DOM and just set window.location as there is no point in modifying the DOM at all if you're just going to a new web page:

function writeAndClickLink(url) {
    window.location = url;    
}


回答4:

$('.shell a')[0] returns the native DOM element which dosn't have jQuery methods bound to it

Remove the "[0]" to keep the jQuery object in order to use jQuery methods

 $('.shell a').click()