window.addEventListener('load', (event) => {...}); on NuxtLink (nuxt-link) or RouterLink (router-link) click - vue.js

I am going to use the simplest example to explain what I mean.
window.addEventListener('load', (event) => {
console.log('page is fully loaded');
});
When the page loads for the first time the client side console logs 'page is fully loaded'. But when I click on a NuxtLink or RouterLink, I don't get a repeated log entry for the new page load.
If I use a standard link, then the console logs 'page is fully loaded' on page I visit, as it should. But it doesn't have the nice speedy page load as NuxtLink or RouterLink accomplishes.
In Rails, it has a similar feature called Turbolinks, but you can use .on('page:load',... to grab each page load.
Does anyone know how to fire the window-load per page load?

The <nuxt-link> component is similar to the <router-link> component.
In HTML5 history mode, router-link will intercept the click event so that the browser doesn't try to reload the page. This means that onload will only be triggered when the app is first loaded.
If you need to refresh and load the page every time you link to a new route, you can do this:
window.location.href = 'your link'
By linking to the page in this way, you can find from the network panel in the browser console that every time you load a page of type text/html from the server.

Related

NextJs Link doesn't reload page but reloads components

I am new to nextjs and I am building my first website. My links are rendered with the following:
const menuList = menu.map(function(menuItem: any){
return <Link href={`${menuItem.slug}`} key={menuItem.slug} as={`${menuItem.slug}`}>{menuItem.title}</Link>;
});
I have an index.tsx and [slug].tsx
When I click on a link it doesn't reload the entire page but the blue menu and image flashe white. I was expecting just the 'I made it to about us' content to change and the image and menu would not appear to change. Am I missing something or is this expected? If I hit the back button I get the results I expect. I read to use 'as' on Link but that doesn't seem to help. Any suggestions?

sending POST request to express route - after receiving form data, res.render is not triggered

I'm trying to create a simple app where a picture gets uploaded, and that picture is drawn on html canvas so that i can do some simple pixel manipulation.
Right now I have the GET method for root render an EJS template with a fileReader and a canvas.
With code attached at the bottom of the EJS file through script tags, I draw the uploaded image onto the canvas so I can read each pixel's rgb values.
I then tried to send those rgb values to the POST route in the app (through fetch), but it's not working as expected.
app.post("/", (req, res)=>{
console.log("inside post");
console.log(req.body);
res.render("test", {result: req.body});
console.log("after res.render");
});
All three of the console logs print correctly in the terminal, including the request body, but the test template is not being rendered. It just stays on the same "index" view the app launches with.
Can someone give me some insight as to why this is happening? I also included console logs inside the script tags in the ejs template, and these are only displayed in the browser, not in the terminal I launch the express app with. How can I render the view inside the post method?
First
If you use AJAX like Fetch API or XHR, browser will not render the test page.
Because it's asynchronous, and you could see Ajax in MDN web docs.
You need to use form post with following code.
<form action="/" method="post">
<button type="submit">go to another page</button>
</form>
But, if you use form post, your page which might be "index.ejs" will be replaced with "test.ejs".
In other words,
Browser uses the response from the forms POST request to load the new page.
But browser pass AJAX request's response to a callback and trigger callback in js.
Browser handle these two type request (Form Post and AJAX POST) with different ways.
In common, both are sending data to server.
So, in your case, res.render is triggered successfully.
Let me show you an example. Here is my server code.
const express = require('express')
const app = express()
app.set("view engine", "ejs")
app.get("/", (req, res, next) => {
res.render("test")
})
app.post("/test", (req, res, next) => {
res.render("other-test")
})
app.listen(3000)
<!-- test.ejs -->
<h1>this is test pages.</h1>
<!-- other-test.ejs -->
<h1>this is other test pages.</h1>
When I type url http://localhost:300, browser show me this.
And I open console in chrome and type following code.
fetch("/test", {
method: 'POST', // or 'PUT'
body: JSON.stringify({}), // data can be `string` or {object}!
}).then(res => {console.log("trigger response")})
Then go the network tab in chrome, you will see the request.
Here, this request trigger the express method.
But, what is the response?
Well, it's a html. That means res.render("other-test") is triggered correctly.
And you will find the console output show "trigger response" which callback is triggered in my fetch.
And, page still stay in "test.ejs".
Next, I add following code in my test.ejs
<form action="/test" method="post">
<button type="submit">Go to other page</button>
</form>
Page will be like this.
After you click, you will find out the browser show you "other-test" content.
That's a difference between form post and ajax post.
Second
You put script tag into ejs template.
Express will use ejs engine to render your ejs template become to html page.
After it become to html page, it means all script is running in browser not your nodejs terminal.

reCAPTCHA not showing after page refresh

Why is google reCaptcha2 (gReCaptcha) not showing after a page refresh, but showing if page is reopened by the link?
See this video for explanation: http://take.ms/I2a9Z
Page url: https://orlov.io/signup
Page first open: captcha exists.
Navigate by link: captcha exists.
Open new browser tab: captcha exists.
Refreshing page by refresh icon, ctrl+R, ctrl+F5: captcha NOT exists.
I added body unload event to prevent browser cache, it did not help.
Browsers for testing:
Firefix 39.0
Chome: 44.0.2403.125 m
Opera: 30.0
In all browsers I get the same result. So does this mean there's an error on my side?
I think it has to do with the browser and the speed of your network. You are calling ReCaptcha with a callback, but you call it before you define the callback. Depending on your network speed or browser quirks, it might execute before the rest of the script has loaded.
Line 330:
<script src="//www.google.com/recaptcha/api.js?onload=renderReCaptchaCallback&render=explicit&hl=en-US" async defer></script>
Line 351:
<script type="text/javascript">if (typeof (renderReCaptchaCallback) === "undefined") {
var reCaptchaWidgets = {};
var renderReCaptchaCallback = function() {
jQuery.each(reCaptchaWidgets, function(widgetId, widgetOptions) {
grecaptcha.render(document.getElementById(widgetId), widgetOptions);
});
};
}</script>
So I would move the definition of renderReCaptchaCallback to the top of the page so it is defined well before trying to load it.

Magnific Popup onload calling a url

I have an static HTML page I want to pop up using Magnific Popup when the page loads. In the examples on the site he only shows clicking a link that has the url of the page. I don't want a link but just page load. How do I get the url to be called without a link? I have the onload figured out
$(window).load(function () {
$.magnificPopup.open({
type: 'ajax',
showCloseBtn: true
}, 0);
});
So for example I want test.html to show up in the popup onload. Not sure how this is done.
You can initialize the magnific popup with a DOM Element created by jQuery and then click it. For example:
$(function() {
$('<a href="test.html">').magnificPopup({
type: 'ajax'
}).click();
});
If you need the link appear in the page, then just use appendTo function after click.

How to use jQuery's .on with Rails ajax link?

I'm having a bunch of problems getting jQuery's .on to work with my Rails ajax link.
Specifically, I've got this link:
<div id="item_7_tools" class="item_tools">
<a rel="nofollow" id="book_item_7" data-remote="true" data-method="post" class="book_link" href="bookings">Book this item</a>
</div>
I've trimmed some of the text in the HTML, but suffice to say that that, and my controller response work.
I click "Book this item", it goes off to the controller, the controller does its magic, and sends back my partial that replaces the contents of that div.
So I'm now trying to replace the contents with an ajax spinner while the loading is working, and that's where its going pear-shape.
I'm trying this initial bunch of jQuery code just to make sure I've got my javascript working:
$('div.item_tools')
.on('click', 'a', function() {
console.log("clicky click")
})
.on('ajax:beforeSend', "a", function() {
console.log('the a in div.item_tools is sending its ajax command');
})
.on('ajax:complete', "a", function() {
console.log('ajax request completed');
})
My understanding of that, is that when I then click any link (a) that lives within an element with the item_tools class, it will bubble up to this function, and then log the message into the console. Similarly, a link that has triggered an ajax request will get the same treatment...
(And assuming I can get that to work, then I'll go to work doing the ajax loader spinner).
The behaviour I'm seeing instead, is that when I click the link, there are no messages appearing in my console (trying this on both firefox and chrome), and my ajax link goes off and does its stuff correctly. Just completely ignoring the javascript...
Is this because my clicking the ajax link somehow has blocked the click event from bubbling up? I know that there's a way to do that, but I don't think I've done it anywhere knowingly. Unless OOTB rails/ujs does that?
So my questions:
Is there a way to tell what has had a binding attached to it?
What am I doing wrong with my javascript?
Thanks!
I use this all the time... and it seems to work fine.
Have you tried adding one that's .on('ajax:success')?
Besides that try putting the . for each line on the previous line...? It's possible that it gets to $('div.item_tools') and then auto-inserts a semi-colon as per javascript's standard... Although if that were the case I'd expect it to give you a JS error about the . on the next line. In any case try changing it to:
$('div.item_tools').
on('click', 'a', function() {
console.log("clicky click")
}).
on('ajax:beforeSend', "a", function() {
console.log('the a in div.item_tools is sending its ajax command');
}).
on('ajax:complete', "a", function() {
console.log('ajax request completed');
})
If worse comes to worse try just doing:
$("a").on("ajax:success", function(){
console.log('ajax:success done');
})
And see if it works without the event delegation...
Then change it to this:
$(document).on("ajax:success", "a", function(){
console.log("ajax:success with delegation to document");
})
And see if delegation works all the way up to document instead of just your item_tools
Are you sure that you've named everything right? it's div.item_tools a in your markup?
Turns out that the javascript was being triggered before the DOM had loaded, which meant that stuff weren't being bound...
$(function () {
$('div.item_tools')
.on('click', 'a', function itemToolsAjaxy() {
console.log("clicky click");
})
.on('ajax:beforeSend', "a", function() {
console.log('the a in div.item_tools is sending its ajax command');
$(this).closest('div').html('<img src=/assets/ajax-loader.gif>');
})
});
Added the $(function()) right at the beginning and it delayed the binding until after the DOM had loaded, and then it started working.
Figured this out by using the Chrome developer tools to stick a break on the div.item_tools selector and watched as the browser hit that even before the DOM had been loaded. /facepalm
(I removed the .on('ajax:complete') callback, because it turns out that there's a known limitation where the original trigger element no longer exists because it had been replaced, so there's nothing to perform the callback on. Not relevant to my original problem, but I thought I'd mention it.)
As far as i'm aware, you can either do ajax stuff 2 ways:
By using :remote => true
By using jQuery's $.ajax (or $.post).
With number 2, make sure to change your href='#'
My suggeston is to remove the :remote => true and manually make a jQuery ajax call. That way you can use beforeSend, complete, etc.
If i'm way off track here, someone please help clarify things for me as well.