I'm working on a Kirby site and I followed the 'Load More' tutorial for a website blog I am working on. Everything is working; however, I am also using an AJAX call for my parent pages. (I'm using swup library).
Normally, I would bind an event after an AJAX request to the document using .on() in jQuery; however, I can't seem to figure out how to do the same within the template/new.js file in pure Javascript.
Here's my code as per the tutorial:
const element = document.querySelector('.articles');
const button = document.querySelector('.load-more');
let page = parseInt(element.getAttribute('data-page'));
console.log(element.getAttribute('data-page'))
const fetchArticles = async () => {
let url = 'news.json/page:2';
try {
const response = await fetch(url);
const {
html,
more
} = await response.json();
button.hidden = !more;
element.innerHTML += html;
page++;
} catch (error) {
console.log('Fetch error: ', error);
}
}
button.addEventListener('click', fetchArticles);
Any help is greatly appreciated.
Related
I want to save the value 'final' (what I am logging to the console) to the clipboard every time it is updated. I have looked into clipboard.js but cannot find an example of where they didn't use HTML. In all the examples I've seen they press a button in order to do it but I need it to be automatically copied without any HTML. I tried using navigator.clipboard.writeText() but it gave me an error regarding promises and I'm not too sure how to resolve it or if there is a better solution.
const puppeteer = require("puppeteer");
const url = "https://www.google.com/";
async function StartScraping() {
await puppeteer
.launch({
headless: false,
})
.then(async (browser) => {
const page = await browser.newPage();
await page.setViewport({
width: 2000,
height: 800,
});
page.on("response", async (response) => {
if (response.url().includes("Example")) {
const location = await response.text()
let ping1= location.indexOf("Follow:")
const final = location.substring(ping1, ping1+ 10)
console.log(final);
//Copy 'final' to clipboard here
}
});
await page.goto(url, {
waitUntil: "load",
timeout: 0,
});
});
}
StartScraping();
Yes, you can do this.
You don't need any libraries, you can just do this with one line of code.
navigator.clipboard.writeText("text");
I put it in a function:
function copyText(a){ navigator.clipboard.writeText(a); } copyText("text");
This example uses a button (to execute the function):
function copyText(a) {
navigator.clipboard.writeText(a);
}
<h1>Copy text on button click</h1>
<p>Copy text without a form input or any extra js libraries</p>
<button onclick="copyText('Hello World!');">Copy</button>
It doesn't work in this snippet, but if you put it into jsfiddle or a w3schools tryit page, it would work.
I have a Wix site and I have this JS code in the site:
import { fetch } from 'wix-fetch';
$w("#button1").onClick( (event) => {
var link = $w("#link").id;
console.log(link)
fetch("https://my-new-app-xyz.herokuapp.com?link="+link, {"method": 'get'})
.then((httpResponse) => {
if (httpResponse.ok) {
return httpResponse;
} else {
return Promise.reject("Failed");
}
} )
.catch( (err) => {
console.log(err);
} );
})
However, upon the click of button1 nothing happens. Hopefully, the code explains what I want to do, but, upon clicking button1. I want to get the value of the text box element with id link and send a GET request to "https://my-new-app-xyz.herokuapp.com?link=" + the link from the text box. I don't know much JavaScript - this code is from reading the Wix API docs.
I am trying to load fingerprintjs in my chrome extension and for some reason it is not loading.
The documentation says to use this approach, which works fine in standalone web sites, just not in chrome extensions
<script>
function initFingerprintJS() {
FingerprintJS.load().then(fp => {
// The FingerprintJS agent is ready.
// Get a visitor identifier when you'd like to.
fp.get().then(result => {
// This is the visitor identifier:
const visitorId = result.visitorId;
console.log("visitorId", visitorId);
});
});
}
</script>
<script async src="fp.min.js" onload="initFingerprintJS();"></script>
For chrome extension I added created a JS file initFingerprint.js that holds the init code like so:
var visitorId = null; //will hold the actual fingerprint
function initFingerprintJS() {
console.log("inside initFingerprintJS");
FingerprintJS.load().then(fp => {
console.log("loaded initFingerprintJS");
fp.get().then(result => {
console.log("initFingerprintJS got result", result)
visitorId = result.visitorId; // This is the visitor identifier
console.log("visitorId", visitorId);
});
});
}
initFingerprintJS();
In background.html, I added this:
<script async src="fp.min.js"></script>
<script async src="initFingerprint.js"></script>
I have tried with async in there and not in there, but still no luck. This line will print, but none of the other lines below it.
inside initFingerprintJS
What am I doing wrong? I appreciate any help. thank you
Remove <script> tag for fp.min.js from the html and create the script element yourself in initFingerprint.js so you can use the onload event directly:
loadScript('fp.min.js').then(initFingerprintJS);
function loadScript(url) {
return new Promise((resolve, reject) => {
const el = document.createElement('script');
el.onload = resolve;
el.onerror = reject;
el.src = url;
document.documentElement.appendChild(el);
});
}
async function initFingerprintJS() {
visitorId = await (await FingerprintJS.load()).get();
console.log('visitorId', visitorId);
}
I have been trying for a few hours now and decided to finally post here. I have been trying so many methods to get my links to stop with preventDefault, this way I can load in content async.
All my links that i have tried that are apart of the template (like in the header) work perfectly, but any of the links brought in through an async view (and generated via js) completely skip over this snippet of code. I wanted to track anything that has a className "router" and stop the default action and run the function navigate instead.
var routeclicked = document.getElementsByClassName('router');
for(let i = 0; i < routeclicked.length; i++) {
routeclicked[i].addEventListener("click", e => {
console.log("Router is: " + routeclicked[i]);
e.preventDefault();
router = routeclicked[i].pathname;
console.log("Router 2 is: " + router);
navigate();
});
}
Attach a listener to "body" or the first non-dynamic parent.
You could go for Event.target and .closest().
Also, don't put functions inside for loops, it defies the reusability of functions.
const navigate = (EL) => {
location = EL.pathname;
}
const navigateHandler = (ev) => {
const EL = ev.target.closest(".router"); // Self or closest
if (!EL) return;
ev.preventDefault();
navigate(EL);
}
document.querySelector("body").addEventListener("click", navigateHandler);
I'm trying to create a markdown editor.
So far: I have loaded the index page. I'm using fs.readdir to get the titles of all the markdown files and display them in the sidebar. Then, on clicking on of these title #content get's the content.
module.exports = (win) => {
fs.readdir( './data', (err, data) =>{
data.map(title => {
if(title.split('.md').length==2){
el = document.createElement("li"); // get gave it the title ..
el.addEventListener('click', function(e){
fs.readFile(`./data/${title}`, (err, data) => {
document.getElementById('content').innerHTML = data;
});
})
document.getElementById('titles').appendChild(el) // title are on the page
The problem is when I introduce another page
I have a preferences page
win.loadURL(path.join('file://', __dirname, '../static/preferences.html'))
It has the same sidebar, hence I import the same code to get the titles. But now when I click one of the links, I don't want document.getElementById('content').innerHTML = data; but I want to load the index page and then inject the content
So far I tried this
const checkPageState = (pageName, callback) => {
if(pageName === "preferences"){
ipcRenderer.send(GO_TO_PAGE, 'index')
}
setTimeout(callback(), 1000);
}
...
el.addEventListener('click', function(e){
checkPageState(win, ()=>{
fs.readFile(`./data/${title}`, (err, data) => {
if (err) throw err;
fileDir = `./data/${title}`;
document.getElementById('content').innerHTML = data;
});
})
})
My thinking was ipcRenderer.send(GO_TO_PAGE, 'index') would load the index page (which it does) when wait for a bit and then inject the data into the index page. It doesn't!
How can I do this?
I recently tried to do this as well and it was kinda tricky but I found something that worked:
In electron when it tries to go to another page I stop it from going to it with:
win.webContents.on('will-navigate', function (evt, url) {
evt.preventDefault();
win.webContents.executeJavaScript('makeHiddenPageIframe("' + url + '");');
});
Then it calls the makeHiddenPageIframe function defined on the page.
Then in the page I define the makeHiddenPageIframe function:
function makeHiddenPageIframe (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, ''));
}
}
This then makes a iframe and loads the page in there then once it has loaded copy all the html from the iframe to the parent window so it seems like the switch happened instantly.
Also the window.history.pushState thing at the bottom was when you overwrite the html the url stays the same so when you reload it goes back to the original page but the window.history.pushState changes the url without reloading the page.
Any form of navigation will do the iframe load so you would keep your win.loadURL( to go to another markdown page.
The 'will-navigate' event docs.
window.history.pushState ref.
I hope this helps :)