移动端UIWebView禁止选中的奇怪问题

最近在IOS客户端UIWebView里遇到禁用选中态的奇怪bug。

本文适用于,仅需要页面部分区域不可选中(比如我们的是一个小图标,span里面包着img),大部分文字都是可以被选中的(因为我们还有反馈错别字功能呀)。

首先说一下我们的场景:
有一个可以无限点击的按键,每次点击都会飞出来一个❤,对于看到这个按键又喜欢乱点的用户,当然会选择一通乱点啊。
于是bug就来了,快速点击会触发浏览器的双击选中事件。点击按键但是按键附近的文字总是动不动就被选中,对于一个有洁癖的程序员来说,这是不可接受的。
于是就引发了一系列的禁止选中态的问题。

先上结论,太长不想看粘走就行

-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;

如果以上代码没有解决你的禁止选中态的问题,你有两个选择:

  1. 更换到WKWebView,他里面双击不会选中。
  2. 使用js来禁掉一且你想禁但是没有禁掉的地方,例如下面
var $body = $('body');
var timeId;
elems.button.on('tap',function() {
    clearTimeout(timeId);
    $body.css({
        '-webkit-user-select': 'none',
        '-moz-user-select': 'none',
        '-ms-user-select': 'none',
        'user-select': 'none',
        '-webkit-touch-callout': 'none'
    });
    //  一些业务代码
    // ....
    timeId = setTimeout(function() {
        $body.css({
            '-webkit-user-select': 'text',
            '-moz-user-select': 'text',
            '-ms-user-select': 'text',
            'user-select': 'text',
            '-webkit-touch-callout': 'default'
        })
    }, 300);
});


下面说一下改造过程

对于普通浏览器

对于IOS端,Safari、Chrome经测试加入以下代码即可禁止双击和长按选中

-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;

-webkit-touch-callout 链接 非标准属性
-webkit-touch-callout: none;禁用了默认的标注显示( callout shown ), 标注是指当触摸并按住一个元素的时候出现的提示。当在iOS上一直按住一个目标元素时,Safari会展示一个关于这个链接的callout信息。webkit-touch-callout
属性允许禁用掉这一行为。

user-select 链接 实验中的属性
控制着实际的选区(Selection)操作。This doesn't have any effect on content loaded as chrome, except in textboxes.


对于UIWebView

上面这些在浏览器里面没啥毛病。

但是放在IOS APP的webview里面(UIWebView),如果长按选中过其他未被禁止的元素,再长按或者双击禁止的元素时,会默认的去选中距离最近的未被禁止的元素....这是一个很奇特的问题.....
(不知道是不是我们的客户端做了别的什么配置导致,我猜测应该不是吧。反正如果你的UIWebView加上以上代码就完全好了,那就不用往下看了)
从代码来看,HTML解构如下:

<style>
  ul li {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
  }
</style>

<p>我是可以选中的节点</p>
<ul>
  <li>
      <div>我是被禁掉选中态的div1</div>
      <p>我是被禁掉选中态的p1</p>
      ...
  </li>
  <li>
      <div>我是被禁掉选中态的div2</div>
      <p>我是被禁掉选中态的p2</p>
      ...
  </li>
  ...
</ul>

一进页面,啥也不选,直接长按或者双击li,很好,什么也选不中;
但是,在已选中过顶部的P节点的情况下,双击或长按li,会自动的选中到顶部P里面的内容..........

原因... 应该是浏览器内核的原因,在不设置任何属性的情况下,点击段落空白处,会去选中举例最近的文字。

那这个问题咋解决呢?....

(1) 对于长按乱选中问题

li的外面套一层a,像下面这样

<style>
  ul li {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
  }

a {
    text-decoration: none;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    outline: none;
}

</style>

<p>我是可以选中的节点</p>
<ul>
  <li>
      <a href="javascript:;">
        <div>我是被禁掉选中态的div1</div>
        <p>我是被禁掉选中态的p1</p>
        ...
      </a>
  </li>
  <li>
      <a href="javascript:;">
        <div>我是被禁掉选中态的div2</div>
        <p>我是被禁掉选中态的p2</p>
        ...
      </a>
  </li>
  ...
</ul>

可以看到
对a标签,加上href="javascript:;",长按的时候乱选中的问题就神奇的解决了。

(2) 对于双击乱选中问题

但是对于双击事件,UIWebView中总是会去找离点击位置最近的可选中的节点。
查看stackoverflow 上的回答,所做的都是我做过的。
事已至此,不得不使用js来帮助了。
去除选中态有两种方法:

  • window.getSelection().removeAllRanges();
  • document.execCommand('Unselect');

在PC端和移动端Safari Chrome都运行良好,但是在UIWebView中直接无效!
是的!!没错!!!虽然这个方法理论上来说会先出选中,然后再禁掉,会造成不好的视觉效果,我已经做好了心理准备接受这个瑕疵,可是他还是,无效。
这样的话就不得不启用终极方案了:点击的时候禁掉页面所有元素的选中态。

var $body = $('body');
var timeId;
elems.button.on('tap',function() {
    clearTimeout(timeId);
    $body.css({
        '-webkit-user-select': 'none',
        '-moz-user-select': 'none',
        '-ms-user-select': 'none',
        'user-select': 'none',
        '-webkit-touch-callout': 'none'
    });
    //  一些业务代码
    // ....
    timeId = setTimeout(function() {
        $body.css({
            '-webkit-user-select': 'text',
            '-moz-user-select': 'text',
            '-ms-user-select': 'text',
            'user-select': 'text',
            '-webkit-touch-callout': 'default'
        })
    }, 300);
});

代码运行稳定,Over!

如果有更好的解决方案,欢迎指出~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容