zoukankan      html  css  js  c++  java
  • 怎么控制contenteditable的输入

    contenteditable是所有流浪器都支持的属性, 可以利用标签模拟文本域, 实现体验相当不错的内容跟着高度自动增高的体验, 但是也带来一些问题, 就是可以直接复制带有style样式的标签进去

    之前有看到过文章过滤HTML的方法, 就是在复制进去后将HTML过滤掉, 这样做的问题是过滤的标签多了之后,会有很明显的感觉, 还有就是, 当光标的位置发生变化之后, 会导致位置不正确

    控制contenteditable只能输入纯文本才是一种比较好的体验

    一. 用CSS控制

    一个div标签要让其可编辑, 直接添加contenteditable属性就可以, 但是你可能不知道还可以通过css来约束它的输入内容

    user-modify: read-only;
    user-modify: read-write;
    user-modify: write-only; /*几乎没有流浪器支持*/
    user-modify: read-write-plaintext-only;

    read-only表示只读, read-write表示可读写, 和不设置没啥区别, write-only表示只写, 到目前为止几乎没有流浪器支持该属性, 估计以后也不会有, read-write-plaintext-only表示可读可写,但是只能写入纯文本

    不用说, 这些标签都是要加私有前缀的

    使用user-modify: read-write-plaintext-only; 就可以完美解决只输入文本的需求

    二. 使用contenteditable的其他属性值来控制

    what??? contanteditable除了true和false还有别的值吗, 答案是当然有的, 新的草案已经明确提出了还有多个其他属性值, 其中有这么一段话

    展开之后就是

    contenteditable=""
    contenteditable
    ="events" contenteditable="caret"
    contenteditable="typing"
    contenteditable="plaintext-only" contenteditable="true" contenteditable="false"

    其中不包括inherit, events, caret, typing, 可能是流浪器还没有支持, 毕竟现在只是草案, 至于能干什么我也不知道, 但是 plaintext-only 这个属性是 Chrome已经支持了的, 就死控制只能输入纯文本, 如果你发现居然可以复制进去富文本, 那么你一定用的不是Chrome流浪器

    三. 控制粘贴 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;
                    }
                }
            }    
        });
    });

    目前经过测试, 在IE9, Chrome, 火狐, 安卓, IOS上,均没有发现问题

    jQuery只是为了便于书写, 核心代码与jQuery无关

    document.execCommand("AutoUrlDetect", false, false); 是为了处理IE浏览器自动添加链接

  • 相关阅读:
    动态横向(水平)合并Repeater数据行DataItem的列
    动态绑数据(Repeater控件HeaderTemplate和ItemTemplate)
    动态横向(水平)合并GridView数据行DataRow的列
    动态绑数据(GridView控件Header和ItemTemplate)
    用具体列名替代星号
    如何实现数据行转换列显示
    用LINQ获取XML节点数据
    从字符串中获取XML节点数据
    字符串创建XML文档
    根据Attribute值条件对XML文档进行修改
  • 原文地址:https://www.cnblogs.com/shenjp/p/8621620.html
Copyright © 2011-2022 走看看