javascript - 使用 Jquery 的 .each() 函数使网页在移动设备上滞后

标签 javascript jquery html

当我点击 spandiv 元素时,会播放音频。该函数还包含 .each() 以防止音频相互重叠,即当用户点击一个单词时播放音频,当用户点击另一个单词时播放当前音频停止播放并播放新音频。

问题是,我的一些页面上有超过一千个 spandiv 元素,虽然网页在计算机上运行良好,但在移动设备上却非常滞后/更小的设备。

网页在计算机上加载最多需要 2 秒,但在移动/小型设备上需要 15-20 秒。我已经发现罪魁祸首是这个 .each() 函数,因为我猜它在加载时循环遍历页面上的 1000 多个元素,而移动设备无法承受此负载。

我正在寻找解决此问题的方法,因为如果我删除 .each() 函数,页面会在移动设备上快速加载,但随后会出现音频重叠问题。任何帮助,将不胜感激。

<span data-audio-url="hello.mp3">Hello</span>
<span data-audio-url="hello.mp3">Hello</span>
<span data-audio-url="hello.mp3">Hello</span>    
<div data-audio-url="hello.mp3">Hello</div>
$("span, div").each(function(event) { 
  $(this).data('audio-object', new Audio()); 
}).on('click', function (event, e) {
  var e = event || window.event;
  e.cancelBubble = true;

  if (e.stopPropagation) 
    e.stopPropagation();

  var audio_url = $(this).attr('data-audio-url');

  $("span, div").each(function() {
    var audio = $(this).data('audio-object');
    if (audio.src) {
      audio.pause();
      audio.currentTime = 0;
    }    
  });

  var clickedAudio = $(this).data('audio-object');
  if (!clickedAudio.src) { 
    clickedAudio.src = audio_url; 
  }    
  clickedAudio.play();
});

最佳答案

问题是因为您首先不必要地遍历每个选定的元素,然后将 audio 元素添加到该元素的 jQuery 的 data 缓存中。然后在点击处理程序本身中,您再次循环遍历所有元素并在其 data 中暂停 audio 元素。这两个循环在性能方面非常昂贵。

为了简化这一点,只需在页面加载时在 DOM 中使用单个 audio 元素,并在单击相关元素时更改其 src 。使用此方法,您不需要任何一个循环。

正如@LieRyan 在评论中所建议的那样,您可以通过在所有 spandiv 元素。试试这个:

var audio = $('#player')[0];

$('#container').on('click', 'span, div', function(e) {
  e.stopPropagation();
  var audio_url = $(this).data('audio-url');
  audio.src = audio_url;
  audio.play();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="container">
  <span data-audio-url="http://media.w3.org/2010/07/bunny/04-Death_Becomes_Fur.oga">Hello</span>
  <span data-audio-url="http://media.w3.org/2010/05/sound/sound_90.mp3">Hello</span>
  <div data-audio-url="http://media.w3.org/2010/11/rrs006.oga">Hello</div>
</div>

<audio id="player"></audio>

请注意,此处不需要 preventDefault(),因为 spandiv 元素没有要阻止的默认点击行为。

另请注意,使用数千个元素列出样本听起来有点过分了。我强烈建议您实现分页、搜索和/或过滤,让您的用户更容易导航。

关于javascript - 使用 Jquery 的 .each() 函数使网页在移动设备上滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56596850/

相关文章:

javascript - 带时间戳的 Firestore 查询

javascript - 选择文件时更新图像

javascript - 取消服务器已收到的 AJAX 调用

jquery - 如何清除Drupal.settings?

javascript - 根据另一个值向文本框添加值

javascript - 当 rangeSelector 隐藏时 Highcharts 库存控制范围

javascript - javascript中符号传播右移和零填充右移之间的区别?

javascript - 页面加载后div消失

html - Bootstrap 布局 : Default Grid System VS Fluid Grid System

javascript - isset/空 php session (if else 语句)给出 undefined index