Javascript to modify web content on cell click - javascript

I am working in an app for iOS with WhatsApp Web, and I am giving a new look to it inside the app.
I am implementing some JS functions to a WkWebView such change width values, background colors and other stuff, but I am stuck in a point.
As you may or may not know, the WhatsApp Web App, has two main columns, one of them shows the chats, and the other one shows the selected chat. Like this:
At this moment, I have managed to load the web app on a wkWebView and give the chats column the 100% of the device width. But now I need to catch the click on "cell" from this column in order to change the width value to the other side of the web app.
Other problem seems to be that on an iPhone I need to tap twice in the "cell" to make it load the chat data in the right column. So the question is, can anyone help me to solve my doubts or give me a little hint with it?
Thanks a lot!
M.W.

Well, some days of research about JS functions I have managed to detect the touches events in the web view. The sentence you can test in the web.whatsapp.com java console is like this:
function handleStart(evt) {
evt.preventDefault();
console.log('touchstart');
}
elements=document.getElementsByClassName('NAME');
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener("touchstart", handleStart, false);
}
The evt.preventDefault(); prevents the execution of the flow of the touch, so if you want it to work, just comment this line.
With this functions you can handle touch start, touch end, touch move, and some more...
Other thing, if you want to execute this sentence in a WkWbView on iOS, you just need to call a JS function like this:
jsString = #"function handleStart(evt) {evt.preventDefault();console.log('touchstart.');} \
elements=document.getElementsByClassName('NAME'); \
for (var i = 0; i < elements.length; i++) { \
elements[i].addEventListener('touchstart', handleStart, false); \
}";
[self callJS:jsString];
And the callJS function will need to call this:
[_wkWebView evaluateJavaScript:jsString completionHandler:^(id response, NSError *error) {
if (error)
NSLog(#"%#", error.description);
}];
And in ordet to 'read' the click on the cell of the left column with out mess with the other events, you can handle the tap with click event like this:
elements=document.getElementsByClassName('NAME');
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', 'console.log('click')', false);
}
Hope it helps!

Related

How to use JavaScript to click a div like button on an HTML page?

I'm currently trying to automate a game called Lyrics Training (https://www.lyricstraining.com/) and I am able to get the words that are from the button through some other code but I am currently struggling with clicking the "button" because it is for some reason classified as a in the HTML code. I was wondering whether there was a way or a function that would allow me to click it so I could finish the automation? Thanks!
So far I have this code that would work if the button was an actual button:
let firstChoice = document.getElementsByClassName("slot s1")[0];
let secondChoice = document.getElementsByClassName("slot s2")[0];
let thirdChoice = document.getElementsByClassName("slot s3")[0];
let fourthChoice = document.getElementsByClassName("slot s4")[0];
// the click function isn't working
for(let i = 0; i < click_order.length; i++){
let word = click_order[i];
if(firstChoice.innerHTML === word){
firstChoice.click();
}else if(secondChoice.innerHTML === word){
secondChoice.click();
}else if(thirdChoice.innerHTML === word){
thirdChoice.click();
}else if(fourthChoice.innerHTML === word){
fourthChoice.click();
}
}
This is how the "buttons" look like in the HTML code of the website:
Any help would be appreciated! Thanks!
If I am not misinterpreting anything, then it sounds like you are trying to automate a game on some website. I'm not sure exactly how they coded the game, but there is a chance the code doesn't actually listen for "click" events.
It seems like your code only works if the website's code responds to click events such as:
div.addEventListener("click", somefunction);
//or
btn.addEventListener("click", somefunction);
In this case, your code would still work on divs.
However, they could be responding to mousedown events:
div.addEventListener("mousedown", somefunction);
If this is the case, you might want to read up on invoking specific events: https://developer.mozilla.org/en-US/docs/Web/Events/Creating_and_triggering_events
But please keep in mind that many websites have code preventing this stuff.
Give the button div element an attribute of role="button". This should work fine.

Javascript code for addEventListener not working!? (open enlarged img when clicked)

