延迟自动重新加载如果一个 div 是可见的。

huangapple go评论59阅读模式
英文:

Delay an automatic reload if a div is visible

问题

我尝试创建一个小项目来跟踪飞越我的地区的飞行。使用python包来访问flight-radar24 API,我成功获取了所需的数据。

我创建了一个systemd服务,以便每隔x秒启动我的python脚本。该脚本输出一个名为"data.html"的HTML文件。每架飞机都输出两个div:一个可见,包含一些信息,一个不可见,包含更详细的信息。

项目的第二部分是显示检索到的数据。我按照以下步骤进行:

  1. 简单的网页(index.html)
  2. CSS文件
  3. 一个时钟(JavaScript,用于显示时间)位于index.html的“header”部分
  4. jQuery(本地下载并使用)
  5. 一个重新加载的JavaScript(从data.html中获取并打印到index.html的“datadiv”中)
  6. 一个“弹出”管理器,这样您可以在单击飞机时看到带有附加信息的漂亮div。

我的问题是,当“弹出”可见时,我无法停止自动重新加载机制。如果在1或2秒内单击一架飞机,您来不及阅读。

我尝试在单击函数中使用"clearInterval/clearTimeout",但没有成功。

我尝试了以下方法:

  • 合并一些js文件,以考虑可能存在的变量范围问题。
  • 在index.html中创建"弹出" div,并保持其为空,然后使用jQuery更改内容,以便在加载data.html之前该div已经存在。
  • 使用setTimeout而不是setInterval。
  • 还有很多我记不起来的事情...

弹出代码(每架飞机("trigger")都有自己的div ID以及附加信息(eXYZ)):

$(function() {
   $('.trigger').click(function(e) {
     $('.plane_info').hide();
     $('div#e'+this.id).show();
   });

   $('.trigger').mouseleave(function(e) {
     $('div#e'+this.id).hide();
   });
 });

重新加载代码:

function setupRefresh()
{
    setInterval("refreshBlock();",5000);
}

function refreshBlock()
{
    $('#datadiv').load("../data.html");
}
setupRefresh();

希望这有所帮助。

英文:

I tried to create a small project to track flying over my area.
Using python package for flight-radar24 API, I successfully got the needed data.

I've created systemd service to launch my python script every x seconds. This script output a html file named "data.html".
Each plane output two div: One visible with few information, one invisible with more detailed information.

Second part of the project is to show the retrieved data. I proceed as follow:

  • 1/ simple webpage (index.html)
  • 2/ CSS file
  • 3/ A clock (JavaScript, just to show the time) on the "header" part of index.html
  • 4/ jQuery (to use jQuery, locally downloaded)
  • 5/ A reloading JavaScript (fetch and print data.html into the "datadiv" of index.html)
  • 6/ A "popup" manager, so you can see a nice div with additional information while clicking on a plane.

My problem is that I failed at stopping the auto-reloading mechanism when the "popup" is visible. If you click on a plane while the reloading is scheduled in 1 or 2 seconds, you don't have time to read.

I tried using "clearInterval/clearTimeout" in the click function without any success.

I tried the following:

  • Merging some js file, thinking I could have a variable scope issue.
  • Creating the "popup" div in index.html and keeping it empty, then just change the content using jQuery so this div exists before the data.html is loaded.
  • Using setTimeout instead of setInterval.
  • And to many thing I can't remember...

