Is there a method for removing the Microsoft Translator widget while still keeping the translation feature intact?

I am currently utilizing the Microsoft Translation Widget to automatically translate a webpage without requiring any user interaction.

Unfortunately, I have been facing an issue where I am unable to remove or hide the widget that keeps popping up on the page because the CSS and JS are loaded directly from Microsoft's script within the widget!

If anyone has a solution or workaround for this problem, I would greatly appreciate the help. I have searched extensively but have not been able to find a resolution so far.

Answer №1

Wow, after spending some time experimenting with it, I've finally managed to achieve the desired outcome.

Although it may not look perfect due to some necessary workarounds, it does the job. Feel free to check out the fiddle to see it in action.

Here are the steps I took:

  1. Firstly, I had to override the default behavior of addEventListener:

    var addEvent = EventTarget.prototype.addEventListener;
    var events = [];
    
    EventTarget.prototype.addEventListener = function(type, listener) {
      addEvent.apply(this, [].slice.call(arguments));
      events.push({
        element: this,
        type: type,
        listener: listener
      });
    }
    
  2. Next, I created a helper function called removeEvents. This function removes all event listeners from an element.

    var removeEvents = function(el, type) {
      var elEvents = events.filter(function(ev) {
        return ev.element === el && (type ? ev.type === type : true);
      });
    
      for (var i = 0; i < elEvents.length; i++) {
        el.removeEventListener(elEvents[i].type, elEvents[i].listener);
      }
    }
    
  3. When creating the script tag according to Microsoft's guidelines:

    var s = d.createElement('script');
    s.type = 'text/javascript';
    s.charset = 'UTF-8';
    s.src = ((location && location.href && location.href.indexOf('https') == 0) ? 'https://ssl.microsofttranslator.com' : 'http://www.microsofttranslator.com') + '/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=True&ui=true&settings=Manual&from=';
    var p = d.getElementsByTagName('head')[0] || d.dElement;
    p.insertBefore(s, p.firstChild);
    

    We need to add a load event listener to that script, and the code below explains it thoroughly:

    s.addEventListener('load', function() {
      // When the translation changes, the plugin calls the TranslateArray method
      // So, we store the original method in a variable and then override it
      var translate = Microsoft.Translator.TranslateArray;
    
      Microsoft.Translator.TranslateArray = function() {
        // We call the original method
        translate.apply(this, [].slice.call(arguments));
    
        // Since the translation is not immediately available
        // And we have no control over when it will be ready
        // I created a function to wait for it
        waitForTranslation(function() {
          // Once the translation is available
          // We select all elements with a lang attribute 
          // And remove all their mouseover event listeners
          [].forEach.call(d.querySelectorAll('[lang]'), function(item, i) {
            removeEvents(item, 'mouseover');
          });
        });
      }
    
      // This helper function waits for the translation to be ready
      function waitForTranslation(cb) {
        // Since we can't control the translation callback
        // I checked if the Translating label is visible as a workaround
        // The function keeps running until the label is hidden again
        // Then it calls our callback function
        var visible = d.getElementById('FloaterProgressBar').style.visibility;
        if (visible === 'visible') {
          setTimeout(function() {
            waitForTranslation(cb);
          }, 0);
          return;
        }
        cb();
      }
    });
    

Update 1

Upon re-evaluating your question, it appears you want to hide all widgets entirely.

To do so, you need to insert the following code once the translation is retrieved:

waitForTranslation(function() {
  document.getElementById('MicrosoftTranslatorWidget').style.display = 'none';
  document.getElementById('WidgetLauncher').style.display = 'none';
  document.getElementById('LauncherTranslatePhrase').style.display = 'none';
  document.getElementById('TranslateSpan').style.display = 'none';
  document.getElementById('LauncherLogo').style.display = 'none';
  document.getElementById('WidgetFloaterPanels').style.display = 'none';
  // additional code
});

I've prepared another version of the fiddle for you to demonstrate this new behavior. You can access it here.

Update 2

You can prevent the widget from appearing completely by applying the following CSS code:

#MicrosoftTranslatorWidget, #WidgetLauncher, #LauncherTranslatePhrase, #TranslateSpan, #LauncherLogo, #WidgetFloaterPanels {
    opacity: 0!important;
}

Furthermore, you can also hide the pre-translated text initially by setting the document.body display to none and revealing it only when the page is fully translated:

(function(w, d) {
  document.body.style.display = 'none';
  /* (...) */

  s.addEventListener('load', function() {
    var translate = Microsoft.Translator.TranslateArray;

    Microsoft.Translator.TranslateArray = function() {
      translate.apply(this, [].slice.call(arguments));

      waitForTranslation(function() {
        /* (...) */
        document.body.style.display = 'block';
      });
    }
  });
});

Feel free to check out the final version of the fiddle I've crafted here.

Answer №2

In my case, I found the following solution to be effective: in your < style > section, include this class definition

.StyleRTL { visibility: hidden !important }

If you are using the translation widget like this:

Microsoft.Translator.Widget.Translate('en', lang, null, null, TranslationComplete, null, 3000);

make sure to add the following lines to your callback function (named TranslationComplete in this example):

function TranslationComplete() {
  Microsoft.Translator.Widget.domTranslator.showHighlight = false;
  Microsoft.Translator.Widget.domTranslator.showTooltips = false;
  document.getElementById('WidgetFloaterPanels').style.visibility = 'hidden';
};

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

