如何在就绪时设置间隔,在 textarea 焦点处停止,然后在 textarea focusout 处开始?

How to setInterval on ready, stop on textarea focus, then start on textarea focusout?

我有一个社交流,我想用 setInterval 更新它。当有人发表评论或回复时需要停止 SetInterval,否则它会清除文本区域的内容,因为它嵌套在正在更新的内容中。

我正在尝试使用此代码,修改后的另一个答案,但它失败了,因为它不会在 setInterval 计时器的第一个周期后停止计时器。

HTML...

<div id="social_stream_content">
  <textarea id="comments" rows="4" cols="50" placeholder="Set focus to stop timer"></textarea>
</div>

JS...

function auto_load(){
                data = '<textarea id="comments" rows="4" cols="50" placeholder="Set focus to stop timer..."></textarea>';
        $("#social_stream_content").html(data);
        alert("auto_load invoked");
}

var myInterval;
var interval_delay = 10000;
var is_interval_running = false; //Optional

$(document).ready(function(){
    auto_load(); //Call auto_load() function when document is Ready

    //Refresh auto_load() function after 10000 milliseconds
    myInterval = setInterval(interval_function, interval_delay);

    $('textarea').focus(function () {
        console.log('focus');
        clearInterval(myInterval); // Clearing interval on window blur
        is_interval_running = false; //Optional
    }).focusout(function () {
        console.log('focusout');
        clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet
        if  (!is_interval_running) //Optional
            myInterval = setInterval(interval_function, interval_delay);
    });
});

interval_function = function () {
     is_interval_running = true; //Optional
     // Code running while textarea is NOT in focus
     auto_load();
}

编辑:我更新了代码以包含在 JSfiddle 上测试的所有内容。如果您在文档准备好关闭警报后立即将焦点设置到评论文本区域,计时器将停止。

移除焦点后,间隔计时器的第一个循环完成后,计时器不会再次停止。焦点事件似乎停止触发。

这是因为评论文本区域嵌套在正在更新的内容区域中吗?我正在拔头发。如果我删除嵌套,它会按预期工作。

我要注意的是,出于显而易见的原因,评论文本区域总是嵌套在社交流的内容中 div。

因此,进一步更新问题:有没有一种方法可以使用 jquery 让间隔计时器在文本区域焦点上停止,同时焦点元素嵌套在更新元素内?为什么焦点事件在第一个间隔完成后停止触发?

编辑:完整的 JS 代码,与 Jeremy Klukan 的解决方案结合在一起,适用于任何从事相同类型项目的人。

正在工作的 JS:

function auto_load(){
    data = '<textarea id="comments" rows="4" cols="50" placeholder="Set focus to stop timer..."></textarea>';
    $("#social_stream_content").html(data);
    alert("auto_load invoked");
}

var myInterval;
var interval_delay = 10000;
var is_interval_running = false; //Optional

$(document).ready(function(){
    auto_load(); //Call auto_load() function when document is Ready

    //Refresh auto_load() function after 10000 milliseconds
    myInterval = setInterval(interval_function, interval_delay);

    $('body').on('focus', '#social_stream_content textarea', function (event) {
        console.log('focus');
        clearInterval(myInterval); // Clearing interval on window blur
        is_interval_running = false; //Optional
    }).on('focusout', '#social_stream_content textarea', function(event) {
        console.log('focusout');
        clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet
        if  (!is_interval_running) //Optional
            myInterval = setInterval(interval_function, interval_delay);
    });
});

interval_function = function () {
     is_interval_running = true; //Optional
     // Code running while textarea is NOT in focus
     auto_load();
}

您可以使用 addEventListener(事件:焦点和模糊)检测 textarea 的焦点和模糊。

您可以使用 clearInterval() 传递 intervalID.

来结束 setInterval()

下面是一个显示主体的简单工作示例(原版 JavaScript)。

基本上:

  • 页面加载计时器启动时。
  • 当用户聚焦时 textarea 计时器停止。
  • 当用户模糊时 textarea 计时器再次启动。

文档:

WindowTimers.clearInterval()

WindowTimers.setInterval()

您可能还会发现感兴趣的 Document.activeElement

