详解移动端html5页面长按实现高亮全选文本内容的兼容解决方案


Posted in HTML / CSS onDecember 03, 2016

最近需要给HTML5的WebAPP在页面上实现一个复制功能:用户点击长按文本会全选文字并弹出系统“复制”菜单,用户可以点击“复制”进行复制操作,然后粘贴到AppStore搜索对应的应用。之所以不是采用链接形式直接跳转到AppStore对应应用是为了通过用户的主动输入关键词搜索给推广的企业App增加权重。所以这一个“复制”功能对用户的体验至关重要。

尝试了一些做法,在安卓/iOS平台上的兼容性都不是很好。在微信浏览器内是很容易实现长按文本激发系统菜单,高亮全选文本内容的。但是在其他浏览器的表现就不是很一致了。包括模拟focus input,JavaScript Selection, 使用a标签尝试激活系统菜单。这些方法都存在兼容的缺陷。

1)虽然使用带有href属性的a标签在uc浏览器和百度浏览器上长按文本会出现“自由复制”/“选择文本”菜单,选择该菜单后会出现“全选/复制”的菜单,但是在一些安卓手机的系统浏览器和iPhone中却被视为纯链接,只弹出“复制链接”,没有“复制文本”菜单。况且即使只考虑少部分浏览器可行,这样也给用户操作多了一步,增加了复杂度。所以该方案不可取。

2)借助selection和range的方法需要考虑到不同浏览器的兼容性,代码如下:

function selectText(element) {  
  var doc = document,  
      text = docgetElementById(element),  
      range,  
      selection;  
  
  if (docbodycreateTextRange) {  
      range = documentbodycreateTextRange();  
      rangemoveToElementText(text);  
      rangeselect();  
  } else if (windowgetSelection) {  
      selection = windowgetSelection();          
      range = documentcreateRange();  
      rangeselectNodeContents(text);  
      selectionremoveAllRanges();  
      selectionaddRange(range);  
      /*if(selectionsetBaseAndExtent){ 
          selectionsetBaseAndExtent(text, 0, text, 1); 
      }*/  
  }else{  
      alert("none");  
  }  
}

遗憾的是在iphone Safari上依然无法通过点击或长按高亮选中所有文本(既然也支持window.getSelection,为何在Safari浏览器addRange操作后文本不能默认选中,知道原因的请留言指教)。因此,该方式存在缺陷。主动选中文本区域的方法后面后附上。

3)iPhone用户可能知道,长按某一文本选区内文字周围的空白区域,Safari会自动将该选区内的文本高亮全选(目标文本需要放在独立的div块级容器内)。根据这一特性,用CSS margin修饰一下,利用这个特点,正好可以解决上述第二种方法在ios设备的不兼容。经过测试,无论安卓和ios平台,一般手机自带的系统浏览器都是可以兼容的。至于uc浏览器、百度浏览器等其他厂家的移动端产品,由于有不同的机制,只能使用这些浏览器菜单提供的“自由复制”功能。

所以,我综合了第二种和第三种方式,使用jQuery mobile中的taphold事件来模拟longtap操作激发手机系统的复制菜单,这样基本上可以做到在所有移动设备浏览器上都能实现长按文本区域来高亮选中所有文本内容。再提一句,taphold的兼容bug这里就不详细附解决方法了,如果你的项目要求精益求精,你可以自行搜索解决方案。

下面列出我的解决方案。具体代码如下:

HTML代码:

<div class=" para requirement">  
    <div class="tips tips-t">  
        1、必须首次下载才生效<br/>  
        2、不能从排行榜下载哦  
    </div>  
    <div class="cparea">  
        <div class="kwd" id="kwd"><span>三国艳义手机优化大师</span></div>                   
    </div>  
    <div class="cparea">  
        <span class="kdes"><b>★</b>长按虚线框,拷贝关键词</span>  
    </div>  
    <a href="https://itunesapplecom/cn/" data-role="button" class="downlink">去AppStore搜索下载</a>  
</div>

