jjzjj

javascript - 需要将光标位置设置到 contentEditable div 的末尾,选择和范围对象问题

coder 2025-02-02 原文

我暂时忘记了跨浏览器兼容性,我只是希望它能工作。 我正在做的是尝试修改位于 typegreek.com 的脚本(您可能不需要知道这一点)找到基本脚本here .基本上它的作用是当您输入字符时,它将您输入的字符转换为希腊字符并将其打印到屏幕上。我想要做的是让它在 contentEditable div 上工作(它只适用于 Textareas)

我的问题是这个函数:用户键入一个键,它被转换为希腊键,然后转到一个函数,它通过一些 if 排序,它最终到达的地方是我可以添加 div 支持的地方.这是我目前所拥有的,

myField 是 div,myValue 是希腊字符。

//Get selection object...
var userSelection
 if (window.getSelection) {userSelection = window.getSelection();}
 else if (document.selection) {userSelection = document.selection.createRange();}

//Now get the cursor position information...
var startPos = userSelection.anchorOffset;
var endPos = userSelection.focusOffset;
var cursorPos = endPos;

//Needed later when reinserting the cursor...
var rangeObj = userSelection.getRangeAt(0) 
var container = rangeObj.startContainer

//Now take the content from pos 0 -> cursor, add in myValue, then insert everything after myValue to the end of the line.
myField.textContent = myField.textContent.substring(0, startPos) + myValue + myField.textContent.substring(endPos, myField.textContent.length);

//Now the issue is, this updates the string, and returns the cursor to the beginning of the div. 
//so that at the next keypress, the character is inserted into the beginning of the div.
//So we need to reinsert the cursor where it was.

//Re-evaluate the cursor position, taking into account the added character.
  var cursorPos = endPos + myValue.length;

  //Set the caracter position.
  rangeObj.setStart(container,cursorPos) 

现在,只要我输入的内容不超过原始文本的大小,它就可以正常工作。假设我之前在 div 中有 30 个字符。如果我键入的字符多于 30,它会添加字符 31,但会将光标放回 30。我可以在 pos.31 键入字符 32,然后在 pos.32 键入字符 33,但是如果我尝试将字符 34 放入,它添加字符,并将光标设置回 32。问题是,如果 cursorPos 大于范围中定义的值,则添加新字符的函数会出错。有什么想法吗?

最佳答案

在内容可编辑的 div 中比文本区域更容易跨浏览器执行此操作。以下假设您的 contenteditable div 的 id 为“greek”。

var greekChars = {
    "a": "\u03b1"
    // Add character mappings here
};

function convertCharToGreek(charStr) {
    return greekChars[charStr] || "[Greek]";
}

function insertTextAtCursor(text) {
    var sel, range, textNode;
    if (window.getSelection) {
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();
            textNode = document.createTextNode(text);
            range.insertNode(textNode);

            // Move caret to the end of the newly inserted text node
            range.setStart(textNode, textNode.length);
            range.setEnd(textNode, textNode.length);
            sel.removeAllRanges();
            sel.addRange(range);
        }
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        range.pasteHTML(text);
    }
}

var div = document.getElementById("greek");

div.onkeypress = function(evt) {
    evt = evt || window.event;
    var charCode = (typeof evt.which == "undefined") ? evt.keyCode : evt.which;
    if (charCode) {
        var charStr = String.fromCharCode(charCode);
        var greek = convertCharToGreek(charStr);
        insertTextAtCursor(greek);
        return false;
    }
}

关于javascript - 需要将光标位置设置到 contentEditable div 的末尾,选择和范围对象问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2940882/

有关javascript - 需要将光标位置设置到 contentEditable div 的末尾,选择和范围对象问题的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  4. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  5. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  8. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  9. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  10. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

随机推荐