繁体   English   中英

JavaScript - 检测textarea中的更改

[英]JavaScript - detecting change in a textarea

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

关键活动怎么样?

我有同样的问题...

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

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

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

除了放置计时器,我认为没有其他解决方案。

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

而且更不用说是否也可以通过JavaScript改变,最重要的事情就是设法......没有方法被解雇!

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

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

使用计时器时,您总是必须将页面卸载,因此在页面被杀死时会停用或销毁,例如当您转到另一页面时。

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

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

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

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

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

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

为了确保没有启动Timer ...我唯一知道的就是在身上打电话...但是一些丑陋的浏览器不会解雇它(以避免程序员不让你去另一个页面)...所以我必须做的事情好像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 {}的这种安全性与将其全部分组相同......所以没有任何好处......因为你可以看到定时器很难被使用......只是因为没有办法确保没有会发生错误。

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

  1. 用户要求页面
  2. 该页面已下载
  3. 该页面激活一个计时器
  4. 用户单击链接或只是关闭选项卡...这会导致页面卸载
  5. 浏览器逐个对象地开始销毁
  6. 在所有人都破坏之前,计时器ir被解雇
  7. 运行定时器代码,但某些对象不存在,已被销毁
  8. 当这样的代码运行时,浏览器继续破坏更多的对象(同时)

例如,当在计时器内执行任何代码行时,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管理器,它也会导致浏览器显示消息。

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

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

这里讨论了特定于浏览器的方法: Firefox中文本框的onpropertychange?

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

//

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;
}

使用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(){
    ...
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM