This is more like a auto-click link problem. But my problem is this link is generate by google's script.
http://translate.google.com/translate_tools
If you choose "translate a section" , there will be a link generate inside the goog-trans-control class
Original script:
<div class="goog-trans-section">
<div class="goog-trans-control">
</div>
Original Text here.
</div>
Script code after execute (Check Component):
<div class="goog-trans-section">
<div class="goog-trans-control">
<div class="skiptranslate goog-te-sectional-gadget-link" style="">
<div id=":1.gadgetLink">
<a class="goog-te-gadget-link" href="javascript:void(0)">
<span class="goog-te-sectional-gadget-link-text">Translate</span>
</a>
</div>
</div>
</div>
Original Text here.
</div>
How would I auto-click (or execute) the Translate link after this page is totally loaded?
For some reason, jsfiddle is not working with my script, though I still post this for your convenience.
http://jsfiddle.net/Wb7tE/
Really appreciate for your time and help.
Edited:
I tried Google translate API, but there is a limitation of 5000 words at a time.
My translations include whole html with tables and scripts, so it reach the limit with no exception.
I have a similar problem, and I solved it temporally like this
google_initialized = false;
function google_auto_translate()
{
if(google_initialized)
{
$('a.goog-te-gadget-link')[0].click();
}
else if(google.translate)
{
google_initialized = true;
setTimeout(google_auto_translate, 500);
}
else
setTimeout(google_auto_translate, 100);
}
window.onload = google_auto_translate;
but on slower connection, in 50 % of time google doesn't load on time, and script already clicks before loading is done. So if anyone know any other way to do this, via some events or something similar please add it here...
P.S. Don't use Google Translation API it's Deprecated and will be removed till the end of this year.
Related
I'm trying to use Tampermonkey to add a popup on pages in the Canvas LMS. It's a forum, and after each post there is a "Reply" option, which is what I want to add the popup to. But when I click the "Reply" link, no popup appears. It opens the Reply box, as normal, but my popup is nowhere to be seen.
The code looks roughly like this:
<div class="entry-controls hide-if-collapsed hide-if-replying">
<div class="notification" data-bind="notification"></div>
<a role="button" class="discussion-reply-action entry-control" data-event="addReply" href="#">
<i class="icon-replied"></i>
<span aria-hidden="true">Reply</span>
<span class="screenreader-only">Reply to Comment</span>
</a>
</div>
The JS code I'm trying to add is:
document.querySelectorAll('.discussion-reply-action').forEach(item => {
item.addEventListener('click', event => {
alert("Popup text here");
})
})
In addition to .discussion-reply-action, I've tried using .entry-controls, .notification, .entry-control, even stuff like span[aria-hidden="true"]. Nothing seems to work.
I know the Tampermonkey script itself is applying correctly, because it has other functionality that is showing up as usual.
Any idea why this bit isn't working for me? I'm a complete JS noob, for what that's worth.
This got answered in the replies, but just wanted to formally note that it came down to delaying my code injection. I was trying to attach to elements that loaded after the doc. Once I got behind them, it worked fine.
I'm trying to create an Electron app that has multiple "pages".
In my case, I'm trying to make an app with a sidebar that has different sections. Once a section is clicked, the main window's content changes to render the appropriate content for the section.
I'm new to JS so sorry if this is a dumb question, but as of now, whenever I try to go to a section of the app, I get a white-flash screen for a second before everything loads again.
Example: https://i.imgur.com/qOyuYsz.gif
I know this has to do with Electron reloading the Chrome engine, but how can I make it so when a section is clicked, the content is displayed automatically without any "flashes" or weird things?
Basically: how can I build a GUI with lots of components using Electron?
My code for my index.html is:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Rupture Tools</title>
<link rel="stylesheet" href="./photon/css/photon.min.css">
</head>
<body>
<div class="window">
<div class="window-content">
<div class="pane-group">
<div class="pane-sm sidebar">
<nav class="nav-group">
<h5 class="nav-group-title">1 Click Generator</h5>
<a class="nav-group-item active">
<span class="icon icon-home"></span>
Dashboard
</a>
<a href="accounts.html">
<span class="nav-group-item">
<span class="icon icon-user-add"></span>
Accounts
</span>
</a>
<span class="nav-group-item">
<span class="icon icon-cloud-thunder"></span>
Activity
</span>
<span class="nav-group-item">
<span class="icon icon-check"></span>
Check Scores
</span>
<span class="nav-group-item">
<span class="icon icon-cog"></span>
Settings
</span>
<span class="nav-group-item">
<span class="icon icon-help-circled"></span>
Help/FAQ
</span>
</nav>
</div>
<div class="pane">Home</div>
</div>
</div>
</div>
</body>
</html>
Please help! I'm clueless at this, been searching everywhere. I come from Python where there isn't much of any front-end development or GUI designing. Thanks!
There is "sort of" a solution here, but it uses something called Sass and as far as I know using something like React or Angular is better. I've never used either of those.
Electron apps are very similar to web apps. The traditional way of navigating between HTML documents doesn't work well for apps as you noticed. That's why web apps are developed as single-page applications (SPA) nowadays. It simply means loading and replacing parts of the page manually using JavaScript when the user navigates. There are several ways to implement this, but here's an example how it could be done for your code:
// Get all the navigation links to an array
const naviLinks = Array.from(document.getElementsByClassName("nav-group-item"));
const contentEl = document.getElementsByClassName("pane")[0];
naviLinks.forEach((linkEl) => {
// Listen click event for the navigation link
linkEl.addEventListener("click", e => {
// Prevent default behavior for the click-event
e.preventDefault();
// Get the path to page content file
const href = linkEl.getAttribute("href");
if (href) {
// Use node.js fs-module to read the file
const fs = require("fs");
fs.readFile(href, (err, data) => {
if (err) {
throw err;
}
// show the selected page
contentEl.innerHTML = "";
contentEl.insertAdjacentHTML("beforeend", data);
})
}
})
})
Note that the page content HTML files (accounts.html etc.) should only have the content for the "pane" div. You also need to pass nodeIntegration:true when creating your BrowserWindow-object in the main-process, so you can use require to load the fs-module:
new BrowserWindow({
webPreferences: {
nodeIntegration: true
}
}
If the page content files are large, navigation may seem slow, because files are read and pages are rendered on every click. One optimization to help with that is to read files and create page elements off-screen already at page load and then just swap the elements on click-events. Alternatively you could put the page contents in <template>-elements and swap them. I'll leave these for you to try out by yourself, if you're interested.
There are loads of JavaScript frameworks that can help you with creating SPAs. Some popular ones at the moment are React, Angular and Vue. "How can I build a GUI with lots of components?" is one of the questions front-end JavaScript frameworks can answer, but there's of course a learning curve. When you feel the need to start splitting your GUI into reusable or hierarchical components, it's probably a good idea to look into those JavaScript frameworks.
I made some code a while back to do this (Unfortunately it's rather complicated but it shouldn't be so hard to implement it).
You put this function on every page:
function loadPageWithIframe (url) {
var hiddenPage = document.createElement("iframe");
hiddenPage.setAttribute("src", url);
hiddenPage.style.display = 'none';
document.body.appendChild(hiddenPage);
hiddenPage.onload = function () {
var frameDocument = hiddenPage.document;
if (hiddenPage.contentDocument) {
frameDocument = hiddenPage.contentDocument;
} else if (hiddenPage.contentWindow) {
frameDocument = hiddenPage.contentWindow.document;
}
document.open();
document.write(frameDocument.documentElement.innerHTML);
document.close();
window.history.pushState("", document.title, url.replace('https://' + window.location.hostname, ''));
}
}
And this code in your Electron file:
mainWindow.webContents.on('will-navigate', function (evt, url) {
evt.preventDefault();
mainWindow.webContents.executeJavaScript('loadPageWithIframe("' + url + '");');
});
And if you put the code in correctly it should work automatically, without any extra code.
The way this works is you call the loadPageWithIframe function when you want to go to a url, then it makes an iframe and loads the page, copies the all the html from the iframe and overwrites the current page's HTML with the iframes HTML.
But instead of calling the loadPageWithIframe function on manually on every click you can use Electron's will-navigate event to let us know that it's going to another page, then call the loadPageWithIframe (this is the purpose of the electron code that I posted).
I hope that Helps :)
There is a carousel on a home page and I would like to add an onclick event to it to send the data back to GA. Each part of the carousel is a link. But I want to specify which selection on the carousel they selected. When I hover over each of the carousel links, the end of the URL says
#carousel-modal1, #carousel-modal2, #carousel-modal3, #carousel-modal4, #carousel-modal5.
How do I programmatically get the number of modal that's selected?
I would like to add an onclick event with a function. When I tried, I added the onclick to the rest of the code below. I know how to send the info back to GA but I guess the most important question is how do get that modal #?
HTML:
<div class="carousel-item">
<a
id="modal-111"
href="#carousel-modal"
onclick="myFunction()"
role="button"
data-toggle="modal">
<img class="d-block w-100" alt="" src="/somepic.png" />
</a>
</div>
Your question is kinda all over the place, but it seems like the prevailing idea is that you want to get 111 from the example via the onclick event...
To do that, you can use this, which provides access the element that activated the click. Then you can use some js string magic to get the number, like so:
function myFunction(){
var id = this.id;
var number = id.substring(id.indexOf('-')+1,id.length);
}
As a sidenote, you may want to consider using jQuery, it makes stuff like this way easier:
<div class="carousel-item">
<a
id="modal-111"
href="#carousel-modal"
role="button"
data-toggle="modal">
<img class="d-block w-100" alt="" src="/somepic.png" />
</a>
</div>
<!-- include the jQuery code on your site -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$( document ).ready(function() {
$('.carousel-item a').click(function(){
var id = this.id;
var number = id.substring(id.indexOf('-')+1,id.length);
});
});
</script>
In this example, you're attaching a function to all anchor links inside carousel-item tags, so you don't need to add an onclick to each one.
And based on your update in the comments, it seems like you want the number that follows the href attribute. Here's how to do that:
function myFunction(){
var href = this.getAttribute( 'href' );
var number = href.substring( href.indexOf('modal')+1, href.length );
}
Take a look at how this answer changed based on what you asked. What you were really looking for was answers to two small problems:
How to get the value of an attribute.
How to search within that value, or how to search a string.
Both of these questions are easily answered with google.
As you build more advanced things, the SO community is not going to spend time deciphering your question.
Next time, be sure to spend a lot of time simplifying your question to the bare essentials. Make sure it is as easy to understand as possible. Also be sure to create a working example (or as close as you can get) of your code on jsfiddle or codepen.
You should aim to spend at least an hour writing a question. If you take this advice, 99% of the time you will answer your own question before you need to post it here, and that will save you a lot of time. Good luck.
High all, I'm testing this e-commerce and I get this random popup (it's a div)that gets in the way of my scripts, given its random appereance I can't relly predict when it's going to show, otherwise I can easily interact with it, as it is a simple div, whenever I see it. It's there a way that can I catch this popup and do as I please whenever it dares to show? Thanks in advance
<div class="fsrFloatingMid"><div class="fsrInvite">
<div class="fsrDialogs">
<div style="margin-left: 0px;" class="fsrDialog ">
<div class="fsrLogos">
<img src="/_ui/desktop/common/foresee/sitelogo.gif" alt="" class="fsrSiteLogo">
<img src="/_ui/desktop/common/foresee/fsrlogo.gif" alt="Foresee" class="fsrCorpLogo">
</div>
<h1 class="fsrHeading">We'd welcome your feedback!</h1>
<p class="fsrBlurb">Some bullshit text</p>
<p class="fsrSubBlurb">The survey is designed to measure your entire experience, please look for it at the <u>conclusion</u> of your visit.</p>
<p class="fsrAttribution">This survey is conducted by an independent company, on behalf of the site you are visiting.</p>
<div style="" class="fsrB">
<div class="fsrAcceptButtonContainer">
Yes, I'll give feedback<span class="hidden-accessible"> (this will launch a new window)</span>
</div>
<div class="fsrDeclineButtonContainer">No, thanks
</div>
</div>
<div class="fsrFooter">
<img src="/_ui/desktop/common/foresee/truste.png" alt="TRUSTe verified" class="fsrTruste">
</div>
</div>
</div>
×<span class="hidden-accessible">Click to close.</span>
If this pop-up appears randomly then I think using the "protection proxy" design pattern would help most. The purpose of it is to execute a particular piece of code, in our example this:
if browser.div(class: 'fsrDialogs').exists?
browser.a(class: 'fsrCloseBtn').click
end
BEFORE any method on the "subject" ("subject" is the object we wrap inside the Proxy class, in our case it's the browser) is called. The Proxy design pattern is pretty straightforward to implement in Ruby, here's how we'd do it in your particular case:
class WatirProxy
attr_reader :subject
def initialize(browser)
#subject = browser
end
def method_missing(method, *args)
puts "I am executing the code below before calling #{method} with args #{args}"
if subject.div(class: 'fsrDialogs').exists?
subject.a(class: 'fsrCloseBtn').click
end
subject.send(method, *args)
end
end
You can remove the puts below method_missing in production, however, I'd recommend you keep it for now if you're not 100% clear on how the code below works.
Let's try playing with it:
browser = WatirProxy.new(Watir::Browser.new(:chrome)) # you can use ANY method on browser, although it's wrapped in a proxy
browser.goto 'https://google.com'
puts browser.text_field(name: 'q').exists?
Ruby should output:
I am executing the code below before calling goto with args ["https://google.com"]
I am executing the code below before calling text_field with args [{:name=>"q"}]
true # May change if google search box 'name' attribute changed to something other than 'q' in the future
In your specific case, this pop-up is raising errors because the browser didn't expect it, now we make sure there's a check BEFORE ANY method on browser is called. A great book for reading about the Proxy design pattern (and some other useful ones in Ruby) is Design Patterns in Ruby by Russ Olsen.
#browser.link(class: "fsrCloseBtn").click if #browser.h1(class: "hsrHeading").visible?
Something like this should be enough. Obviously, sub whatever you name your WebDriver instance for #browser. This clicks the close link if the dialog is visible and skips this step if the dialog is not there. My syntax might be a little wrong, so double check that. I'm used to wrapping all this in page-object, which would look like:
page_class.close_dialog if page_class.dialog_header_element.visible?
Had same issue with Foresee survey, I got around it by adding
while browser.text.include?("We'd welcome your feedback!") == false do
browser.refresh
sleep 1
end
browser.link(:class => /declineButton/).click
end
to the first step after going to the page. It's not the best option but it deals with the Foresee because once you close the window you get a fsr cookie that prevents the survey from popping up again during that browser session. The "sleep 1" was added so chrome would slow down and look for the Foresee survey. Hope it helps.
I have a client site that has a community events page. On that page, events are generated and put out one by one like this:
<div class="event-info">
<h5>This is an event</h5>
<span class="date">December 25, 2013</span>
<p class="details"></p>
</div>
They want a link on the homepage that goes to this one Christmas event, which will eventually start to move down the page. The only way to really find that block is by the contents of the <H5>. A classic anchor link would do the trick, but I can't add them to the <div class="event-info" /> block. The homepage link has to go to this page and then jump down to the necessary <div class="event-info" />.
jQuery or vanilla javascript are all I have to work with. I have one .js file that I can add to, and of course the html/javascript of the link itself on the homepage. I can't manipulate the existing HTML of the pages (content is dynamic - I add new stuff to it), and I have no access to the backend .NET framework.
Thanks.
something like this?
jquery:
var hash = window.location.hash;
if (hash==='#xmas') {
var xmas = $('.date:contains("December 25")').parent('.event-info').offset().top;
$('html,body').animate({scrollTop: xmas}, 500);
}
You just add #xmas to end of the page url, like: http://fiddle.jshell.net/filever10/afK7M/show/light/#xmas
made a fiddle: http://jsfiddle.net/filever10/afK7M/