如何处理HTMLElement.Click()无声地失败

时间:2017-09-01 13:13:23

标签: javascript html dom

我使用类似于this answer的代码通过ajax实现了文件下载按钮。我的代码看起来像这样:

$('#download-link').on('click', function (event) {
    event.preventDefault();
    var link = $('#download-link').attr('href');
    $.ajax({
        url: link,
        success: function (result) {

            var blob = getBlob(result);
            var a = document.createElement('a');
            var url = (window.URL ? URL : webkitURL).createObjectURL(blob);
            a.href = url;
            a.download = 'somefilename.txt';
            a.style.display = 'none';
            document.body.appendChild(a);                       
            try {
                a.click();
            }
            catch (err) {
                //fallback. if .click() is unavailable display a new button for user to get file.
                a.style.display = '';
                a.innerText = 'Get File';
                var downloadButton = document.getElementById('download-link');
                downloadButton.style.display = 'none';
            }
        }
    });
});

基本上,我们正在创建一个对象URL,使用对象URL的Href创建一个<a>元素,并在该元素上调用Click()来下载该文件。有些浏览器会在此时抛出错误,因此作为后备,我们会捕获错误并显示创建的按钮,以便用户可以按下并获取文件。

问题是某些浏览器(似乎在iOS上,而旧版本的Android)会忽略Click()调用。我知道我可以使用浏览器嗅探来解决这个问题,但我不认为这是一个非常好的解决方案。我能做些更优雅的事情来发现这种情况并使用我的后备吗?

2 个答案:

答案 0 :(得分:2)

您可以创建一个标志来检查您的脚本是否能够触发click事件。听取点击并翻转标志,并在一段时间后处理没有检测到点击的情况。

        a.href = url;
        a.download = 'somefilename.txt';
        a.style.display = 'none';
        var linkClicked = false;
        a.addEventListener('click',()=>linkClicked = true);
        document.body.appendChild(a);                       
        a.click();
        setTimeout(()=>{
            if(!linkClicked){
            //fallback. if .click() is unavailable display a new button for user to get file.
            a.style.display = '';
            a.innerText = 'Get File';
            var downloadButton = document.getElementById('download-link');
            downloadButton.style.display = 'none';
            }
        },500);

另一个解决方案是始终显示链接,但链接文本就行了#34;如果您的下载没有开始,请点击此处&#34;

答案 1 :(得分:0)

@Professor Allman已经通过检测.click()功能提供了一个优雅的解决方案,而不是嗅探浏览器。

为了使代码更易于使用,我想重构代码,添加缓存并将其包装为单个函数:

function hasClickFeature(callback) {
  if (window.hasAnchorClickFeature !== undefined) {
    callback(window.hasAnchorClickFeature);
  }

  var a = document.createElement('a');
  var hasClick = false;
  a.href='javascript:;';
  a.style.display = 'none';
  a.addEventListener('click', function() {
    hasClick = true;
    window.hasAnchorClickFeature = hasClick;
    callback(hasClick);
  });
  document.body.appendChild(a);
  a.click();
  setTimeout(function() {
    if (!hasClick) {
      window.hasAnchorClickFeature = hasClick;
      callback(hasClick);
    }
  }, 500);
}

hasClickFeature(function(hasClick) {
  console.log(hasClick);
});