-1

I have a Chrome extension that essentially removes a button and adds 2 other HTML elements in a 3rd party web page. It does this by observing what the URL is on the current tab and if it matches the regex, it will proceed and perform the HTML injection. However, even with a fairly high-end laptop, I see a small amount of latency. The button where I set the CSS to display:none is appearing for a fraction of a second before it is removed and replaced by my 2 HTML elements.

Is it possible to remove this latency so that the user cannot see the original button display during that fraction of a second before the js script within my Chrome extension removes it? So far I made sure the js file responsible for setting the button's property to none has this code in its first 5 lines. Is there anything in the Chrome API that will allow me to remove that button before it loads the page?

My code.js

var tabURL = window.location.href;
var origBtn = document.getElementsByClassName("Btn Btn-short Btn-primary Mend-med")[0];

if(origBtn != null) origBtn.style.display = "none";

var canProceed = correctURL(); //external method check if it matches url regex
if(canProceed == true){
    var rowElm = document.getElementsByClassName("Grid-table W-100 Fz-xs Py-lg")[0];
    var div = document.createElement('div');

    div.innerHTML = "<div class='extelms'>\
        <div class='selectContainer'>\
            <select required class='form-control' name='dayselect' id='days'>\
                <option value='1'>1 Day</option>\
                <option value='2'>2 Days</option>\
                <option value='3'>3 Days</option>\
                <option value='4'>4 Days</option>\
                <option value='5'>5 Days</option>\
                <option value='6'>6 Days</option>\
                <option value='7'>7 Days</option>\
            </select>\
            <button id='submit'>Submit</button>\
        </div>\
    </div>\
    </div>";
    document.getElementsByClassName("Grid-u Px-med Fz-sm Va-mid")[0].appendChild(div);
    document.getElementsByClassName("Grid-u Px-med Fz-sm Va-mid")[0].style.display = '-webkit-inline-box';
}

And my manifest.json

  "content_scripts": [
    {
      "matches": ["https://basketball.fantasysports.yahoo.com/nba/*"],
      "css": ["fantasy.css"],
      "js": ["js/fantasy.js"],
      "run_at": "document_end"
    }
  ]

Assuming that the replacing of HTML elements doesn't occur because the web site's elements haven't been loaded yet when I'm trying to search for the element that I'm trying to delete from the web page.

btramisetty
  • 119
  • 1
  • 9
  • 1
    You could always improve the perceived performance by hiding the body by default and displaying it as soon as the code has been injected. – roberrrt-s Dec 29 '16 at 09:39
  • I tried your method by hiding the body (`display:none`) when the URL is the targetted one (because it shouldn't do this for the irrelevant websites) and injecting and unhiding (ie `display:initial`) – btramisetty Dec 29 '16 at 10:00
  • And does it fit your need? Assuming no, since you'll still have a flashy website, but perhaps if you fire it in the onbeforeload event. – roberrrt-s Dec 29 '16 at 10:00
  • 2
    Have a look at [Chrome extension: Inject JS before page load](http://stackoverflow.com/questions/19191679/chrome-extension-inject-js-before-page-load) – Gabriele Petrioli Dec 29 '16 at 10:38
  • 2
    your delay is unrelated to display:none speed per-se. look instead at the 3 different script injection modes and how you detect the url change. both have delays. – Zig Mandel Dec 29 '16 at 11:27
  • 1
    Inject at document_start and use MutationObserver if you want to eliminate the delay. – wOxxOm Dec 29 '16 at 12:25
  • Please [edit] the question to be on-topic: include a **complete** [mcve] that *duplicates the problem*. Including a *manifest.json*, some of the background/content/popup scripts/HTML. Questions seeking debugging help ("**why isn't this code working?**") must include: ►the desired behavior, ►a specific problem or error *and* ►the shortest code necessary to reproduce it **in the question itself**. Questions without a clear problem statement are not useful to other readers. See: "**How to create a [mcve]**", [What topics can I ask about here?](http://stackoverflow.com/help/on-topic), and [ask]. – Makyen Dec 29 '16 at 20:37
  • When I use Chrome API for content scripts and have `run_at: document_start`, it doesn't perform the whole removing original button and adding new elements. – btramisetty Dec 30 '16 at 02:15
  • @btramisetty, at document-start there is no page contents yet, please read the documentation. That's why you need a MutationObserver as suggested. – wOxxOm Dec 30 '16 at 14:59

1 Answers1

0

One way to make sure the button never appears would be to include
.Btn.Btn-short.Btn-primary.Mend-med{display:none;}
in fantasy.css (with possibly an even more explicit selector). Content script style sheets are able to affect the original DOM (despite the manifest key name content_scripts). You’ll still need to wait for the DOM to complete it’s loading before you’re able to add buttons to the DOM; there’s not really a way around that.

Teepeemm
  • 4,331
  • 5
  • 35
  • 58
  • This was an excellent solution. Now the original button never appears, but there is still a slight delay for the injected elements to appear, which is better than what I initially had. – btramisetty Dec 30 '16 at 09:50
  • Using MutationObserver and document-start you can add buttons or modify the page seamlessly without any perceivable delay like it was served that way. – wOxxOm Dec 30 '16 at 15:01