1

A connected question to this problem with the iframe issue: Copy div from parent website to a textarea in iframe

I'm trying to copy InnerHtml from a div to a TextArea. image I've made two instances of google translator on the same web page, and I'm trying to apply auto-correction of the first instance to the second instance, without changing the first textarea.

I tried different code:

setInterval(function() {
childAnchors1 = document.querySelectorAll("#spelling-correction > a")[0];
$("#source")[1].val(childAnchors1.text());
 }, 100);

setInterval(function copyText() {
    $(".goog-textarea short_text")[1].val($("#spelling-correction > a")[0].innerText());
}
, 100);

setInterval(function copyText() {
    $("#source")[1].val($("#spelling-correction > a")[0].innertext());
}
, 100);

setInterval(function() {
 var finalarea = document.getElementsByClassName("goog-textarea short_text")[1];
var correction = document.querySelectorAll("#spelling-correction > a")[0].innerHTML
  document.getElementsByClassName("goog-textarea short_text")[1].value = correction.innerText;
}, 100);

onclick='document.getElementsByClassName("goog-textarea short_text")[1].innerHTML=document.getElementById("spelling-correction > a")[0].innerHTML;'

But nothing of that seems to work, unfortunately...

I would be very grateful for any help.

I should have mentioned this. I used iframe to create the second instance, so simple solutions don't work... This is the code I used for creating iframe instance:

var makediv = document.createElement("secondinstance");
makediv.innerHTML = '<iframe id="iframenaturalID" width="1500" height="300" src="https://translate.google.com"></iframe>';
makediv.setAttribute("id", "iframeID");
var NewTranslator = document.getElementById("secondinstance");
var getRef = document.getElementById("gt-c");
var parentDiv = getRef.parentNode;
parentDiv.insertBefore(makediv, getRef);

I tried to use this to communicate between the iframe and the parent website:

setInterval(function() {
    var childAnchors1 = window.parent.document.querySelectorAll("#spelling-correction > a");
    var TheiFrameInstance = document.getElementById("iframeID");
    TheiFrameInstance.contentWindow.document.querySelectorAll("#source").value = childAnchors1.textContent;
}, 100);

But it doesn't work...

Ok, I made it work with:

var a = document.createElement('iframe');
a.src = "https://translate.google.com"; 
a.id = "iframenaturalID";
a.width = "1000";
a.height = "500";
document.querySelector('body').appendChild(a)

And

let iframe = document.getElementById("iframenaturalID");
setInterval(function() {
let source = iframe.contentWindow.document.getElementById("source");
let destination = window.parent.document.querySelector("#spelling-correction > a");


source.value = destination.textContent;
     }, 100);

Now it does what I tried to do, however I still get mistake message: Uncaught TypeError: Cannot set property 'value' of null at eval, which points at this line: source.value = destination.textContent;. It's not a big problem though, but still it's strange that it returns this mistake...

Ok, I was able to solve it by adding setTimeout.

teg_brightly
  • 468
  • 6
  • 20

2 Answers2

4

Since a textarea is a form element, neither .innerText or .innerHTML will work. You need to extract its content with the value property (or .val() with JQuery).

And FYI:

  • It's innerText, not .innertext.
  • .innerText is a property, not a function, so you don't use () after it.
  • It's .innerHTML, not .innerHtml.
  • innerHTML is used when there is HTML in the string that should be parsed as HTML and .textContent is used for strings that should not be parsed as HTML. Usually, you don't map the contents of one to the other.
  • document.querySelectorAll() scans the entire DOM to find all matching nodes. If you know you only have one matching node or you only want the first matching node, that's a waste of resources. Instead, use .querySelector(), which stops searching after the first match is found. Since you are using JQuery, you should be consistent in its use. There's no need for .querySelector() or .querySelectorAll() with JQuery, just use JQuery selector syntax.

Here's an example that shows both the vanilla JavaScript and JQuery approaches using the HTML types that you show in your question with the same id values and nesting structure that you show. You can see that I'm using different selectors to correctly locate the input/output elements.

// Standare DOM queries to get standard DOM objects
let source = document.getElementById("source");
let destination = document.querySelector("#spelling-correction > a");

// JQuery syntax to get JQuery objects:
let jSource = $("#source");
let jDestination = $("#spelling-correction > a");

// Vanilla JavaScript way to set up the event handler and do the work
source.addEventListener("keyup", function(){
  destination.textContent = source.value;  
});

// JQuery way to set up the event handler and do the work
jSource.on("keyup", function(){
  jDestination.text(jSource.val());   
});
textarea, div {
  border:3px solid grey;
  width:500px;
  height:75px;
  font-size:1.5em;
  font-family:Arial, Helvetica, sans-serif;
}

.destination { pointer-events:none; background:#e0e0e0; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Type in the first textarea</p>
<textarea id="source"></textarea>
<div id="spelling-correction">
  Did you mean: <a href="#"></a>
</div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • Thank you, now I figured out how to do this with two elements. However, this doesn't work when I have to communicate information between the first website and the embedded iframe instance of the same website. I will have to research how to do that. – teg_brightly Oct 06 '18 at 00:30
  • Thank you, I made it work with the Vanilla Javascript code. Now it does what I want. It gives me error messages though (in the line `source.value = destination.textContent;`, I wrote about this in the updated answer). Maybe there is some way to get rid of those errors; though they are not very important. Thank you! – teg_brightly Oct 06 '18 at 22:07
1

The problem in all the codes you've tried is how to get the text correctly.

Starting with your First example it should be using innerText instead of text() since it's a jquery object and you're returning a DOM object not a jQuery object:

setInterval(function() {
    childAnchors1 = document.querySelectorAll("#spelling-correction > a")[0];
    $("#source")[1].val(childAnchors1.innerText);
}, 100);

In your Second example and Third one, you need to remove the parentheses from the innerText like:

setInterval(function copyText() {
    $(".goog-textarea short_text")[1].val($("#spelling-correction > a")[0].innerText);
}, 100);

I suggest the use of pure js and textContent attribute like:

setInterval(function() {
    var childAnchors1 = document.querySelectorAll("#spelling-correction > a")[0];
    document.querySelectorAll("#source")[1].value = childAnchors1.textContent;
}, 100);

enter image description here

NOTE: I should point that your HTML code in invalid since you're using duplicate identifier when the id attribute should be unique in the same document.

Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
  • I Hope this is what you're looking for @Ernest – Zakaria Acharki Oct 05 '18 at 16:44
  • Yes, the HTML code is invalid, because I'm using two instances of google translate on the same web page. Unfortunately it seems that selecting by anything with [0] or [1] doesn't work. Either one only selects the first element on the page, or just both. – teg_brightly Oct 05 '18 at 16:49
  • I've tried the code in my answer and it works just fine – Zakaria Acharki Oct 05 '18 at 17:08
  • Maybe the problem is that I use an extension to bypass X-Frame headers. Because when I tried to create the second instance of google translate, it was written that it was denied. How did you create the second instance of google translate? – teg_brightly Oct 05 '18 at 17:16
  • Did the second instance also translate the words? – teg_brightly Oct 05 '18 at 19:20
  • No @Ernest it doesn't – Zakaria Acharki Oct 05 '18 at 19:30
  • Yes, thank you, the code works if I create a second instance in the inspector. But if the second instance is an embedded iframe, then it doesn't work... I will have to research how to communicate information between two instances of the same website. – teg_brightly Oct 06 '18 at 00:27