使用jQuery检测设备是否支持电话呼叫(支持“tel://”协议)

23

在我的网站上,我有几个链接如下:

<a href="tel://+12181112222" class="call">218.111.2222</a>

我想使用jQuery(或其他方法)来确定设备是否支持拨打电话/使用tel://协议。世界上是否存在这样的方法?

我想使用一些方法启用或禁用链接,因为在桌面上单击时,我们会进入一个页面,例如“Firefox不知道如何打开此地址,因为该协议(tel)未与任何程序关联。”

目前,我正在嗅探用户代理并检测它是否是移动设备。但是,是否有更好/准确的方法?类似于jQuery的$.support.xx

if ( (/iPhone|iPod|iPad|Android|BlackBerry/).test(navigator.userAgent) != true ){
    $(".call").attr("href", "#");
}

3
https://dev59.com/Kmct5IYBdhLWcg3wXsXH - dsgriffin
@Zenith,那个问题很相关,但它没有讨论如何检测包含 tel: 链接将起作用的方法。 - Pointy
@Zenith 谢谢,这很有帮助,但正如Pointy所提到的,它实际上并没有特别检测tel://是否受支持。这就是我想要实现的 - 用户代理测试,我已经处理好了...只是想知道/希望有更准确的描述设备是否能够处理tel:// - Patrick Moore
@SetSailMedia 对不起,我是想说别忘了看侧边栏(我没有投票关闭)。看看这个问题的评论 - https://dev59.com/U3LYa4cB1Zd3GeqPaay0?lq=1 - dsgriffin
这个问题也很相关:https://dev59.com/w3E85IYBdhLWcg3wPBB8,其中包含如何检查某些浏览器是否支持协议。 - Eric Beaulieu
4个回答

13

我不确定Android或BlackBerry,但iOS会自动接收电话号码并将其包装成如下所示的方式:<a href="tel:xxx"> xxx </a> ...因此您可以在某个地方放置一个隐藏的<div>,其中包含像1-800-555-5555这样的电话号码,然后在页面加载时执行以下操作:

var isTelephone = $("a[href*='tel:']").length > 0;

这可能(也可能不)适用于其他平台,您需要尝试一下。


Android似乎默认一系列数字是电话号码,并在点击时尝试拨打。 - Jez D
3
我知道我太晚了,但我找到了此篇文章,讨论哪些格式被哪种手机识别。你需要选择一个Android和iPhone都能识别的格式作为你隐藏的<div>号码,否则你的工作将徒劳无功! - Meshaal
这似乎不起作用。有人能创建一个测试页面,确保它可以正常工作吗?即使在头部有一个<meta name="format-detection" content="telephone=yes">标签,Google Chrome在Android上似乎仍会忽略<div>,即使它没有被隐藏。 - Talia
聪明的技巧。然而,如果您的页面显式创建了“tel:”链接,则应始终通过元标签将电话格式检测关闭。我发现用户代理检测在各种浏览器和设备上更可靠且具有未来性。 - Adam Leggett
Skype或其他类似软件可能是“tel:”协议的处理程序,因此这种方式不太好。通常情况下,当安装Skype时,它还会安装一些浏览器扩展,将几乎所有数字序列转换为“tel:”链接。 - SynCap

2
我使用下面的代码来检测一个非链接元素是否很可能是电话号码,并将其转化为tel链接:

在增强一个非链接元素之前,我用以下代码检测它是否为电话号码:

var probablyPhone = (
    (/iphone|android|ie|blackberry|fennec/).test
     (navigator.userAgent.toLowerCase())
     && 'ontouchstart' in document.documentElement
  );

我排除ipod|ipad,因为我知道它们不是手机

关键点在于很可能。当然,在某些平板设备上也会返回true,但这已足够满足我的需求了。在非手机触摸设备上,链接将无法正常工作-我主要想要排除桌面设备,因此使用了触摸事件检测。我想检查设备宽度也会缩小范围,但最终没有找到一种可靠的方法来检测能够进行电话呼叫的移动设备。


触摸事件可以通过软件方式模拟, Android、黑莓可以是平板电脑、电视、玩具、收音机等。 - SynCap
1
是的,但我几乎在4年前发布了那篇文章,我不建议在没有寻找更近期解决方案的情况下使用3年前的东西。 - rgb
我的评论不是回答你的问题,而是为那些从今天开始阅读这篇文章的人准备的。 对于那些日子来说,这个解决方案已经足够完美了。 - SynCap

2

可以尝试找到第一个包含tel://的href实例并发布ajax调用。如果成功,应该具有readyState为1,所以不做任何操作。失败时,查找所有包含tel://的href,并获取内部HTML并替换a标签。

这更像是一个假设,没有经过测试。

另一个想法是大多数浏览器都支持自定义电话号码格式化字符串,如果输入电话号码,则不需要创建a标签,因为它应该自动完成。


好的,对于不加标签的做法,你的看法很有趣。我之前认为即使它是自动添加的,也是最佳实践呢?我也会尝试你关于ajax的建议。 - JGallardo
在回答问题之前,最好至少进行最基本的测试,因为成千上万的人将花费时间阅读您的答案。:upside_down_smile:(是的,阅读完此评论后,它将自动销毁,所以为其他人节省时间...:wink:) - Simon B.
由于可以根据人们的计算机注册自定义协议,我不可能测试每种情况。有人可能已经在他们的计算机上注册了tel://,在这种情况下,ajax请求将返回一个readyState为1的状态。然而,点赞功能确实允许我们筛选可能的答案,找到最佳解决方案。至于测试场景,我已经在桌面/平板电脑上使用了其他自定义协议(而不是tel://)。 - ctatro85

1

一些有限的解决方案可以用来检测一些纯净的电话。但不是所有的都可以:

(function(a) {
 window.isPhone = /\bi?Phone\b|(?=.*\bAndroid\b)(?=.*\bMobile\b)|(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i.test(a);
})(navigator.userAgent || navigator.vendor || window.opera);

console.info('This device %s make phone calls', window.isPhone ? 'is originally intended to' : 'probably can\'t' );


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接