Plugin for Chrome that executes code based on ajax requests

Allow me to provide a brief overview of the issue I am experiencing.

Currently, I have an extension that successfully wraps phone numbers in a specific tag. However, the problem arises when content is dynamically loaded through JavaScript based on user actions or AJAX requests.

For instance, if I click on a Hotmail email and open it, the script functions only after refreshing the page to trigger my contentscript.

I considered requiring users to click the extension icon to work around this, but that deviates from the intended functionality.

If there is a way in Chrome to monitor AJAX requests (as indicated by http://code.google.com/chrome/extensions/webRequest.html), then that is what I aim to achieve. However, implementation is unclear. Should I treat it as a listener?

Although I found an alternative method based on DOM changes, it significantly slowed down loading times due to the complexity of the DOM. Listening for AJAX requests and re-running my code upon completion appears to be the ideal approach.

Any assistance or guidance in the right direction would be greatly appreciated =)

Please excuse any potential ignorance in my question, as I have diligently searched Google and forums for answers with no success. My limited experience of two weeks working with JavaScript has presented a steep learning curve.

Answer №1

When you mention...

I discovered an alternative method to tackle this issue by monitoring DOM changes, but it significantly slowed down the loading time due to the complexity of the DOM structure. I realized that listening for AJAX requests and re-running my code upon their completion would be a more efficient approach.

...were you utilizing Mutation Events or Mutation Observers? I recall that Observers were designed to address such issues. Personally, I hadn't worked with Observers before and opted for Mutation Summary. It seemed capable of achieving the desired outcome, although it only began observing once the document was ready/idle (uncertain which). You might consider scanning on document ready and then triggering the observer.
Below is an outline of how my test code appeared (in a content script)...

handleChanges = function(summaries) {
    // Additional elements may need to be ignored
    var ignore = {
        SCRIPT: true,
        NOSCRIPT: true, 
        CDATA: true,
        '#comment': true
    }
    summaries.forEach(function(summary) {
        summary.added.forEach(function(node) {
            if (!ignore[node.nodeName] || (node.parentNode && !ignore[node.parentNode.nodeName]) && node.nodeValue.trim()) {
                node.nodeValue='PAEz woz ere - '+node.nodeValue;
            }
        })
    })

}

var observer = new MutationSummary({
    callback: handleChanges,
    // mandatory
    rootNode: document,
    // optional, defaults to window.document
    observeOwnChanges: false,
    // optional, defaults to false
    queries: [{
        characterData: true
    }]
});

An additional approach to detecting a XMLHttpRequest involves intercepting it, where the process can be as follows (in a content script at document start).....

function injectScript(source) {

    var elem = document.createElement("script"); //Create a new script element
    elem.type = "text/javascript"; //It's javascript
    elem.innerHTML = source; //Assign the source
    document.documentElement.appendChild(elem); //Inject it into the DOM
}

injectScript("("+(function() {

    function bindResponse(request, response) {
        request.__defineGetter__("responseText", function() {
            console.warn('Something attempted to retrieve the responseText');
            console.debug(response);
            return response;
        })
    }

    function processResponse(request, caller, method, path) {
        bindResponse(request, request.responseText);
    }

    var proxied = window.XMLHttpRequest.prototype.open;
    window.XMLHttpRequest.prototype.open = function(method, path, async) {
            var caller = arguments.callee.caller;
            this.addEventListener('readystatechange', function() {
                if (this.readyState === 4)
                    processResponse(this, caller, method, path);
            }, true);
        return proxied.apply(this, [].slice.call(arguments));
    };
}).toString()+")()");

...learned from the incredibly useful Supper Happy Fun Blog.
However, as you are likely aware, this might not suffice for websites driven by AJAX. It usually necessitates crafting something tailored for the site, or perhaps the Mutation Observer could meet your requirements.

Answer №2

This response has been updated to utilize the MutationObserver method instead of MutationSummary, which is no longer functioning:

var observer = new MutationObserver(function(mutationsList) {
  console.log(`Something has changed`);
});

observer.observe(document.querySelector('.whatever'), {
  attributes: true,
  characterData: true,
  childList: true,
  subtree: true
});
  • Be sure to adjust the selector .whatever to match the class/id you are monitoring.
  • Specify either true/false for the subtree option depending on whether you want to track changes in children elements or not.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

retrieve all entries from a paginated grid

Currently, I am utilizing the datatable feature in bootstrap4 with a table that has pagination set to display 10 items per page. I have implemented a function to retrieve values from the table, however I am facing an issue where I am only able to retriev ...

Using javascript to store HTML tags in a variable

Hey there, I have a quick question. Can someone help me figure out why this code isn't working? let plus = "+" + '<h1>'+"This is a heading"+'</h1>'; When I run the code, the output I get is: +<h1 ...