Whenever an image is clicked, the image should be displayed alone in a new window. It should be done completely in javascript (so no onclick functions in the HTML should be used) and with no jquery. I´ve done some research and have managed to get this far:
Javascript
var img = document.getElementsByTagName("img");
for(var i=0; i < img.length; i++) {
img[i].addEventListener("click", enlarge);
}
function enlarge() {
window.open(this.src);
}
Unfortunately, nothing happens when any image is clicked and I can´t figure out why. Can anyone help me solve this problem of mine?
Thank you in advance!
your code should work fine check https://jsfiddle.net/3hgkaxgv/1/
The possible causes for your issue are:
Either browser compatibility or you already have something attached or catching click event.
Edit:
try the new changes if click registered was logged then you probably have popup disabled or something like that.
Try this instead of your code.
var img = document.getElementsByTagName("img");
for(var i=0; i < img.length; i++) {
img[i].onclick = enlarge;
}
function enlarge() {
console.log('click registered ');
window.open(this.src);
}
I found the solution!
The reason no clicks registrered (which turned out to be the issue as to why my code didn´t work for me) was because I put the <script src="inlamning6.js" type="text/javascript"> </script> first in the HTML-document, namely right after the <body> tag. It should be last in the HTML-document, right before the <body>tag is closed. I moved it accordingly, and everything works fine now!
I thought that this could be valuable information if anyone else ever gets stuck on the same problem as I did here.

Page Load for extracting from Google chrome

I have found a few related questions, but none was able to solve my problem, so any help is greatly appreciated!
I am fairly new to coding and am creating a JavaScript extractor for the chrome console. I am loading a search page, but when Javascript attempts to extract the information, the search is not loaded yet.
I tried a for loop to pause my script, but turns out the page load is paused during that time. I found something like this:
for(var i=0; i < 1000000; ++i) {
setTimeout(function(i) {
return function() { dosomethingheavy(i); }
}(i), 0);
}
but it did not work right (or I did not know how to use it properly). I structured my code like this:
For loop to go to each page, extract info from page, go to next page, in the end it returns a csv file of all the data.
My question is how can I allow for the ca. 2 sec page load?
Thank you very much!
You must wait for the DOM to be fully loaded before acting. You can do that using the DOMContentLoaded event.
document.addEventListener('DOMContentLoaded', function() {
dosomethingheavy();
}, false);

window.scrollTo not working in phonegap - alternative solution or workaround?

