用一个div模拟textarea的实现

转自:http://www.zhangxinxu.com/wordpress/2016/01/contenteditable-plaintext-only/   by zhangxinxu


1.contenteditable 属性介绍

contenteditable 属性规定是否可编辑元素的内容。

contenteditable 属性是 HTML5 中的新属性。

2.传统过滤HTML的方法

之前的文章提到过过滤HTML的方法,保证内容都是纯文本。然而,这种方法的问题在于:

  1. 粘贴完毕到过滤结束有时间差,用户很看到内容一闪而过的糟糕体验;
  2. 光标的位置会发生变化,不是之前focus的位置了;

当年的我图样图森破,所以,只有上面这种程度。实际上,控制contenteditable元素只能输入纯文本是有体验比较好的方法的。

3.元素只可编辑只输入纯文本的方法一:与contenteditable属性无关的CSS控制法

(部分属性只有webkit内核浏览器才支持

一个div元素,要让其可编辑,也就是可读写,contenteditable属性是最常用方法,做前端的基本上都知道。但是,知道CSS中有属性可以让普通元素可读写的的同学怕是就少多了。

主角亮相:user-modify.

支持属性值如下:

user-modify: read-only;
user-modify: read-write;
user-modify: write-only;
user-modify: read-write-plaintext-only;

其中,write-only不用在意,当下这个年代,基本上没有浏览器支持,以后估计也不会有。

read-only表示只读,就是普通元素的默认状态啦。

然后,read-writeread-write-plaintext-only会让元素表现得像个文本域一样,可以focus以及输入内容。这两者的区别就在于,一个可以输入富文本,而下面一个只能输入纯文本

至此,本文标题的答案实际上就已经有了。也就是给元素设置:

user-modify: read-write-plaintext-only

就可以让元素既可以编辑,也只能输入纯文本,表现得就跟textarea文本域一样。

是不是很酷啊!然而,抱歉地跟大家讲下,目前只有webkit内核浏览器才支持read-write-plaintext-only这个值,因此,我们的使用其实是:

-webkit-user-modify: read-write-plaintext-only

注意:我们可以在移动端使用,以及,只需要兼顾webkit内容的桌面网页项目。

5.在HTML中,contenteditable支持的属性值是?

垂直展示下就是(不包括默认的inherit继承):

contenteditable=""
contenteditable="events"
contenteditable="caret"
contenteditable="plaintext-only"
contenteditable="true"
contenteditable="false"
别问我,我也不知道 "events" "caret" 是干什么用的,嘿,但是 "plaintext-only" 我是知道的,可以让编辑区域只能键入纯文本。这里就不需要demo了,直接下面的框框,大家可以试试,看看能不能搞富文本。

如果您发现,居然出乎意料,可以弄进去富文本,那说明你使用的是非Chrome之流的浏览器。

换句话说,contenteditable="plaintext-only"和CSS只的-webkit-user-modify: read-write-plaintext-only一样,目前仅仅是Chrome浏览器支持比较好的。

所以,您的项目如果还有很多IE8浏览器的用户,我只能替你惋惜,美妙的东西无法立即用上,不得已,寻求下面的方法。

6. 控制粘贴paste事件的JS控制法(增强兼容性)

如果我们单纯地敲击键盘,输入的内容实际上都是纯文本。除了一些特殊情况,例如IE浏览器下的编辑框会自动把合乎条件的url地址自动加上链接。富文本污染的情况主要出现在复制粘贴的时候,于是,如果我们能在粘贴的时候,对剪切板中的内容进行HTML过滤,再手动插入内容,岂不就可以完美解决无法输入富文本的问题了吗!?

$('[contenteditable]').each(function () {
// 干掉IE http之类地址自动加链接
    try {
      document.execCommand("AutoUrlDetect", false, false);
    } catch (e) {
    }

    $(this).on('paste', function (e) {
      e.preventDefault();
      var text = null;

      if (window.clipboardData && clipboardData.setData) {
      // IE
        text = window.clipboardData.getData('text');
      } else {
        text = (e.originalEvent || e).clipboardData.getData('text/plain') || prompt('在这里输入文本');
      }
      if (document.body.createTextRange) {
        if (document.selection) {
          textRange = document.selection.createRange();
        } else if (window.getSelection) {
          sel = window.getSelection();
          var range = sel.getRangeAt(0);

// 创建临时元素,使得TextRange可以移动到正确的位置
          var tempEl = document.createElement("span");
          tempEl.innerHTML = "&#FEFF;";
          range.deleteContents();
          range.insertNode(tempEl);
          textRange = document.body.createTextRange();
          textRange.moveToElementText(tempEl);
          tempEl.parentNode.removeChild(tempEl);
        }
        textRange.text = text;
        textRange.collapse(false);
        textRange.select();
      } else {
// Chrome之类浏览器
        document.execCommand("insertText", false, text);
      }
    });
// 去除Crtl+b/Ctrl+i/Ctrl+u等快捷键
    $(this).on('keydown', function (e) {
// e.metaKey for mac
      if (e.ctrlKey || e.metaKey) {
        switch (e.keyCode) {
          case 66: //ctrl+B or ctrl+b
          case 98:
          case 73: //ctrl+I or ctrl+i
          case 105:
          case 85: //ctrl+U or ctrl+u
          case 117:
          {
            e.preventDefault();
            break;
          }
        }
      }
    });
  });



  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值