JavaScript - 检测textarea中的更改

时间:2009-09-20 00:40:24

标签: javascript event-handling

我希望两个textareas的值始终相等。 听“改变”事件是不够的,因为我希望这些字段即使在有焦点时也是相等的。 听一个按键似乎不起作用,因为在用新字母更新字段的值之前触发了这个事件,所以我不确定是否有一种使用按键处理程序获取字段当前值的好方法为了将其复制到其他字段。 有什么想法吗?

5 个答案:

答案 0 :(得分:4)

keyup事件怎么样?

答案 1 :(得分:2)

我遇到同样的问题......

textarea的价值可以通过很多方式改变......我只会提到我不知道如何检测的那些:

  • 鼠标上下文粘贴
  • 键盘上下文菜单粘贴
  • 拖放其他应用程序,对象等
  • 从同一文本中移动拖放(在其他位置选择内容)
  • 执行Ctrl + Insert - Shift + Insert(复制和粘贴的另一种方式)

我曾经尝试为我知道的每个事件(onkeyup,onkeydown,onmouseup,onmousedown等等)创建一个事件处理程序,但是使用以前的一些粘贴方式,没有人被解雇,所以没办法控制何时发生。

除了放置计时器之外我没有其他解决方案。

啊!内容也可以在没有焦点的情况下改变...... Drag& Drop的情况。

更不用说是否也可以通过JavaScript进行更改,这是一个最重要的事情......没有方法被解雇!!!

我不想放一个计时器(做事非常难看,可能导致错误)。

如果计时器被触发但正在加载另一个页面(用户点击链接)...你必须控制所有对象存在...否则会带来错误信息(某些浏览器会将其显示为模态窗口而其他人会忽略它)...所以用户获得了非常糟糕的内容......在最坏的情况下......对你的事件处理程序的调用可能会失败,因为你的函数在计时器调用之前就被销毁了。

使用计时器,你总是必须把页面卸载,所以当页面被杀死时会被取消激活或销毁,例如当你去另一页时。

这种事情比需要复杂得多,将来更新也很可怕。

为了确保计时器不会失败,我会做第一句话这样丑陋的事情:clearTimeout(MyTimer);

如果我需要计时器每隔X毫秒重复一次...在函数内{i setTimeout(function(){MyFunction();)

通过这种方式,如果事情在不合适的情况下被破坏,则不会因调用计时器处理程序而导致错误。

同样在函数MyFunction中的每个句子都必须是错误控制的......任何被使用的对象都必须确保存在...在每个句子上...这是不可能完成的..所以一个try catch必须是加入。

使用计时器时可以做的另一件事是忽略销毁问题,让用户在卸载页面时得到非常糟糕的印象。

为了确保没有启动定时器......我唯一知道的就是为身体提供服务...但是一些丑陋的浏览器不会解雇它(以避免程序员不让你去另一页)所以我必须做的事情好像onunload不存在...所以当对象被销毁时可以调用计时器...错误总是会发生......

确保在使用计时器时不会出现错误窗口太麻烦了:

var MyTimer;
function MyTimer_Handler(){
 try{
  clearTimeout(TemporizadorCapaLogin);
  try{
   // Do whatever the timer must do
  }Catch(theError){
   // Your own code to control errors, but have in mind that while running the lines you write here can also cause error because while running this the objects get destroyed, so better not to put anything
  }
  MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);
 }Catch(theError){}
}
try{MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);}Catch(theError){}

看看我在说什么......太丑陋的代码......但是所有的小部件都是必需的,否则一些浏览器会显示一条错误消息,说明在发生卸载页面时不存在某些内容。

这也是最糟糕的,真的确保你会尝试这个:

var MyTimer;
function MyTimer_Handler(){
 try{
  clearTimeout(TemporizadorCapaLogin);

  try{
   // Do only one sentence at a time
  }Catch(theError){} // Ther is no way to ensure any line on Catch part can not cause an error because objects can have being destroyed before and while running this part

  try{
   // Do only one sentence at a time
  }Catch(theError){} // Ther is no way to ensure any line on Catch part can not cause an error because objects can have being destroyed before and while running this part

  // Repeat for each sentence

  MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);
 }Catch(theError){}
}
try{MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);}Catch(theError){}

但是Try {} Catch {}的这种安全性与将其全部分组相同......所以没有任何好处......因为你可以看到Timers非常痛苦被使用......只是因为没有办法确保不会发生错误。

原因在于某些浏览器上的事件:

  1. 用户要求提供一个页面
  2. 页面已下载
  3. 页面激活计时器
  4. 用户点击链接或只是关闭标签...这会导致页面卸载
  5. 浏览器按对象
  6. 开始销毁
  7. 在所有人都摧毁计时器之前
  8. 运行定时器代码,但某些对象不存在,已被销毁
  9. 当这样的代码运行时,浏览器继续破坏更多的对象 (同时)
  10. 例如,当在计时器内执行任何代码行时,JavaScript管理器可能在某些浏览器上被破坏,因此它将失败并且浏览器将呈现模态窗口,告诉您的页面编码错误,句子也可以就这么简单:alert('bla bla bla');

    直到现在我还没有找到避免这样的行为... execpt在所有计时器上执行此操作:

    var MyTimer;
    function MyTimer_Handler(){
     try{
      clearTimeout(TemporizadorCapaLogin);
      try{
       // Do whatever the timer must do
      }Catch(theError){}
      MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);
     }Catch(theError){}
    }
    try{MyTimer=setTimeout(function(){try{MyTimer_Handler()}Catch(theError){}},theIntervalToRepeatInMiliseconds);}Catch(theError){}
    

    它也不是一个完美的解决方案......如果浏览器只是在计时器被触发时但在fisrt尝试之前(在接近完美的毫秒sycn竞争条件之前)销毁de JavaScript管理器,它也会导致浏览器显示消息。 / p>

    但是有时候,某些事情会在一段时间之后完成......没有更好/完美的解决方案,这是我能做的最好的事情!

    我个人讨厌这种编码不好的浏览器(其中一个是IE),但我必须支持它们!

答案 2 :(得分:0)

此处讨论了特定于浏览器的方法:onpropertychange for a textbox in Firefox?

然而,经过各种实验,我发现唯一的跨浏览器方法是使用window.setInterval()来检查更改(例如,每20毫秒)。不优雅,但非常有效。

答案 3 :(得分:0)

//

function clonekeyup(e){
 var e= window.event || e;
 var who= e.target || e.srcElement;
 var val= who.value;
 var tem, temp, TA= document.getElementsByTagName('textarea'), L= TA.length;
 while(L){
  tem= TA[--L];
  if(tem.onchange== arguments.callee && tem.value!= val) tem.value= val;
 }
}

将onkeyup和onchange函数分配给您想要相互反映的textareas。 例如,这会将处理程序分配给所有 textareas。

var tem, TA= document.getElementsByTagName('textarea'), L= TA.length;
while(L){
 tem= TA[--L];
 tem.onkeyup= tem.onchange= clonekeyup;
}

答案 4 :(得分:-1)

使用shift + letter时,Keyup无法正常工作,但如果将其绑定到window对象,它可以正常工作。

这是一个利用它的jQuery插件:

$.fn.edited = function(callback) {
  this.each(function() {

    var that = $(this);
    var active = false;

    that.focusin(function() {
      active = true;
    });

    that.focusout(function() {
      active = false;
    });

    $(window).keyup(function(e) {
      if (active) {
        callback(e);
      }
    });

  });
};   

用法:

$("textarea").edited(function(){
    ...
});