jquery 如何限制对页面上更改的源代码采取的“操作”(更新)

jyztefdp  于 2023-03-17  发布在  jQuery
关注(0)|答案(3)|浏览(132)

我搜索了很多方法来解决这个并非唯一的问题,但是没有找到任何适合我的HTML页面环境的方法。
我有一个输入文本,其中包含生成 something 的某种源代码,我可以在同一个HTML页面上显示该 something 的预览注意,源可以是LaTeX文件、电子邮件、Java程序、光线跟踪代码等。生成预览的“动作”具有一定的成本,所以我不想在每次修改源代码时都生成这个预览,但是我希望预览能够自动更新(触发 action),而无需用户显式请求。
另一种表述问题的方式是保持源和宿与某个合理的频率同步。
下面是我的解决方案,这是太贪婪(更新在每一个变化):

$('#source-text').keyup(function(){
    updatePreview(); // update on a change
  });

我试着使用时间戳来限制它:

$('#source-text').keyup(function(){
    if (nextTime "before" Now) { // pseudocode
       updatePreview(); // update on a change
    } else {
       nextTime = Now + some delay // pseudocode
    }
  });

这样更好,但是一旦用户停止在源文本字段中键入,它可能会错过最后的更新。
我想到了一个更新的“轮询循环”,它以合理的时间间隔运行,查找更改或表示需要更新的标记,但我不确定这是否是一个HTML页面的好模型(甚至不确定如何在javascript中实现)。

3yhwsihp

3yhwsihp1#

使用setTimeout,但是保存引用,这样你就可以防止它在进一步编辑时执行。基本上,只在最后一次击键过去5秒后更新预览一次(至少在下面的例子中)。

// maintain out of the scope of the event
var to;

$('#source-text').on('keyup',function(){
  // if it exists, clear it and prevent it from occuring
  if (to) clearTimeout(to);

  // reassign it a new timeout that will expire (assuming user doesn't
  // type before it's timed out)
  to = setTimeout(function(){
    updatePreview();
  }, 5e3 /* 5 seconds or whatever */);
});

参考文献:

我并不是要自我碰撞,但这里有另一个(相关的)答案:How to trigger an event in input text after I stop typing/writing?

gmxoilav

gmxoilav2#

我调整了@bradchristie的回答,这并不是我想要的行为(用户停止输入后只会发生一次更新--我希望它们在输入过程中发生,但速度要慢一些)。
以下是解决方案(在http://jsfiddle.net/p4u2mhb9/3/上演示):

// maintain out of the scope of the event
var to;
var updateCount = 0;
var timerInProgress = false;

$('#source-text').on('keyup', function () {
    // reassign a new timeout that will expire
    if (!timerInProgress) {
        timerInProgress = true;
        to = setTimeout(function () {
            timerInProgress = false;
            updatePreview();
        }, 1e3 /* 1 second */ );
    }
});
ckocjqey

ckocjqey3#

我让@布拉德Christie的回答更通用,见http://jsfiddle.net/NickU/gLxucfjv/38/

var lazyRun = function (funcCall, delay, key) 
{
  if (typeof funcCall !== "function") return;
  if (typeof key === "undefined") key = "timeoutId";
  funcCall.to = funcCall.to || {};
  if (funcCall.to[key]) clearTimeout(funcCall.to[key]);
  var args = arguments.length > 3 ? Array.prototype.slice.call(arguments, 3) : [];
  funcCall.to[key] = setTimeout(funcCall, delay, ...args);
};


  $(document).ready(function () 
  {
      $('input').on('keyup', function () {
          lazyRun(updatePreview,1e3, this.id, '#update-count-'+ this.id, 
          this.updateCount ? ++this.updateCount : (this.updateCount = 1));
      });
      $('label').text("not updated yet");
  });

  function updatePreview(id, updateCount) {
      $(id).text("->" + updateCount);
  }

超文本:

<form>
    <input type="text" id="source-text" />
    <label id="update-count-source-text">not updated</label><hr>
     <input type="text" id="source-text-2" />
    <label id="update-count-source-text-2">not updated</label>
 </form>

lazyRun的最简单形式是:

var lazyRun = function (funcCall, delay) {
  if (funcCall.to) clearTimeout(funcCall.to);
  funcCall.to = setTimeout(funcCall, delay);
};

相关问题