I've written a rather basic js function that programatically and automatically aligns the iPhone keyboard perfectly underneath each and every input field that gets focused (feel free to use it if you like it!). The alignment's primarily handled by window.scroll - a standard method that works in any browser view, except in UIWebView hence phonegap/cordova (2.1). So I need a workaround.
My working code:
function setKeyboardPos(tarId) {
//programmatically: set scroll pos so keyboard aligns perfectly underneath textfield
var elVerticalDistance = $("#"+tarId).offset()["top"]; //i.e. 287
var keyboardHeight = 158;
var heightOfView = document.height; // i.e. 444
var inputHeight = $("#"+tarId).outerHeight();
var viewPortSpace = heightOfView-keyboardHeight; //i.e. 180
var verticalNewSroll = (elVerticalDistance+inputHeight)-viewPortSpace;
if(verticalNewSroll<0) { verticalNewSroll = 0; }
////
//OK, all done lets go ahead with some actions
$("#footer").hide(); //hide footer so that the keyboard doesn't push it on top of textfield
$("#containingDiv").css("bottom","0px"); //remove bottom space for footer
window.scrollTo(0,verticalNewSroll); //scroll! where the problem starts
}
Working in everything but UIWebView, that is. As I mentioned above, everything works except the window.scrollTo (N.B. some minor changes have been made for the sake of clarity). So does anyone know of an alternative solution or even a good workaround?
Similar questions
window.scrollTo doesn't work in phonegap for IOS
PhoneGap / Cordova scrollTo Ignored
How to add vertical scroll in Phonegap
Above are furthermore three similar questions that somewhat points one in the right direction. One of the answerers mentions the use of css to accomplish this. Can anyone come up with a more concrete example? Another guy suggests anchors but that's not a very pretty solution and doesn't go very well with the rest of my code.
After doing some research, I realized window.scrollTo() does actually work in iOS6 with phonegap 2.1, there was something else that failed; for some reason, document.height didn't yield a property of equal proportion within UIwebView so I had to write a small workaround. I'll post the solution and the entire code below for future reference.
function setKeyboardPos(tarId) {
//programmatically: set scroll pos so keyboard aligns perfectly underneath textfield
var elVerticalDistance = $("#"+tarId).offset()["top"];
var keyboardHeight = 157;
if(isNativeApp()) { keyboardHeight = 261; } //I choose to change the keyboard height for the sake of simplicity. Obviously, this value does not correnspond to the actual height of the keyboard but it does the trick
var keyboardTextfieldPadding = 2;
var heightOfView = document.height;
var inputHeight = $("#"+tarId).outerHeight();
var viewPortSpace = heightOfView-keyboardHeight-keyboardTextfieldPadding; //180
var verticalNewSroll = (elVerticalDistance+inputHeight)-viewPortSpace;
if(verticalNewSroll<0) { verticalNewSroll = 0; }
////
//OK, all done lets go ahead with some actions
$("#footer").hide(); //hide footer so that the keyboard doesn't push it on top of textfield
$("#containingDiv").css("bottom","0px"); //remove bottom space for footer
window.scrollTo(0,verticalNewSroll); // perform scroll!
}
function isNativeApp() {
var app = (document.URL.indexOf('http://') === -1) && (document.URL.indexOf('https://') === -1);
if (app) {
return true; // PhoneGap native application
} else {
return false; // Web app / safari
}
}
you can try and use the animate and scrollTop property to scroll It looks something like this:
$("html, body").animate({ scrollTop: "The value to scroll to" });
Hope this helps.
You just need to use this:
$(window).scrollTop(0);

Resize a dynamically generated iframe

I have a report generated by Oracle Apex (A UI tool operating against the Oracle database). I have customized it to have a hyperlink on each record, which when clicked opens a detail report in an iframe right under the current record. This, I am doing by using the Javascript insertRow method on the html table element (Condensed Javascript code below. Oracle APEX allows use of JS/Jquery)
var pTable= html_CascadeUpTill(t,'TABLE');
var myNewRow = pTable.insertRow(pTR.rowIndex+1);
var myNewCell = myNewRow.insertCell(0);
myNewCell.innerHTML = '<iframe src="detail report url" height="0"></iframe>';
In order to resize the height of the iFrame that is different for different detail records, I have the following code in the document).ready(function() of the page
$('iframe').load(function()
{
setTimeout(iResize, 1000);
}
function iResize()
{
// Iterate through all iframes in the page.
for (var i = 0, j = iFrames.length; i < j; i++)
{
var y=(iFrames[i].contentWindow || iFrames[i].contentDocument);
if (y.document)y=y.document;
var docHt = getDocHeight(y);
if (docHt) iFrames[i].height = docHt + "px";
}
}
);
Without the setTimeout call to iResize function, the iframe resize is not happening. But this setTimeout is adding a delay in the resized iframe to appear which I want to avoid. Is there a way to do this? All the related posts/articles I have seen online deal with iframes that are built into the page but not generated on-the-fly as in my case.
Let me know if you need more information. Please help. Thank you.
You should consider putting the details in a <div> block, then showing or hiding the <div> with JQuery. You can set dimensions for your block with CSS, or just let the content flow normally inside of the block. Sounds like a much simpler way to achieve the same effect.
The issue is that if you perform the resize too soon it will get the dimensions of the child document before it has been fully rendered, hence the use of a timer.
If your detail reports are other APEX pages that you control, then you could call the iResize function from the "Execute when page loads" section of the detail page:
parent.iResize();
That seems to work for me.
It sounds to me like the iframes don't even exist when the page first loads.
Instead of calling the iResize function on page load and then every second you could place the call to iResize in the code that creates the iframe.

Categories

Resources