本帖最后由 mingfish2 于 2010-08-14 16:51:23 编辑

解决方案 »

  1.   

    这个比较复杂,如果改变比较简单,如果获取光标位置的字符串就比较复杂,先标记一下。
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script type="text/javascript">
        function fill_val(){
            $("#code").val($(".box").html());
        } 
        function select_area(){
            //将光标置于textarea中的成对符号("xxx",[xxx],>xxx<)之间,
            //按就近原则选,如先>[栏(光标在这里)目]<,则选中“栏目”
            //点击按钮实现高亮选中成对符号之间的文本。
        } 
        function alter_selected(){
            //之前的高亮选中文本后,再进行替换,如将高亮选中部分变成"hello"
    $("#code").each(function() {
    var range;
    if (document.selection) {
    range = document.selection.createRange();
    }
    setSelectText(this, "hello", range);
    })
        }  function setSelectText(editor, value, range) {
    if (!editor || !value) return;
    editor.focus();
    if (range && range.parentElement() == editor) {
    range.text = value;
    range.select();
    range = null;
    } else if (document.selection) {
    document.selection.createRange().text = value;
    } else if (typeof editor.selectionStart != "undefined") { // firefox
    var str = editor.value;
    var start = editor.selectionStart;
    var scroll = editor.scrollTop;
    editor.value = str.substr(0, start) + value +
    str.substring(editor.selectionEnd, str.length);
    editor.selectionStart = start + value.length;
    editor.selectionEnd = start + value.length;
    editor.scrollTop = scroll;
    }
    }
    </script>
    <div class="box">
        <ul>
            <li>
                <a href="http://baidu.com">[栏目]</a>
                <a href="http://google.com">hello world</a>
            </li>
            <li>
                <a href="http://baidu.com">[栏目]</a>
                <a href="http://google.com">hello world</a>
            </li>
        </ul>
    </div>
    <textarea cols="80" rows="10" id="code"></textarea>
    <div>
        <button onclick="fill_val()">fill val</button>
        <button onclick="select_area()">select area</button>
        <button onclick="alter_selected()">alter selected</button>
    </div>
      

  2.   

    这个问题研究了一天
    IE里处理这类问题真够变态的
    换行在字符串里是两字符,而编辑器里只记一个字符,搜了N多资料和代码。
    调试了很多次,才做出下面的Demo。
    IE6\7\8测试通过<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script type="text/javascript">
    var Editor = {
    __calcBook: function(book) {
    return (book.charCodeAt(0) - 1) + (book.charCodeAt(3) - 1) * 65536 + (book.charCodeAt(2) - 1);
    },
    __getSelectPos: function(editor, end) {
    if (!editor) return;
    if (typeof editor.selectionStart != "undefined")
    return end ? editor.selectionEnd : editor.selectionStart;
    if (!editor.createTextRange) return;
    editor.focus ();
    var range = document.selection.createRange().duplicate();
    if (!end) range.collapse(true)
    range.setEndPoint("StartToEnd", range);
    var start = document.body.createTextRange();
    start.moveToElementText(editor);
    var start = this.__calcBook(range.getBook()) - this.__calcBook(start.getBook());
    var value = editor.value;
    return start;
    },
    getSelectStart: function(editor) {
    return this.__getSelectPos(editor);
    },
    getSelectEnd: function(editor) {
    return this.__getSelectPos(editor, true);
    },
    getSelectRange: function(editor) {
    return [this.getSelectStart(editor), this.getSelectEnd(editor)];
    },
    setSelectRange: function(editor, range) {
    if (!editor) return;
    if (range[0] > range[1]) return;
    editor.focus();
    if (editor.setSelectionRange) {
    editor.setSelectionRange(range[0], range[1]);
    } else if (editor.createTextRange) {
    var value = editor.value;
    var textRange = editor.createTextRange();
    textRange.collapse(true);
    textRange.moveEnd("character", range[1]);
    textRange.moveStart("character", range[0]);
    textRange.select();
    }
    },
    textPos: function(editor, pos) {
    if (!editor) return;
    if (!editor.createTextRange) return pos;
    var value = editor.value;
    for (var i = 0; i <= pos; i++) if (value.charAt(i) == "\n") pos++;
    return pos;
    },
    cartPos: function(editor, pos) {
    if (!editor) return;
    if (!editor.createTextRange) return pos;
    var value = editor.value;
    var j = 0;
    for (var i = 0; i <= pos; i++) if (value.charAt(i) == "\n") j++;
    return pos - j;
    },
    selectEx: function(editor, startPattern, endPattern, include) {
    if (!editor) return;
    startPattern = "" + startPattern;
    endPattern = "" + endPattern;
    var range = this.getSelectRange(editor);
    var value = editor.value;
    var textRange = [this.textPos(editor, range[0]), this.textPos(editor, range[1])];
    var startStr = value.substr(0, textRange[0]);
    var endStr = value.substring(textRange[1], value.length);
    var i = startStr.lastIndexOf(startPattern);
    if (i < 0) return;
    var j = endStr.indexOf(endPattern);
    if (j < 0) return;
    j += textRange[1];
    if (include)
    j += endPattern.length;
    else i += startPattern.length;
    this.setSelectRange(editor, [this.cartPos(editor, i), this.cartPos(editor, j)]);
    },
    setSelectText: function (editor, value, range) {
    if (!editor) return;
    editor.focus();
    if (range && range.parentElement() == editor) {
    range.text = value;
    range.select();
    range = null;
    } else if (document.selection) {
    document.selection.createRange().text = value;
    } else if (typeof editor.selectionStart != "undefined") { // firefox
    var str = editor.value;
    var start = editor.selectionStart;
    var scroll = editor.scrollTop;
    editor.value = str.substr(0, start) + value +
    str.substring(editor.selectionEnd, str.length);
    editor.selectionStart = start + value.length;
    editor.selectionEnd = start + value.length;
    editor.scrollTop = scroll;
    }
    }
    };
    </script>
    <script type="text/javascript">
        function fill_val(){
            $("#code").val($(".box").html());
        } 
        function select_area(){
            //将光标置于textarea中的成对符号("xxx",[xxx],>xxx<)之间,
            //按就近原则选,如先>[栏(光标在这里)目]<,则选中“栏目”
            //点击按钮实现高亮选中成对符号之间的文本。
    $("#code").each(function() {
    Editor.selectEx(this, ">", "<");
    })
        } 
        function alter_selected(){
            //之前的高亮选中文本后,再进行替换,如将高亮选中部分变成"hello"
    $("#code").each(function() {
    Editor.setSelectText(this, "hello");
    })
        }  function setSelectText(editor, value, range) {
    if (!editor || !value) return;
    editor.focus();
    if (range && range.parentElement() == editor) {
    range.text = value;
    range.select();
    range = null;
    } else if (document.selection) {
    document.selection.createRange().text = value;
    } else if (typeof editor.selectionStart != "undefined") { // firefox
    var str = editor.value;
    var start = editor.selectionStart;
    var scroll = editor.scrollTop;
    editor.value = str.substr(0, start) + value +
    str.substring(editor.selectionEnd, str.length);
    editor.selectionStart = start + value.length;
    editor.selectionEnd = start + value.length;
    editor.scrollTop = scroll;
    }
    }
    </script>
    <div class="box">
        <ul>
            <li>
                <a href="http://baidu.com">[栏目]</a>
                <a href="http://google.com">hello world</a>
            </li>
            <li>
                <a href="http://baidu.com">[栏目]</a>
                <a href="http://google.com">hello world</a>
            </li>
        </ul>
    </div>
    <textarea cols="80" rows="10" id="code"></textarea>
    <div>
        <button onclick="fill_val()">fill val</button>
        <button onclick="select_area()">select area</button>
        <button onclick="alter_selected()">alter selected</button>
    </div>
      

  3.   

    更复杂的选择规则请参考这段。
    selectEx: function(editor, startPattern, endPattern, include) {
            if (!editor) return;
            startPattern = "" + startPattern;
            endPattern = "" + endPattern;
            var range = this.getSelectRange(editor);
            var value = editor.value;
            var textRange = [this.textPos(editor, range[0]), this.textPos(editor, range[1])];
            var startStr = value.substr(0, textRange[0]);
            var endStr = value.substring(textRange[1], value.length);
            var i = startStr.lastIndexOf(startPattern);
            if (i < 0) return;
            var j = endStr.indexOf(endPattern);
            if (j < 0) return;
            j += textRange[1];
            if (include)
                j += endPattern.length;
            else i += startPattern.length;
            this.setSelectRange(editor, [this.cartPos(editor, i), this.cartPos(editor, j)]);
        }
      

  4.   

    一瓢眼泪!!王哥别太较真了,这忙帮得让我都觉得汗颜!
    王哥你的代码虽然我本地测试还不完美,也请不要再深究下去啦,浪费大哥你时间我等菜鸟实在无颜再问问题。
    其实我也有替代方案了,直接用在fill_val()函数前用js对innerHTML,href等等属性进行替换,或fill_val以后直接正则替换成对符号中的值,也很方便。
    我提的那个获取光标位置再成对高亮抓取,这种要求太过变态,涉及到js的原生代码太多。你给我的代码我会好好研究的,对于先学jquery再学js的菜鸟实在有点头痛,好生呀!
      

  5.   

    本帖最后由 zswang 于 2010-08-15 19:39:12 编辑