在 AJAX 响应更改 textarea val 时在内容脚本中收听

Listen in Content Script for when AJAX response changes textarea val

我正在为文本编辑器编写 WebExtension。当用户单击按钮时,format 编辑器会触发 ajax 请求,然后 returns 格式化文本。我需要我的插件来监听 textarea.

中的变化

我已经尝试使用 onchangeoninput,但是当收到响应时,这些事件 不会 触发。 ajax 响应使用此函数(不是我自己的)设置 body:

function setBody(text) {
  $(opts.codeEl).val(text); // opts.codeEl is the textarea in question
}

ajax 响应如下所示:

{"Body":"Hello World","Error":""}

是否可以从 WebExtension Content Script 处理此 ajax request/response?以某种方式监听 DOMtextareaval 的变化?我可以监听并拦截响应吗?

ajax 请求在网站的 javascript 代码中发送和接收, 与我正在使用的内容脚本隔离(WebExtension代码)给编辑器。请求是这样的

function fmt() {
  loading();
  var data = {"body": body()};
  if ($(opts.fmtImportEl).is(":checked")) {
    data["imports"] = "true";
  }
  $.ajax("/fmt", {
    data: data,
    type: "POST",
    dataType: "json",
    success: function(data) {
      if (data.Error) {
        setError(data.Error);
      } else {
        setBody(data.Body);
        setError("");
      }
    }
  });
}

编辑

正在注入 ajaxComplete 处理程序:

  $(document).ajaxComplete(function(event, jqxhr, options) {
    if(options.url === "/fmt") {
      console.log("fmtted");
      $('#code').change();
    }
  });

进入目标站点 header 将在收到 ajax 响应时调用。但是,当尝试使用注入脚本修改 DOM 时(例如,出于安全原因调用 change()onchange(),它会引发 Error: Permission denied to access property "apply" 错误。

jQuery .val(value) 会调度 change 事件。调用 .change().trigger("change").

如果您不知道何时调用 setBody,您可以在最后一个 $.ajax() 调用完成时使用 .ajaxStop()$(opts.codeEl) 上调用 .change()

$(function() {

  let opts = {
    codeEl: document.querySelector("textarea")
  }

  $(opts.codeEl).on("change", function(event) {
    console.log("changed")
  });

  function setBody(text) {
    $(opts.codeEl).val(text)
  }

  let url = URL.createObjectURL(
    new Blob([
      JSON.stringify({
        "Body": "Hello World",
        "Error": ""
      })
    ], {
      type: "application/json"
    })
  );

  $.get(url)
  .then(function(data) {
    URL.revokeObjectURL(url);
    setBody(JSON.stringify(data))
  });
  
  $(document).ajaxComplete(function(event, jqxhr, options) {
    if (options.url === url) {
      console.log("ajaxStop");
      $(opts.codeEl).change(); // trigger `change` event
    }
    
  });

})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<textarea></textarea>