使用jquery </span>用<span>包装某个单词

时间:2012-11-06 21:40:32

标签: javascript jquery

我有以下div

<div id="query" style="width:500px; height:200px;border:1px solid black"
 spellcheck="false" contenteditable="true"></div>​

客户端可以编写SQL个查询。我试图做的是在用span点击 Space 之后立即包装客户输入的单词,并根据输入的单词给这个跨度指定class

例如

如果客户端类型select我需要在div中包含这样的选择单词:

<span class='select'> SELECT </span> <span> emp_name </span>

CSS

.select{color:blue ;text-transform:uppercase;}

这与jsFiddle非常相似。我怎样才能做到这一点?

以下是我到目前为止所尝试的内容:jsFiddle

$(function(){
    $('div').focus() ;
    $('div').keyup(function(e){
        //console.log(e.keyCode) ;
        if(e.keyCode == 32){
            var txt = $('div').text() ;
            var x = 'SELECT' ;
            $('div:contains("'+x+'")').wrap("<span style='color:blue ;
      text-transform:uppercase;'>") ;
            if(txt == 'SELECT'){
                console.log('found') ; // why This Doesn't do any thing  ?
            }

        }
    });

});

2 个答案:

答案 0 :(得分:3)

我做了一个概念验证,并对你原来的一些进行了一些修改。见下文,

DEMO: http://jsfiddle.net/cgy69/

$(function() {
    $('div').focus();
    var x = ['SELECT', 'WHERE', 'FROM'];
    $('div').keyup(function(e) {
        //console.log(e.keyCode) ;
        if (e.keyCode == 32) {

            //using .text() remove prev span inserts
            var text = $.trim($(this).text()).split(' ');            
            $.each(text, function(i, v) {
                $.each(x, function(j, xv) {
                    if (v.toUpperCase() === xv) {
                        text[i] = '<span style="color: blue; text-transform: uppercase;">' + v + '</span>';    
                    }                                        
                });
            });

            $(this).html(text.join(' ') + '&nbsp;');

            setEndOfContenteditable(this);
        }
    });

    function setEndOfContenteditable(contentEditableElement) {
        var range, selection;
        if (document.createRange) //Firefox, Chrome, Opera, Safari, IE 9+
        {
            range = document.createRange(); //Create a range (a range is a like the selection but invisible)
            range.selectNodeContents(contentEditableElement); //Select the entire contents of the element with the range
            range.collapse(false); //collapse the range to the end point. false means collapse to end rather than the start
            selection = window.getSelection(); //get the selection object (allows you to change selection)
            selection.removeAllRanges(); //remove any selections already made
            selection.addRange(range); //make the range you have just created the visible selection
        }
        else if (document.selection) //IE 8 and lower
        {
            range = document.body.createTextRange(); //Create a range (a range is a like the selection but invisible)
            range.moveToElementText(contentEditableElement); //Select the entire contents of the element with the range
            range.collapse(false); //collapse the range to the end point. false means collapse to end rather than the start
            range.select(); //Select the range (make it the visible selection
        }
    }
});

您将进一步扩展此处理

  1. 退格
  2. 以前插入的HTML内容
  3. 光标位置部分完成,在中间编辑仍然会使插入符号变得混乱。
  4. 以及更多......

答案 1 :(得分:0)

contenteditable元素开始,我们可以直接在其innerHtml上运行来替换标记:

$('#query-container').on('keyup', function(e){
  var $this = $(this);
  //(?!\<\/b\>) negative lookahead is used so that anything already wrapped
  //into a markup tag would not get wrapped again
  $this.html($this.html().replace(/(SELECT|UPDATE|DELETE)(?!\<\/b\>)/gi, '<b>$1</b>'));
  setEndOfContenteditable(this);
});

IMO这是一个更具可读性的选择。添加上一个答案中的rangeselect方法,我们有a working fiddle