Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
553 views
in Technique[技术] by (71.8m points)

javascript - 为什么在没有延迟的情况下运行超时功能时会触发阻塞的指针事件?(Why blocked pointer events are fired while timed-out function with no delay is running?)

Why after clicking the load button, both buttons load and dummy covered by the loader's overlay still register clicks?

(为什么单击加载按钮后,加载器覆盖层覆盖的两个按钮加载虚拟按钮仍记录点击?)

Sometimes when clicking the load button, the loader is not even displayed.

(有时,当单击加载按钮时,甚至不会显示加载器。)

Buttons correctly don't register clicks

(正确的按钮不会记录点击)

  • if we for example display the loader from the start by commenting the line 5 loader.hide();

    (例如,如果我们通过注释第5行loader.hide();从头开始显示加载器loader.hide();)

  • add some timeout delay ( but I don't want that )

    (添加一些超时延迟( 但是我不想要 ))

Example (best to run in Full Page mode):

(示例(最好在整页模式下运行):)

 const iterations = 1e3; const multiplier = 1e9; const loader = $('.css-loader-fullscreen'); const dummyBtn = $('#dummy'); const loadBtn = $('#load'); loader.hide(); dummyBtn.on('click', () => console.log('dummy clicked')); loadBtn.on('click', jsHeavyTask); function calculatePrimes(iterations, multiplier) { var primes = []; for (var i = 0; i < iterations; i++) { var candidate = i * (multiplier * Math.random()); var isPrime = true; for (var c = 2; c <= Math.sqrt(candidate); ++c) { if (candidate % c === 0) { // not prime isPrime = false; break; } } if (isPrime) { primes.push(candidate); } } return primes; } function jsHeavyTask(){ console.log('heavy function started'); loader.show(); setTimeout(() => { const start = performance.now(); calculatePrimes(iterations, multiplier); const end = performance.now(); loader.hide(); console.log('heavy function ended in '+ (end - start).toFixed() +' ms'); }); } 
 input {width: 150px} .css-loader-background { display: flex; align-items: center; justify-content: center; background-color: white; border-radius: 10px; font-size: 12px; } .css-loader-fullscreen { top: 0; bottom: 0; left: 0; right: 0; z-index: 100000; position: fixed; background-color: rgba(0, 0, 0, 0.4); display: flex; justify-content: center; align-items: center; } .css-loader-fullscreen .css-loader-background { width: 100px; height: 100px; } .css-loader-animation { width: 40px; height: 40px; border-radius: 50%; border: 8px solid transparent; border-top-color: purple; border-bottom-color: purple; text-indent: -9999em; animation: spinner 0.8s ease infinite; transform: translateZ(0); } @-webkit-keyframes spinner { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <div class="css-loader-fullscreen"> <div class="css-loader-background"> <div class="css-loader-animation"></div> </div> </div> <input id="load" type="button" value="load"> <input id="dummy" type="button" value="dummy"> 

Run times of jsHeavyTask() are different on every machine.

(每台机器上的jsHeavyTask()运行时间都不同。)

For me it's around 5s.

(对我来说大约是5秒。)

You can change iterations and multiplier constants to modify the run time.

(您可以更改iterationsmultiplier常量来修改运行时间。)

There is lot more of weird I observed related to this no delay timed-out calc-heavy function, especially in Webkit, but first I am curious about this one.

(我观察到与此无延迟超时calc-heavy函数有关的更多奇怪信息,尤其是在Webkit中,但首先我对此感到好奇。)

  ask by DarkPatronusLinX translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

as first I would try to call the heavy function differently:

(首先,我将尝试以不同的方式调用Heavy函数:)

loadBtn.on('click', () => {
  loader.show();  
  jsHeavyTask
});

If that doesn't do the trick, I would try different approach with the show/hide method and use opacity with ponter-events combination for better performance and disabling passing through the clicks.

(如果那不能解决问题,我将尝试使用show / hide方法的不同方法,并将不透明性与ponter-events组合一起使用,以实现更好的性能并禁用点击。)

JavaScript

(的JavaScript)

const loader = $('.css-loader-fullscreen');
const dummyBtn = $('#dummy');
const loadBtn = $('#load');
const content = $('#content');

const cssHidden = 'css-hidden';
const cssLoading = 'css-loading';

loader.addClass(cssHidden);

dummyBtn.on('click', () => console.log('dummy clicked'));
loadBtn.on('click', () => {
  content.addClass(cssLoading);
  loader.removeClass(cssHidden);

  jsHeavyTask
});

function jsHeavyTask(){
  console.log('heavy function started');

  setTimeout(() => {

    for ( var i = 0; i < 2e7; i++){
      Math.sqrt(Date.now());
    }

    loader.addClass(cssHidden);
    content.removeClass(cssLoading);

    console.log('heavy function ended');
  });
}

CSS (only changes)

(CSS(仅更改))

.css-loader-fullscreen {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 100000;
  position: fixed;
  background-color: rgba(0, 0, 0, 0.4);
  display: flex;
  justify-content: center;
  align-items: center;
  opacity: 99.99999;
  pointer-events: auto;
}

.css-hidden {
  opacity: 0.000001;
  pointer-events: none;
}

.css-loading {
  pointer-events: none;
}

HTML

(的HTML)

<div class="css-loader-fullscreen">
    <div class="css-loader-background">
        <div class="css-loader-animation"></div>
    </div>
</div>

<div id="content">
  <input id="load" type="button" value="load">
  <input id="dummy" type="button" value="dummy">
</div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...