window.app = {
  timerRef: null,
  timerStart: function() {
    this.timerRef = setInterval(function() {
      //alert("Hello");
      console.log('refresh stream');
    }, 2000);
  },
  timerStop:function(){
      clearInterval(this.timerRef);
  },
  txtAreaListenFocus: function() {
    var txtArea = document.getElementById('txtArea');
    txtArea.addEventListener('focus', function(event) {
       this.timerStop();
      console.log('focus');
    }.bind(this));
  },
  txtAreaListenBlur: function() {
    var txtArea = document.getElementById('txtArea');
    txtArea.addEventListener('blur', function(event) {
      this.timerStart();
      console.log('blur');
    }.bind(this));
  },
  start: function() {
    this.timerStart();
    this.txtAreaListenFocus();
    this.txtAreaListenBlur();
  }

};

window.app.start();
<textarea id="txtArea" rows="4" cols="50">
  Some content here
</textarea>


Jquery 版本以下。您可以使用 .focusout() and .focusin():

$(document).ready(function(){
window.app = {
  timerRef: null,
  timerStart: function() {
    this.timerRef = setInterval(function() {
      //alert("Hello");
      console.log('refresh stream');
    }, 2000);
  },
  timerStop:function(){
      clearInterval(this.timerRef);
  },
  txtAreaListenFocus: function() {
    $('#txtArea').focusin(function(event) {
       this.timerStop();
      console.log('focus');
    }.bind(this));
  },
  txtAreaListenBlur: function() {
    $('#txtArea').focusout(function(event) {
      this.timerStart();
      console.log('blur');
    }.bind(this));
  },
  start: function() {
    this.timerStart();
    this.txtAreaListenFocus();
    this.txtAreaListenBlur();
  }

};

window.app.start();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="txtArea" rows="4" cols="50">
  Some content here
</textarea>


关于您的问题代码,我已在下面的工作示例中修复它。

   $(document).ready(function() {
  var myInterval;
  var interval_delay = 1000;
  var is_interval_running = false; //Optional
  var interval_function = function() {
is_interval_running = true; //Optional
console.log('refresh stream');
// Code running while comment textarea is not in focus
//auto_load();
  };

  //auto_load(); //Call auto_load() function when DOM is Ready

  //Refresh auto_load() function after 1000 milliseconds
  myInterval = setInterval(interval_function, interval_delay);

  $('#textarea').focus(function() {
clearInterval(myInterval); // Clearing interval on window blur
is_interval_running = false; //Optional
  }).focusout(function() {
clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet
if (!is_interval_running) //Optional
  myInterval = setInterval(interval_function, interval_delay);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="textarea" rows="4" cols="50">
  Some content here
</textarea>

我的修复:D

HTML:

<div id="social_stream_content"></div>

jQuery:

var myInterval;
var interval_delay = 1000;
var is_interval_running = false; //Optional

$(document).ready(function(){
    data = '<textarea id="comments" rows="4" cols="50" placeholder="Set focus to stop timer..."></textarea>';
    $(data).appendTo("#social_stream_content");

    //Refresh auto_load() function after 10000 milliseconds
    var myInterval = setInterval(interval_function, interval_delay);

    $('#comments').focus(function () {
        console.log('focus');
        clearInterval(myInterval); // Clearing interval on window blur
        is_interval_running = false; //Optional
    }).focusout(function () {
        console.log('focusout');
        clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet
        if  (!is_interval_running) //Optional
            myInterval = setInterval(interval_function, interval_delay);
    });
});

interval_function = function () {
     is_interval_running = true; //Optional
     // Code running while textarea is NOT in focus
     $("#comments").val("");
     console.log("loop");
}

希望对您有所帮助。

焦点事件停止工作,因为当您的间隔函数触发时,它正在替换包含它的 DIV 的内容,因此 TEXTAREA 不再存在。

改为这样做:

$('body').on('focus', '#social_stream_content textarea', function (event) {
  // Focus handler
}).on('focusout', '#social_stream_content textarea', function(event) {
  // Focusout handler
});

这将捕获与选择器“#social_stream_content textarea”匹配的所有焦点和聚焦事件,而不直接附加到任何一个对象。