在contentEditable div中显示上下文菜单

时间:2010-10-30 20:09:12

标签: javascript jquery asp.net-mvc asp.net-mvc-2 contenteditable

我有一个contentEditable div,其中包含以下文字:

<div contentEditable='true'> This document is classified</div>

现在例如,如果用户点击word文档中的“m”,我想显示包含少量文本选项的上下文菜单。该上下文菜单将包含在div元素中。我想用用户从上下文菜单中选择的选项(文本)替换单词“document”。在我看来,我必须找到单击的绝对位置以显示上下文菜单,然后我必须在插入符号位置之前和之后找到空格元素,然后用从上下文菜单中选择的选项替换选择。知道如何使用JavaScript和jQuery做到这一点? 修改 我的问题的一部分是关于上下文菜单,而另一方面,更重要的是我如何检测用户在contentEditable div或文本区域中单击的单词。我的目标如下图所示 alt text 实际上我想制作一个类似的音译应用程序。从罗马到乌尔都语的脚本转换过程已经完成,但是我在Web上的用户界面开发中面临很多问题。谷歌音译应用程序可以找到here。我希望有人可以帮助我在用户的鼠标下获取文字,并显示一个包含很少选择的上下文菜单。

2 个答案:

答案 0 :(得分:6)

您可能想要查看一些现有的上下文菜单插件

  1. http://www.trendskitchens.co.nz/jquery/contextmenu/
  2. http://labs.abeautifulsite.net/projects/js/jquery/contextMenu/demo/
  3. http://plugins.jquery.com/plugin-tags/context-menu
  4. 要获取文本区域中当前选定的单词,请查看fieldSelection插件。

    所以使用第二个插件和fieldSelection(免责声明:我认为有关字符串替换的索引略有偏离 - 尚未完全测试)

    <强>的Javascript

     $(document).ready(function () {
        //replace
        $("#tx").contextMenu({
           menu: 'replace'
        }, function (action, el, pos) {
            update(action, el)
        });
    
        function update(action, el) {
            var range = $("#tx").getSelection();
            var textLength = $("#tx").val().length;
    
            var firstPart = $("#tx").val().substring(0, range.start);
            var secondPart = $("#tx").val().substring(range.start, textLength);
    
            var lastIndexofSpaceInfirstPart = firstPart.lastIndexOf(" ");
            var firstIndexofSpaceInSecondPart = secondPart.indexOf(" ");
    
            var startOfWord = 0
            var endOfWord = 0
    
    
            if (lastIndexofSpaceInfirstPart < 0) {
                // start of string
                startOfWord = 0;
            } else {
                startOfWord = lastIndexofSpaceInfirstPart;
            }
    
            if (firstIndexofSpaceInSecondPart < 0) {
                // end of textArea
                endOfWord = textLength
            } else {
                endOfWord = firstIndexofSpaceInSecondPart + range.start;
            }
    
            var word = $.trim($("#tx").val().substring(startOfWord, endOfWord));
    
            var replaceMent = $("#tx").val().substr(0, startOfWord)
                                + action.toString()
                                + $("#tx").val().substr(endOfWord, textLength);
    
                    alert(
                          "rangeStart: " + range.start +
                          "\n\nrangeEnd: " + range.end +
                          "\n\nrangeLength: " + range.length +
                        +"\n\nfirstPart: " + firstPart
                        + "\n\n secondPart: " + secondPart
                        + "\n\n lastIndexofSpaceInfirstPart: " + lastIndexofSpaceInfirstPart
                        + "\n\n firstIndexofSpaceInSecondPart:" + firstIndexofSpaceInSecondPart
                         + "\n\nWordStart: " + startOfWord
                         + "\n\nEndofWord: " + endOfWord
                         + "\n\nWord: '" + word + "'"
                         + "\n\nNew Text: '" + replaceMent + "'"
                        );
                }
            });
    

    <强> HTML

    <textarea id="tx">
        Some text
        </textarea>
    
    
        <ul id="replace" class="contextMenu">
          <li class="edit"><a href="#youwordhere1">youwordhere1</a></li>
          <li class="cut separator"><a href="#youwordhere2">youwordhere2</a></li>
          <li class="copy"><a href="#youwordhere3">youwordhere3</a></li>
          <li class="paste"><a href="#youwordhere4">youwordhere4</a></li>
          <li class="delete"><a href="#youwordhere5">youwordhere5</a></li>
          <li class="quit separator"><a href="#youwordhere6">youwordhere6</a></li>
        </ul>
    

答案 1 :(得分:2)

  1. 要检测鼠标光标下的单词,可靠可靠:只需将要检测的每个单词都包装在一个单独的容器中,例如。使用javascript并不难。只需解析循环中的单词并为每个单词创建span元素,然后设置其innerHTML =单词。然后,您可以阅读点击事件目标,它将为您提供带有单词的范围。

  2. 在现场显示上下文菜单是一项简单的任务: 使用内容菜单创建一个div并将其设置为positiion:absolute和display:none。如果要显示它,请将其顶部和左侧样式(例如)设置为等于父容器的目标span元素偏移量,并使其样式为display =“box”。你们都准备好了;)