【问题标题】:javascript not working on ajax loaded content; not using jqueryjavascript 不适用于 ajax 加载的内容;不使用jquery
【发布时间】:2018-04-08 02:58:36
【问题描述】:

我正在使用 ajax 将“mysite/math/”中的所有内容加载到 math.php 中。在 math.php 中,我想使用 katex 渲染加载的数学内容。

https://github.com/Khan/KaTeX

在 math.php 中,我从上面链接中的 cdn 加载库 katex。

math.php 的 html:

<body>
  <div id='main'>
</body>

在 math.php 的脚本标签中,我有一些 php 可以从 'mysite/math/' 获取 url 列表

echo "var x = [];";
$dir = "./math/";
$a = scandir($dir);
foreach ($a as $x) {
if ($x === '.' or $x === '..') continue;
  echo "x.push('mysite/math/" . $x . "');";
}

所以这给了我一个数组 x,其中包含我想将其内容加载到我的网页中的每个文件的位置。

现在,在 javascript 中,我对数组 x 中的 url 进行多次 AJAX 调用:

// defining the ajaxing function
function myfunction(url, someFunction) {
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function () {
    if (this.readyState === 4 && this.status === 200) {
      someFunction(this, url);
    }
  };
  xhr.open('GET', url, true);
  xhr.send(null);
}

// defining the callback function
function callbackfunction(xhr, url) {
  var name = url;
  var div = document.createElement('div');
  div.innerHTML = xhr.responseText;
  div.className += name;
  document.getElementById('main').appendChild(div);
}

// here, I'm actually executing the ajax calls
for (var i = 0; i < x.length; i++) {
  myfunction(x[i] + '?w=' + Math.random(), callbackfunction);
}

到目前为止,所有这些都运行良好。

问题:

在 'mysite/math/' 中的每个 html 文件中,都有带有 class='math' 的 span 标签,其中包含我要呈现的数学内容。所以在 math.php 中,我看到了我所有的内容,我看到了我的 span 标签,class='math';他们都在那里。

在 math.php 内部还有以下使用 katex 函数 katex.render() 的 javascript

var math = document.getElementsByClassName('math');
for (var i = 0; i < math.length; i++) {
  katex.render(math[i].innerHTML, math[i]);
}

如果内容不是使用 ajax 加载的,我使用 katex 的方式可以正常工作。

注意: 我已经多次看到这个问题,但答案总是使用 jquery。我想要一个 javascript 的解决方案。

【问题讨论】:

    标签: javascript ajax


    【解决方案1】:

    问题很可能是当浏览器调用katex.render 时,您的AJAX 提供的内容还没有出现在页面上。

    由于您要进行多次调用以加载内容,因此您需要等到所有调用都返回后才能调用katex.render。我可以想到几种使用 vanilla JavaScript 的方法:

    1. 创建一个事件处理程序来侦听每个要完成的调用。当它们都完成后(也许跟踪变量中完成的调用次数)调用katex.render。
    2. 将每个 AJAX 调用包装在一个 Promise 中,将它们全部推送到一个数组中,然后在该数组上调用 Promise.all。在Promise.all().then() 中,调用katex.render。

    【讨论】:

    • 我想到了您列出的第一个选项:创建事件处理程序。我只是想起来有点麻烦。你有什么建议吗?至于第二个,我不知道什么是承诺,所以我可能会去了解它。
    • 就我个人而言,我倾向于 (2)-- 承诺。如果您正在编写 JavaScript,了解一般情况是一件非常有用的事情。下面是关于如何将原生 XHR 调用转换为 Promise 的一个很好的解释:stackoverflow.com/questions/30008114/…
    • 这里是 MDN 对 Promise.all() 的解释:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    • 我的 js 技能还需要很多工作,所以我会继续研究 Promise 对象。但是,我确实认为我已经找到了一种方法来获得我想要的结果。我不确定这是否是一种优雅的方式,但我现在将 katex.render 应用于每个 div 的子项,因为将 div 添加到页面似乎有效。
    【解决方案2】:

    这个解决方案不是那么复杂,但我认为它可以完成工作。

    我通过添加一行 applyKatex(div) 更改了我的回调函数

    // defining the callback function
    function callbackfunction(xhr, url) {
      var name = url;
      var div = document.createElement('div');
      div.innerHTML = xhr.responseText;
      div.className += name;
      document.getElementById('main').appendChild(div);
      applyKatex(div); //  <---this is what i added
    }
    

    我创建了一个函数 applyKatex(),它接受一个 html 元素并将函数 katex.render() 应用于每个类名为“math”的子元素

    当每个新的 div 添加到页面时,katex.render() 将被应用到它

    function applyKatex(element) {
      var math = element.getElementsByClassName('math');
      for (var i = 0; i < math.length; i++) {
        katex.render(math[i].innerHTML, math[i]);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-28
      相关资源
      最近更新 更多