Click on the checkbox to activate it using JavaScript

I'm trying to use JavaScript to toggle the checkbox status when clicking a button. The first button is supposed to uncheck the box and it's working correctly: function clear() { document.getElementById("check").checked = ""; } However, I al ...

Encountering problems when transforming Next.js server components into client components

I've been working on a blog site using next.js. Initially, I had a home page that was a server component, but I wanted to convert it into a client component to add interactivity like pagination. However, after converting the code to a client componen ...

Struggling to connect CSS and JavaScript files to index.html on Heroku while utilizing Node.js

Trying to set up a Tic Tac Toe game in my app.js file, but encountering some issues with linking files in index.html. app.set('port', (process.env.PORT || 5000)) //serve static files in the public directory app.use(express.static('public& ...

Saving sortable portlet items to a database using JQuery AJAX

I've searched through numerous resources to find a solution to my problem, but none of them have been successful. Here is the code I am working with: http://plnkr.co/edit/pcfz33lzHz4wdehjGEuQ I am trying to utilize AJAX to save the order of two port ...

What is causing the net::ERR_CONNECTION_RESET in Node JS and ExpressJS?

Our application, built on ExpressJS and NodeJS, is hosted on a Linode server and served at port 3000. Although the app has been functioning well for a year, we have recently encountered consistent connection errors. The errors vary, but they are mostly re ...

What is the method to load only specific element contents using .load() rather than the entire web page?

I have a web page that allows users to add, edit, and update different sections. These segments are stored on an external page, and I use the jquery .load() function to achieve this functionality. However, I am facing some concerns regarding this process: ...

Using the v-for directive in Vue.js to loop through an array and display

Looking at the image provided, I am trying to access the content. I attempted to do so using element.comments.content, but it did not seem to work as expected. Here is the snippet of code: <div class="fil-actualites-container"> <div cl ...

Refresh a div with Ajax once all data has been fully loaded

I am currently using an ajax refresh div function that reloads a specific div every 10 seconds. Occasionally, the div loads before receiving data from mysql. Is there a way to modify it so that it waits 2 seconds after reloading the div? <script type ...

The controller is unable to provide the output in JSON format within the AJAX response

My task requires me to continuously call and fetch data from a REST API every second. To achieve this, I am calling the method with a time interval of 1 second as shown below: var myVar = setInterval(function(){ getData1() }, 1000); Below is the JavaScri ...

Load prior state when the value changes with UseState in NextJS

In the development of my e-commerce application, I am currently working on implementing filters based on category and price for the Shop page. To handle this functionality, I have established the initial state as follows: const [filters, setFilters] = useS ...

Adding content to a text field and then moving to the next line

I am looking to add a string to a text area, followed by a new line. After conducting some research, here are the methods I have attempted so far but without success: function appendString(str){ document.getElementById('output').value += st ...

Saving a collection of unique identifiers in Firebase

Struggling to find a solution for organizing Firebase data: Each user has posts with generated IDs, but how do I store these IDs in a user node efficiently? Currently using string concatenation and treating them like a CSV file in my JS app, but that feel ...

Error: Cannot read property 'X' of undefined in JavaScript when using Django framework

Using p5.js, I am creating drawings with data from a JSON provided by my Django backend. The draw function is defined at the base level of my HTML document within the script element: function draw(json) { if (json["leaf_text"]) { stroke(100) el ...

find the middle element in the Vue array

Currently in the process of developing a custom Vue carousel component, I have utilized some code snippets from this resource: link My goal right now is to enhance the slider with additional navigation bullets. However, due to the justify-content:center p ...

The source 'http://localhost:3000' is not authorized to access the Twitter API

I am working on a web application that utilizes the Twitter API REST. On one of my pages, I have a list of Twitter accounts and a button to add a new account. When this button is clicked, it triggers a function in the Angular controller: // Function to ...

Exploring AngularJS and Jasmine: Testing a controller function that interacts with a service via $http

I encountered an issue while testing a controller that relies on a service. The problem arises because the service is currently set to null in order to focus solely on testing the controller. The current test setup is failing due to the BoardService being ...

How can I retrieve an attribute from another model in Ember using the current handlebar in the HTML file?

I'm attempting to achieve the following: {{#if model.user.isAdmin}} <div> My name is {{model.user.name}} </div> {{/if}} within a handlebar that is being used in a controller unrelated to users: <script type="text/x-handlebars" data- ...

Send data through Ajax and Jquery to upload files

For hours on end, I've been grappling with how to use ajax to upload a file and coming up empty. Here's the snippet: HTML: <form action="" method="post" id="uploadForm" enctype="multipart/form-data"> <input type="file" name="image" ...

What causes the `d-none` class to toggle on and off repeatedly when the distance between two div elements is less than 10 during window resizing?

My primary objective is to display or hide the icon based on the width of the right container and the rightButtonGroupWrapper. If the difference between these widths falls below 10, the icons should be shown, otherwise hidden. However, I'm facing an i ...

Obtaining the current value with each keystroke

While working with vue.js, I'm building a table that contains an input field called quantity. However, when I start typing the first word, it shows 'empty' on the console. If I type 3, it displays empty; and if I type 44, it prints 4. I am ...