How do I read elements from any website using vanilla JavaScript? - javascript

I've been trying to write some JavaScript for a Chrome extension that can read elements by class name from a website which I don't own. For example, if I inspect this website there is a body tag with class="x" in it, this sometimes updates to class="y". All I need to do is be able to read this value.
So far I have tried using:
var x = document.getElementsByClassName("x");
if (x.length > 0) window.alert("Alert");
This works when I have this in script tags beneath my own HTML. However I have no idea how to do this for an external website. Ideally I use a solution using vanilla JS but please also let me know if I will have to use libraries to do this.

You need to use "content scripts" to run your code in a context of web page.
Take a look at Google's doc here - https://developer.chrome.com/extensions/content_scripts
Also you mentioned about possibility of changes, if you need to watch if object changes, you can use Mutation Observer API.
Take a look at Mozilla's doc here - https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

Related

How can I edit html inside an iframe using javascript

I am working on automating a process within my business, part of which is sending an email through SalesForce. We don't have access to the SF API and the email has to be sent through salesforce in order to keep the communication searchable for the coworkers.
I need to use a template which can be selected in SalesForce, however this function does not work in IE (which our RPA solution uses) so I need to build this email from scratch.
I see two options for this:
Use the HTML to recreate the format with the right variables. This entails inserting/injecting/manipulating HTML.
Copy the format into memory/the clipboard, edit it programatically and paste it into the SF interface
This question will be about option 1. I will post an additional question with regards to the second option separately and edit this question to include that link. EDIT: Here is the link to the other question!
Now on to the question:
We use the Blue Prism RPA software suite. It has a possibility to insert javascript fragments into a website and subsequently invoke them. I was hoping that I could create a javascript fragment that recreates the template, insert it and then invoke it. I have been working on this for the past week and have hardly gotten any further.
I now am able to add basic text into the required field, but have found that to be able to use the template structure I need to use a different, HTML based, field. This field I find lives inside an iframe.
I have had zero experience with javascript prior to this week (luckily it seems similar to c# in which I do have experience) and now this iframe has me stumped. Apparently when you use Selenium or similar you can switch the driver to the new iframe but I don't have that option, it needs to be done through surface automation. Within javascript as well as the console I can not get it to target the separate document within the iframe. Apparently the iframe contents are not incorporated in that way in the bigger webpage.
So my question is this: How can I "switch focus" to the iframe using javascript? How can I then edit the iframe contents through javascript? Any help, tips etc. would be highly appreciated!
If you go to developer tools in the browser (F12 or right-click inspect) you can use the inpsect tool to get the path you are looking for. an iframe is just another window inside the window and once you have the 'base path' you can then extend further into the window from the iframe base path.
You can access frames one of two ways I know of;
document.getElementById('the frame you are looking for goes here').contentWindow.targetFunction();
and/or
window.frames[0].otherfunctions
where 0 is the Nth order of frame on the window in case there are others.
once you find that path you can interact with sub-elements on that iframe by getting the path to it from within the iframe.
some things to watch out for. frames not loading yet so make sure the frame you want is loaded and no other frame is moving it around the screen at run time. Also make sure the child frame is in the same domain, I think calling javascript has issues when going cross-domain i.e. it doesn't work (stand to be corrected there though maybe it depends on group settings)
Supply some code or the layout of the page and could give you a code example but top of my head the format will look like this
var doc = window.frames[0]
var thing = getElementById(doc.getElementByPath('maybePath')
'perform some set operations like set innerhtml to thing you desire

How to make my autocomplete chrome extension work?

I have created a code that gives me different standard answers i always use when i'm working. The code is simple but it will make me more efficient ...if is doable. The standard phrases have tag names and if i open the browser i'll get an "userBox", if i type in "moving" i'll get the phrase for that tag name. I've created a chrome extension that "matches": [""] but i want the tag names to be triggered and to give me the corresponding phrase automatically when i write an email. I have no experience with chrome extensions and i'm a beginner in js and html, is this doable for a beginner and if so i would really appreciate some help.
I am currently working on a similar project, the first task for you would be to get the contentEditable divs and textarea using querySelector, the divs and textarea inside iframe should be handled separately and listen for the changes made in the textarea. if you want to alter DOM or get something from DOM it should go in content scripts read more about it here in Chrome extension documentation and know the difference between content scripts and background scripts. Try starting with simple extensions like background-color changing extension to get the hang of it. JS for beginers might be confusing since its asynchronous, so I recommend doing some simple extensions first and get familarised with chrome extension API.

Importing / Changing HTML content (after ES6 update)

I have been trying to dynamically change the content of my HTML page by importing external HTML-files. I found a way to do this using HTML imports but if I have understood it correctly this feature is going to become obsolete in because of the ES6 update. From what I've manage to found online there could maybe be an alternative way to do this using javascript modules but I can't find anything concrete.
I want to be to change a big part of the page (a window containing a form becoming a window showcasing user statistics) so it doesn't seem smart to use .innerHTML in javascript. Does anyone have any good ideas on how to import html files or dynamically change the content of the page ? (using javascript, node, etc)
Any help much appreciated :)
I'm a bit late and the answer has already been linked to in the comments of this question, but here i go anyways.
You should be able to use Ajax to get the html file contents. (As a string)
With the content of the html file you should be able to parse it to a htmlDoc in JS (like the global document from document.getElement etc) using the DOMParser class.
https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
https://codepen.io/Deefoozy/pen/PeYWge
After parsing the html into a htmlDocument you should be able to get the body through the result using .getElement or .body.children. The result of this should be a simple domNode which you can append to another domNode.

How to use page-mod to modify element loaded by JavaScript

I'm creating firefox addon to add onclick event to the specific button. ("input" element)
The button is placed in http://example.com/welcome#_pg=compose
but when I open the page, following error occures:
TypeError: document.querySelector("#send_top") is null
#send_top is id of the button which I want to modify. So, the button is not found.
This error occurs because http://example.com/welcome and http://example.com/welcome#_pg=compose is completely different pages.
In this case, the addon seems loading http://example.com/welcome but there is no button whose '#send_top' ID.
When #_pg=compose anchor is added, the button is loaded by JavaScript.
How can I load http://example.com/welcome#_pg=compose to modify the button?
Three thoughts to help you debug this:
to correctly match the url you should consider using a regular expression instead of the page-match syntax - this might allow you to react to the anchors in a more predictable way
I've found that when using content scripts with pages that are heavily modified by JS, you can run into timing issues. A hacky workaround might be to look for the element you want and, if it isn' there, do a setTimeout for a 100 milliseconds or so and then re-check. Ugly, yes, but it worked for some example code I used with the new twitter UI, for example.
You can use the unsafeWindow variable in your content script to directly access the page's window object - this object will contain any changes JS has made to the page and is not proxied. You should use unsafeWindow with great caution however as its use represent a possible security problem. In particular, you should never trust any data coming from unsafeWindow, ever.

How does one properly test a javascript widget?

So, I've written a little javascript widget. All a user has to do is paste a script tag into the page, and right below it I insert a div with all of the content the user has requested.
Many sites do similar things, such as Twitter, Delicious and even StackOverflow.
What I'm curious about is how to test this widget to make sure that it will work properly on everyone's webpage. I'm not using an iframe, so I really want to make sure that this code will work when inserted most places. I know it looks the same in all browsers.
Suggestions? Or should I just build one hundred web pages and insert my script tag and see if it works? I would hope there is an easier way than that.
Once you have confirmed that your javascript works cross-browser in a controlled environment, here are some things that might cause problems when used on an actual website:
CSS
You're using a CSS class that is already being used (for a different purpose) by the target website
You're using positioning that might interfere with the site's CSS
The elements you are using are being styled by the website's CSS (you might want to use some sort of "reset" CSS that applies only to your widget)
HTML
You're creating elements with the same id attribute as an element that already exists on the website
You're specifying a name attribute that is already being used (while name can be used for multiple elements, you may not be expecting that)
Javascript
What is the expected behaviour without Javascript enabled? If your script creates everything, is it acceptable for nothing to be present without JS?
At very basic you should make sure your widget works for following test-cases. I am sure then it will work on all web-pages -
http/https: There should not be any warning for HTTPS pages for unencrypted content.
<script> / <no-script>: What if JavaScript is disabled? Is your widget still visible?
What happens when third-party cookies are disabled? Does your widget still work?
Layout-box restrictions: When parent div element's size is less than your widget. Does your widget overflow the given size and destroys owners page?
By keeping all your Javascripts under a namespace (global object) with a very unique name, you should be pretty much OK. Also, you can simply use an anonymous function if you just want to print out something.
Similar question: How to avoid name clashes in JavaScript widgets

Categories

Resources