Is it possible to dynamically assign trigger and target divs to bPopup?

On our ColdFusion page, we have a dynamic list of paired divs created using a loop over a query. For example, each pair consists of internshipHandleX and internshipHiddenX: <div id="internshipHidden#internship.currentrow#" class="hidden pop-up"> We ...

Troubleshooting not locating view files in ExpressJS and implementing client-side JavaScript and CSS deployment in ExpressJS

My JavaScript file is located in the same directory as my HTML file, and I am trying to render it. I'm unsure of what I may be missing. How difficult could it possibly be? var express = require('express'); var app = express(); app.engine( ...

I am having trouble with setInterval not functioning as expected. I am trying to make a function repeat every 500ms using setInterval, but it seems to be ineffective

var direction; function movement(){ switch(direction){ case 1: positionX = positionX + 10; break; case 2: positionX = positionX - 10; break; case 3: positionY = positionY - 10; bre ...

In Vue, the CropperJs image initially appears small, but it returns to its original size after editing

I encountered a peculiar issue while working on a website for image cropping using Vue.js and CropperJs. On the homepage, users can select an image to crop and proceed to the next page where a component named ImageCropper.vue is displayed. Strangely, the c ...

Can we re-trigger the document.ready() jQuery function for injected HTML through AJAX?

Presenting my scenario: <html> <body> <head> ... <script> $(function(){ $('.do-tip').qtip({ content: 'This is a tip of active ho ...

Ways to distinguish between two div elements that have scroll bars and those that do not

I created a div with CSS styling. .comment-list { margin: 20px 0; max-height: 100px; min-height: 100px; overflow-y: scroll; width: 100%; background-color:#000; } Here is the HTML code for the div: <div class="comment-list"> </div> When the ...

AngularJS, the element being referenced by the directive is empty

Currently, I am in the process of transferring a jQuery plugin to AngularJS simply for the enjoyment of it. Previously, when working with jQuery, my focus was on manipulating the DOM using jQuery functions within the plugin loading function. Now that I am ...

Utilizing jQuery to invoke a function at the conclusion of another function's execution

Can someone explain how jQuery can achieve the following? $('.test').css().otherThing...... etc I'm attempting to accomplish this with prototype: var myPrototype = function () {}; myPrototype.prototype.console1 = function() { console.lo ...

Is it possible to prevent the late method from running during the execution of Promise.race()?

The following code snippet serves as a simple example. function pause(duration) { return new Promise(function (resolve) { setTimeout(resolve, duration); }).then((e) => { console.log(`Pause for ${duration}ms.`); return dur ...

Trigger ajax request upon app closure

During my work on Cordova with jQuery Mobile, I encountered a requirement where the app needed to send an ajax request to a server when the user either pauses or closes the application. To achieve this, I included the following code: document.addEventList ...

Troubleshooting: jQuery AJAX .done() function failing to execute

Currently, I have a piece of code that is being utilized to dynamically load HTML into a CodeIgniter view: $.ajax({ type:"POST", url: "Ajax/getHtml", data: { u : conten ...

React Hook Form: Reset function triggers changes across all controllers on the page

I encountered an issue with using the reset function to clear my form. When I invoke the reset function, both of my form selects, which are wrapped by a Controller, get cleared even though I only defined default value for one of them. Is there a way to pr ...

Declare webpage as manager for mailto links

One interesting feature I've observed in various web-based email providers is the ability to add the website as the default mailto links handler in browsers like Firefox and Chrome. This means that when clicking on a mailto: link, it will automaticall ...

Tips for changing the dimensions of the canvas?

I'm struggling to display a photo captured from the webcam. The sizes are not matching up, and I can't pinpoint where the size is defined in the code. https://i.stack.imgur.com/Is921.png The camera view is on the left, while the photo should be ...

JavaScript does not allow for the incrementation of a global variable within a function

Imagine I have some JavaScript and HTML code like this: var x = 1 function increase() { x += 1 console.log(x) } <button onclick="increase()">Click</button> When the button is clicked, x increases to 2 but doesn't go any higher ...

Sending JSON data along with sendFile() in Node.js and Express done right

After setting up a Node.js server with Express and routing, I am faced with the challenge of passing JSON data onto a specific page ("/users/id") while using sendFile(). While I could make an AJAX request on page load to retrieve the data separately, I am ...

Change the default direction of content scrolling in CSS and JavaScript to scroll upwards instead of

I am currently working on a website where the navigation bar spans the entire width and remains fixed in place. Below the navigation bar is a cover image, followed by the main content section. As you scroll down, the navigation bar covers the image from t ...

I am interested in sending an email from a PDF document based on the selected check boxes

I have added a button in a PDF form that says "send an email" and I would like the form to be sent to different email addresses based on which checkboxes were selected previously. For example, there is a question about the "Size of the company" with 2 che ...