JavaScript代码:

<script type="text/javascript">  
  
$("#kwd")bind("taphold", function(){ //不支持iPhone/iTouch/iPad Safari  
    var doc = document,   
        text = docgetElementById("kwd"),  
        range,   
        selection;  
    if (docbodycreateTextRange) {  
        range = documentbodycreateTextRange();  
        rangemoveToElementText(text);  
        rangeselect();  
    } else if (windowgetSelection) {  
        selection = windowgetSelection();          
        range = documentcreateRange();  
        rangeselectNodeContents(text);  
        selectionremoveAllRanges();  
        selectionaddRange(range);   
    }else{  
        alert("浏览器不支持长按复制功能");  
    }         
});  
  
</script>

关键的CSS代码:

cparea{  
    text-align: center;  
    font-family: Microsoft Yahei;  
    margin: -2em 0 0;  
}  
kwd{  
    display: inline-block;  
    color: #272727;  
    background-color: #fff;  
    font-size: 1875em;  
    font-size: 1875em;  
    padding: 75em 1em;  
    border: 1px dashed #e60012;  
    -webkit-user-select:element;   
    margin: 2em;  
}  
kwd span{  
    display: block;   
    border: 1px solid #fff;  
}  
kdes{  
    display: inline-block;  
    color: #212121;  
    font-size: 875em;  
    padding-top: 0;  
}  
kdes b{  
    color: #ed5353;  
    font-size: 25em;  
    padding-right: 1em;  
}

说明:这里的margin:2em正是为了实现Safari浏览器上的长按全选功能,为了尊重还原设计稿效果,父容器.cparea又使用了负边距来抵消这个2em的外边距。最终,不仅视觉上和设计图保持了一致,也实现了长按全选激发系统菜单。

最后再补充一下支持Safari下的完整方法:

