6

我正在使用带有 jquery 的 jsdom,它工作得很好。然而,我试图将我的代码模块化一点,所以我不会重复自己,所以我用一些 jsdom 代码制作了一个基本函数,它接受一些 html (DOM),用 jquery 调整它,然后把它吐出来. 但是,我无法返回结果并因此将其分配给调用 var。我可能不会在正确的地方返回,但如果是这样,我只是没有看到明显的情况。可以使用一点帮助。

这是代码:

function tweakIt(html_in){
  var jsdom = require('jsdom');
  jsdom.env({
    html: html_in,
    scripts: [
      '../public/javascripts/jquery-1.7.1.min.js',
    ],
    done: function(errors, window) {
      var $ = window.$;
      // do some jquery magic and manipulate the dom
      $('body').append('<div>foo</div>');

      console.log('Freshly Manipulated HTML: '+ $('body').html()); // it logs perfectly
      return $('body').html(); // this isn't returned to where I called tweakIt() from, why not?
    }
  });
}

var oldhtml = '<html><body><div>some text</div></body></html>';
var newhtml = tweakIt(oldhtml); // never gets set because nothing gets returned, why?

编辑:

这确实是一个异步问题,所以这里应该如何使用回调而不是返回来完成:

function tweakIt(html_in, callback){
  var jsdom = require('jsdom');
  jsdom.env({
    html: html_in,
    scripts: [
      '../public/javascripts/jquery-1.7.1.min.js',
    ],
    done: function(errors, window) {
      var $ = window.$;
      // do some jquery magic and manipulate the dom
      $('body').append('<div>foo</div>');

      console.log('Freshly Manipulated HTML: '+ $('body').html()); // it logs perfectly
      callback($('body').html()); // instead of a return, pass the results to the callback
    }
  });
}

var oldhtml = '<html><body><div>some text</div></body></html>';
var newhtml = tweakIt(oldhtml, function(newstuff){
  console.log(newstuff); // woohoo! it works!
});
4

2 回答 2

5

我认为您不能使用返回值来执行此操作,因为 done: 是一个异步函数。尝试向您的tweakIt 添加回调并通过将其作为参数发送来获取新的html,例如

tweakIt(oldHtml, function(newHtml) {/*use the result here*/})

于 2012-02-23T18:59:58.380 回答
2

新版本的 JSDOM API 不再包含“完成”回调选项。

所以我写了一个“穷人的回调”来访问一个DOM变量,只有在它被设置之后。

function getSomeDOMVar(callback) {

    const jsdom = require("jsdom");
    const { JSDOM } = jsdom;

    const dom = new JSDOM(`
    <!DOCTYPE html>
    <html>
        <body>
            <script>
                var result; // globally scoped, undefined var, accessible in the node scope as dom.window.result

                function doSomething() {
                    // your code goes here
                }

                // then assign the data you want back to your the globally scoped var
                result = doSomething();

            </script>
        </body>
    </html>
    `, {
        runScripts: "dangerously",
        resources: "usable"
    });

    // poor man's callback
    function waitForVar() {
        if (typeof dom.window.result !== 'undefined') {
           cb(dom.window.result);
        }
    }
    setTimeout(waitForVar, 1000);
}

getSomeDOMVar(function(result) {
    console.log(result)
});

于 2017-08-04T17:23:04.207 回答