【问题标题】:Listen in Content Script for when AJAX response changes textarea val在内容脚本中侦听 AJAX 响应何时更改 textarea val
【发布时间】:2017-01-05 16:02:52
【问题描述】:

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

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

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

ajax 响应如下所示:

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

是否可以处理来自 WebExtension 内容脚本 的 ajax 请求/响应?以某种方式监听 DOMtextareaval 的变化?我可以收听并拦截响应吗?

在网站的 javascript 代码中发送和接收 ajax 请求,与我正在为编辑器使用的内容脚本(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();
    }
  });

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

【问题讨论】:

  • 您是否要检查服务器对$.ajax() 呼叫或change 事件textarea 的响应?
  • 1.这个文本编辑器是否提供自己的 js API 和事件订阅? 2.您可能必须使用DOM-injected scriptspoof val method
  • @guest271314 检查change 事件
  • @wOxxOm 是的......我想。我现在要研究这些链接
  • @guest271314 总的来说,我对 javascript 有很多不确定,但是编辑 textarea 并不会改变 DOM AFAIK,所以 MutationObservers 不会注册任何东西

标签: javascript ajax google-chrome-extension content-script firefox-addon-webextensions


【解决方案1】:

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>

【讨论】:

  • @guest271314 所以ajaxComplete 会在ajax 请求通过时触发?即使ajax请求是用外代码发送和接收的?
  • @Nevermore “外码”是什么意思?您能否在问题中包含所有相关的javascript
  • @Nevermore,是的,它会一直执行,但您可以简单地将旧的 textarea 值与当前值进行比较。此外,您必须在 DOM-injected script 中挂钩 ajaxComplete。
  • @guest271314 所以我已经更新了我的问题,以指定 ajax 调用是在我的内容脚本的一个独立脚本中发生的——我认为 wOxxOm 有点意思,但我需要先了解代码在我真正理解“挂钩”ajaxComplete 函数意味着什么之前,你就提出来了……基本上,我需要将你上面写的那个监听器注入到孤立的脚本中?
  • 如果您可以控制html document,您可以在document 处注入Answer 的.ajaxComplete() 部分。或者,只需将.change() 链接到.val()。您也可以尝试使用扩展程序中的chrome.webRequestWebRequest API
猜你喜欢
  • 2011-07-06
  • 2020-01-24
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 2017-12-29
  • 2016-11-22
  • 1970-01-01
  • 2017-04-07
相关资源
最近更新 更多