The popup code (each plane ("trigger") got it's own div ID with additional information (eXYZ)):

$(function() {

   $('.trigger').click(function(e) {
     $('.plane_info').hide();
     $('div#e'+this.id).show();
   });

   $('.trigger').mouseleave(function(e) {
     $('div#e'+this.id).hide();
   });

 });

The reloading code:

function setupRefresh()
{
    setInterval("refreshBlock();",5000);
}

function refreshBlock()
{
    $('#datadiv').load("../data.html");
}
setupRefresh();

答案1

得分: 1

你忽略了代码部分,其中你尝试使用clearInterval的部分...但鉴于你没有捕获setInterval的返回值,我可以猜到出了什么问题:

要使用clearInterval,你需要在设置间隔时捕获间隔ID,这样浏览器才知道要清除哪个间隔。

let foo = setInterval(refreshBlock, 5000); // 当你想要开始刷新时

// ...

clearInterval(foo); // 当你想要停止刷新时
英文:

You omitted the part of the code where you tried using clearInterval... but given that you aren't capturing the return value of setInterval, I can guess what went wrong:

In order to use clearInterval you need to capture the interval ID when setting the interval, so the browser can know which one to clear.

let foo = setInterval(refreshBlock,5000); // when you want to start refreshing

// ...

clearInterval(foo); // when you want to stop refreshing

答案2

得分: 0

啊,我看到您的项目面临一个有趣的挑战!为了解决“弹出窗口”可见时阻止自动重新加载的问题,您可以通过修改重新加载代码,添加一个条件来检查弹出窗口当前是否可见,然后再触发重新加载。让我们进行必要的调整:

<!DOCTYPE html>
<html>
<head>
  <title>Flight Radar</title>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
  <div id="header">
    <!-- 在这里显示时钟 -->
  </div>
  <div id="datadiv">
    <!-- 从data.html加载的数据将显示在这里 -->
  </div>
  <script src="jquery.js"></script>
  <script>
    $(function() {
      $('.trigger').click(function(e) {
        $('.plane_info').hide();
        $('div#e' + this.id).show();
        stopAutoReload();
      });

      $('.trigger').mouseleave(function(e) {
        $('div#e' + this.id).hide();
        restartAutoReload();
      });

      function setupRefresh() {
        intervalID = setInterval(refreshBlock, 5000);
      }

      function refreshBlock() {
        if ($('.plane_info').is(":hidden")) {
          $('#datadiv').load("../data.html");
        }
      }

      function stopAutoReload() {
        clearInterval(intervalID);
      }

      function restartAutoReload() {
        setupRefresh();
      }

      var intervalID; // 用于存储间隔ID的变量
      setupRefresh(); // 初始时开始自动重新加载
    });
  </script>
</body>
</html>
英文:

Ah, I see you're facing an interesting challenge with your project! To address the issue of preventing automatic reloading when the "popup" is visible, you can modify the reloading code by adding a condition to check if the popup is currently visible before triggering the reload. Let's make the necessary adjustments:

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Flight Radar&lt;/title&gt;
  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;style.css&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id=&quot;header&quot;&gt;
    &lt;!-- Clock display here --&gt;
  &lt;/div&gt;
  &lt;div id=&quot;datadiv&quot;&gt;
    &lt;!-- Data from data.html will be loaded here --&gt;
  &lt;/div&gt;

  &lt;script src=&quot;jquery.js&quot;&gt;&lt;/script&gt;
  &lt;script&gt;
    $(function() {
      $(&#39;.trigger&#39;).click(function(e) {
        $(&#39;.plane_info&#39;).hide();
        $(&#39;div#e&#39; + this.id).show();
        stopAutoReload();
      });

      $(&#39;.trigger&#39;).mouseleave(function(e) {
        $(&#39;div#e&#39; + this.id).hide();
        restartAutoReload();
      });

      function setupRefresh() {
        intervalID = setInterval(refreshBlock, 5000);
      }

      function refreshBlock() {
        if ($(&#39;.plane_info&#39;).is(&quot;:hidden&quot;)) {
          $(&#39;#datadiv&#39;).load(&quot;../data.html&quot;);
        }
      }

      function stopAutoReload() {
        clearInterval(intervalID);
      }

      function restartAutoReload() {
        setupRefresh();
      }

      var intervalID; // Variable to store the interval ID
      setupRefresh(); // Start the automatic reloading initially
    });
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

答案3

得分: 0

让我们尝试一种简单的方法:

  • 有一个名为isVisible的变量,用于跟踪弹出窗口是否可见
  • 当弹出窗口不可见时,有条件地运行refreshBlock
let isVisible = false;

function togglePopup(toggle) {
  if (toggle) {
    $(".content").show();
    isVisible = true;
  } else {
    $(".content").hide();
    isVisible = false;
  }
}
let counter = 0;

function refreshBlock() {
  if (!isVisible) {
    console.log("Reloading...", ++counter);
  }
  // 或者,您可以放弃`isVisible`变量,直接检查弹出窗口元素是否可见:
  /*
  if ($(".content").is(":hidden")) {
    console.log("Reloading...", ++counter);
  }
  */
}

setInterval(refreshBlock, 1000);
.content {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 200px;
  height: 100px;
  background-color: #e8eae6;
  padding: 10px;
  z-index: 100;
  display: none;
}

.close-btn {
  position: absolute;
  right: 20px;
  top: 15px;
  background-color: black;
  color: white;
  padding: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button onclick="togglePopup(true)">显示弹出窗口</button>
<div class="content">
  <div onclick="togglePopup(false)" class="close-btn">
    &#215;
  </div>
  <h3>弹出窗口</h3>
</div>
英文:

Let's try a simple approach:

  • Have a variable called isVisible that tracks whether the popup is visible or not
  • Conditionally run refreshBlock if the popup is not visible

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let isVisible = false;

function togglePopup( toggle ) {
  if ( toggle ){
    $(&quot;.content&quot;).show();
    isVisible = true;
  } else {
    $(&quot;.content&quot;).hide();
    isVisible = false;
  }
}
let counter = 0;

function refreshBlock(){
  if ( !isVisible ){
    console.log(&quot;Reloading...&quot;, ++counter);
  }
  // Alternatively, you can discard the isVisible variable, and just check
  // whether the popup element is visible or not:
  /*
  if ( $(&quot;.content&quot;).is(&quot;:hidden&quot;) ){
    console.log(&quot;Reloading...&quot;, ++counter);
  }
  */
}

setInterval(refreshBlock, 1000);

<!-- language: lang-css -->

.content {
  position: absolute;
	top: 50%;
	left: 50%;
  width: 200px;
	height: 100px;
	background-color: #e8eae6;
	padding: 10px;
	z-index: 100;
	display: none;
}
		
.close-btn {
  position: absolute;
	right: 20px;
	top: 15px;
	background-color: black;
	color: white;
	padding: 4px;
}

<!-- language: lang-html -->

&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js&quot;&gt;&lt;/script&gt;
	&lt;button onclick=&quot;togglePopup(true)&quot;&gt;show popup&lt;/button&gt;
	&lt;div class=&quot;content&quot;&gt;
		&lt;div onclick=&quot;togglePopup(false)&quot; class=&quot;close-btn&quot;&gt;
			&#215;
		&lt;/div&gt;
		&lt;h3&gt;Popup&lt;/h3&gt;
	&lt;/div&gt;

<!-- end snippet -->

答案4

得分: 0

已完成!我还有一些CSS问题要解决(摆脱使用“
”作为填充以扩展“hideall”按钮的不干净方法),但混合答案给了我一个可以工作的东西。

我添加了一个超时,所以弹出窗口在几秒钟后自动关闭,单击弹出窗口以外的区域和航班列表也会关闭它。这部分有点混乱,使用了航班列表顶部和底部的两个按钮来实现。一个更清洁的解决方案本应该是单击除了弹出窗口区域以外的任何地方(即使在显示弹出窗口时单击航班列表也会重新显示新的弹出窗口,所以并不算真正混乱)。

非常感谢你们三个!

以下是您提供的HTML和JavaScript代码,没有翻译:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->
<!DOCTYPE html>
<html>
<head>
  <title>Flight Radar</title>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<button class="trigger_close" onclick="hideall()">
  <div class="heading" id="clock"/>
	<script src="js/jquery-3.7.0.min.js"></script>
    <script src="js/clock.js"></script>
  </div>
  <br/>
  <div class="table_headings">
<table>
  <tr>
    <td width="280" style="text-align: center">CALLSIGN</td>
    <td width="200" style="text-align: center">&nbsp;FROM</td>
    <td width="250" style="text-align: center">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TO</td>
    <td width="250" style="text-align: center">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ALT</td>
  </tr>
</table>
  </div><br/><br/></button>
  <div id="datadiv">
    <!-- Data from data.html will be loaded here -->
  </div>
  <div class="plane_info" id="master"></div> 
  <script>

          function hideall(){
          if ($('div#master').is(":visible")) {

		restartAutoReload();
	  }}

	  function showplanedetails(flight_callsign,flight_number,ticket_aircraft,ticket_airline,ticket_country_ori_full,ticket_city_ori,ticket_country_dest_full,ticket_city_dest) {	
        $('div#master').hide();
        clearTimeout(timeoutID);
        $('div#master').html("<table class='ticket_table'>" +
        "<div class='plane_info_header'>"+ flight_callsign + " <img src='img/departingflights2.png' width='35' height='35' /> " + flight_number +"</div>"+
        "<div class='plane_info_content'>Aicraft: " + ticket_aircraft + "</div><br>"+
        "<div class='plane_info_content'>Airline: " + ticket_airline +"</div><br>"+
        "<div class='plane_info_content'>From: " + ticket_country_ori_full + " - " + ticket_city_ori + " </div><br>"+
        "<div class='plane_info_content'>Dest: " + ticket_country_dest_full + " - " + ticket_city_dest +"</div>");
        $('div#master').show();
        stopAutoReload();
      }

      function setupRefresh() {
        intervalID = setInterval(refreshBlock, 5000);
      }

      function refreshBlock() {
        if ($('div#master').is(":hidden")) {
          $('#datadiv').load("data.html");
        }
      }

      function stopAutoReload() {
        clearInterval(intervalID);
        timeoutID = setTimeout(restartAutoReload, 5000);
      }

      function restartAutoReload() {
		$('div#master').hide();
        setupRefresh();
      }

      var intervalID; // Variable to store the interval ID
      var timeoutID; // Variable to store the interval ID
      setupRefresh(); // Start the automatic reloading initially
  </script>
<button class="trigger_close" onclick="hideall()">
 <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
</button>
</body>
</html>

<!-- end snippet -->

Python脚本生成的“data.html”现在输出如下按钮:

html += f'<button class="trigger" onclick="showplanedetails(\'{flight_callsign}\',\'{flight_number}\',\'{ticket_aircraft}\',\'{ticket_airline}\',\'{ticket_country_ori_full}\',\'{ticket_city_ori}\',\'{ticket_country_dest_full}\',\'{ticket_city_dest}\')">'

将来某一天会尝试为这个项目创建一个Git存储库。

主要航班信息板

航班详情

英文:

Done! I still have a few css think to fix (getting ride of dirty "<br/>" used as padding to expand "hideall" buttons), but mixing the answers gave me something working.

I added a timeout so the popup close itself after a few seconds, and clicking out of a the popup and the flight list also close it. This part is dirty, done by using two buttons on top and bottom of flights list. A cleaner solution would have been clicking anywhere but the popup area (even if, clicking on flight list while popup is shown brings back the new popup, so that's not really dirty...)

Many thanks to the three if you!

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Flight Radar&lt;/title&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;style.css&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;button class=&quot;trigger_close&quot; onclick=&quot;hideall()&quot;&gt;
&lt;div class=&quot;heading&quot; id=&quot;clock&quot;/&gt;
&lt;script src=&quot;js/jquery-3.7.0.min.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;js/clock.js&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;br/&gt;
&lt;div class=&quot;table_headings&quot;&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td width=&quot;280&quot; style=&quot;text-align: center&quot;&gt;CALLSIGN&lt;/td&gt;
&lt;td width=&quot;200&quot; style=&quot;text-align: center&quot;&gt;&amp;nbsp;FROM&lt;/td&gt;
&lt;td width=&quot;250&quot; style=&quot;text-align: center&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TO&lt;/td&gt;
&lt;td width=&quot;250&quot; style=&quot;text-align: center&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ALT&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;&lt;/button&gt;
&lt;div id=&quot;datadiv&quot;&gt;
&lt;!-- Data from data.html will be loaded here --&gt;
&lt;/div&gt;
&lt;div class=&quot;plane_info&quot; id=&quot;master&quot;&gt;&lt;/div&gt; 
&lt;script&gt;
function hideall(){
if ($(&#39;div#master&#39;).is(&quot;:visible&quot;)) {
restartAutoReload();
}}
function showplanedetails(flight_callsign,flight_number,ticket_aircraft,ticket_airline,ticket_country_ori_full,ticket_city_ori,ticket_country_dest_full,ticket_city_dest) {	
$(&#39;div#master&#39;).hide();
clearTimeout(timeoutID);
$(&#39;div#master&#39;).html(&quot;&lt;table class=&#39;ticket_table&#39;&gt;&lt;div class=&#39;plane_info_header&#39;&gt;&quot;+ flight_callsign + &quot; &lt;img src=&#39;img/departingflights2.png&#39; width=&#39;35&#39; height=&#39;35&#39; /&gt; &quot; + flight_number +&quot;&lt;/div&gt;&quot;+
&quot;&lt;div class=&#39;plane_info_content&#39;&gt;Aicraft: &quot; + ticket_aircraft + &quot;&lt;/div&gt;&lt;br&gt;&quot;+
&quot;&lt;div class=&#39;plane_info_content&#39;&gt;Airline: &quot; + ticket_airline +&quot;&lt;/div&gt;&lt;br&gt;&quot;+
&quot;&lt;div class=&#39;plane_info_content&#39;&gt;From: &quot; + ticket_country_ori_full + &quot; - &quot; + ticket_city_ori + &quot; &lt;/div&gt;&lt;br&gt;&quot;+
&quot;&lt;div class=&#39;plane_info_content&#39;&gt;Dest: &quot; + ticket_country_dest_full + &quot; - &quot; + ticket_city_dest +&quot;&lt;/div&gt;&quot;);
$(&#39;div#master&#39;).show();
stopAutoReload();
}
function setupRefresh() {
intervalID = setInterval(refreshBlock, 5000);
}
function refreshBlock() {
if ($(&#39;div#master&#39;).is(&quot;:hidden&quot;)) {
$(&#39;#datadiv&#39;).load(&quot;data.html&quot;);
}
}
function stopAutoReload() {
clearInterval(intervalID);
timeoutID = setTimeout(restartAutoReload, 5000);
}
function restartAutoReload() {
$(&#39;div#master&#39;).hide();
setupRefresh();
}
var intervalID; // Variable to store the interval ID
var timeoutID; // Variable to store the interval ID
setupRefresh(); // Start the automatic reloading initially
&lt;/script&gt;
&lt;button class=&quot;trigger_close&quot; onclick=&quot;hideall()&quot;&gt;
&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;
&lt;/button&gt;
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

The python script generating "data.html" now outputs buttons such as:

            html += f&#39;&lt;button class=&quot;trigger&quot; onclick=&quot;showplanedetails(\&#39;{flight_callsign}\&#39;,\&#39;{flight_number}\&#39;,\&#39;{ticket_aircraft}\&#39;,\&#39;{ticket_airline}\&#39;,\&#39;{ticket_country_ori_full}\&#39;,\&#39;{ticket_city_ori}\&#39;,\&#39;{ticket_country_dest_full}\&#39;,\&#39;{ticket_city_dest}\&#39;)&quot;&gt;&#39;

Will try someday to create a git repository for this project.
Main Flight Board

Flight Details

huangapple
  • 本文由 发表于 2023年7月18日 02:35:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76707236.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定