$("#kwd").bind("taphold", function(){  
    var doc = document,   
        text = docgetElementById("kwd"),  
        range,   
        selection;  
    if (docbodycreateTextRange) { //IE  
        range = documentbodycreateTextRange();  
        rangemoveToElementText(text);  
        rangeselect();  
  
    } else if (windowgetSelection) {   //FF CH SF  
        selection = windowgetSelection();          
        range = documentcreateRange();  
        rangeselectNodeContents(text);  
        selectionremoveAllRanges();  
        selectionaddRange(range);  
  
        //测试  
        consolelog(texttextContent);  
        textinnerText && consolelog(textinnerText);  //FireFox不支持innerText  
        consolelog(texttextContentlength);  
        textinnerText && consolelog(textinnerTextlength);   //在Chrome下长度比IE/FF下多1  
        consolelog(textfirstChildtextContentlength);  
        textinnerText && consolelog(textfirstChildinnerTextlength);  
        consolelog(textfirstChildinnerHTMLlength);  
  
        //注意IE9-不支持textContent  
        makeSelection(0, textfirstChildtextContentlength, 0, textfirstChild);  
        /* 
        if(selectionsetBaseAndExtent){ 
            selectionselectAllChildren(text); 
            selectionsetBaseAndExtent(text, 0, text, 4); 
        } 
        */  
    }else{  
        alert("浏览器不支持长按复制功能");  
    }  
  
});  
function makeSelection(start, end, child, parent) {  
    var range = documentcreateRange();  
    //consolelog(parentchildNodes[child]);  
    rangesetStart(parentchildNodes[child], start);  
    rangesetEnd(parentchildNodes[child], end);  
  
    var sel = windowgetSelection();  
    selremoveAllRanges();  
    seladdRange(range);   
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
CSS3实战第一波 让我们尽情的圆角吧
Aug 27 HTML / CSS
纯CSS3实现带动画效果导航菜单无需js
Sep 27 HTML / CSS
利用CSS3实现开门效果实例源码
Aug 22 HTML / CSS
html5 浏览器支持 如何让所有的浏览器都支持HTML5标签样式
Dec 07 HTML / CSS
HTML5自定义data-* data(obj)属性和jquery的data()方法的使用
Dec 13 HTML / CSS
html5 viewport使用方法示例详解
Dec 02 HTML / CSS
HTML5 visibilityState属性详细介绍和使用实例
May 03 HTML / CSS
html5 css3实例教程 一款html5和css3实现的小机器人走路动画
Oct 20 HTML / CSS
HTML5页面无缝闪开的问题及解决方案
Jun 11 HTML / CSS
CSS3 天气图标动画效果
Apr 06 HTML / CSS
浅谈CSS不规则边框的生成方案
May 25 HTML / CSS
CSS布局之浮动(float)和定位(position)属性的区别
Sep 25 HTML / CSS
HTML5标签大全
Nov 23 #HTML / CSS
HTML5拖放效果的实现代码
Nov 17 #HTML / CSS
html5 div布局与table布局详解
Nov 16 #HTML / CSS
纯HTML5+CSS3制作生日蛋糕(代码易懂)
Nov 16 #HTML / CSS
HTML5制作表格样式
Nov 15 #HTML / CSS
详解HTML5中的拖放事件(Drag 和 drop)
Nov 14 #HTML / CSS
HTML5不支持frameset的两种解决方法
Nov 14 #HTML / CSS
You might like
php中的ini配置原理详解
2014/10/14 PHP
php实现字符串首字母转换成大写的方法
2015/03/17 PHP
PHP里的单例类写法实例
2015/06/25 PHP
Laravel中使用FormRequest进行表单验证方法及问题汇总
2016/06/19 PHP
基于Laravel5.4实现多字段登录功能方法示例
2017/08/11 PHP
ajax+php实现无刷新验证手机号的实例
2017/12/22 PHP
laravel获取不到session的三种解决办法【推荐】
2018/09/16 PHP
Javascript的一种模块模式
2010/09/08 Javascript
通过Jscript中@cc_on 语句识别IE浏览器及版本的代码
2011/05/07 Javascript
javaScript 利用闭包模拟对象的私有属性
2011/12/29 Javascript
JavaScript中的匀速运动和变速(缓冲)运动详细介绍
2012/11/11 Javascript
JavaScript操作XML/HTML比较常用的对象属性集锦
2015/10/30 Javascript
javascript弹出窗口中增加确定取消按钮
2016/06/24 Javascript
vue2笔记 — vue-router路由懒加载的实现
2017/03/03 Javascript
JavaScript实现封闭区域布尔运算的示例代码
2018/06/25 Javascript
JavaScript中交换值的10种方法总结
2020/08/18 Javascript
Python使用sorted排序的方法小结
2017/07/28 Python
python生成不重复随机数和对list乱序的解决方法
2018/04/09 Python
Python实现模拟浏览器请求及会话保持操作示例
2018/07/30 Python
Python 排序最长英文单词链(列表中前一个单词末字母是下一个单词的首字母)
2020/12/14 Python
利用纯CSS3实现文字向右循环闪过效果实例(可用于移动端)
2017/06/15 HTML / CSS
Derek Rose官网:英国高档睡衣、家居服和内衣品牌
2020/01/18 全球购物
数据库方面面试题
2012/04/22 面试题
动态密码技术
2012/10/18 面试题
法律专业应届本科毕业生求职信
2013/10/25 职场文书
门诊挂号室室长岗位职责
2013/11/27 职场文书
销售人员自我评价
2014/02/01 职场文书
八一慰问活动方案
2014/02/07 职场文书
家长会演讲稿
2014/04/26 职场文书
承诺书格式
2014/06/03 职场文书
小学庆六一活动总结
2014/08/28 职场文书
工作收入证明模板
2014/10/10 职场文书
个人作风纪律整顿整改措施
2014/10/25 职场文书
见习期个人总结
2015/03/05 职场文书
大学迎新生欢迎词
2015/09/29 职场文书
「魔导具师妲莉亚永不妥协~从今天开始的自由职人生活~」1、2卷发售宣传CM公开
2022/03/21 日漫