How to write a "Delayed" svelte component? - javascript

I'm trying to write a Svelte component that hides its slot during the time specified.
For example, this next line should hide the paragraph during 3 seconds
<Delayed mili_time={3000}> <p>some text</p> <Delayed>
My attempt is not working and nothing is being shown (plus the log is shown though no errors are being raised)
I'd love to receive some help, tips or guidance.
The attempt:
<script>
import { onMount} from "svelte";
export let mili_time = 500;
let shown = false;
onMount(
setTimeout(() => {
console.log("delayed!");
shown = true;
}, mili_time)
);
</script>
{#if shown}
<slot />
{/if}
<style></style>
Thanks in advance to anyone reading or answering for getting till the end of the question ^^

your onMount is badly formatted, it takes as an argument a function while you have a function call.
The correct format would be:
onMount(() => setTimeout(....)
This way the function () => setTimeout(...) will be executed.
In your code, the setTimeout function is called and the return value of that function (a reference to the timeout) is passed into onMount

With a 100% native Component:
<delayed-content delay="1000" hidden>
<h1>Hello World</h1>
</delayed-content>
<script>
customElements.define("delayed-content", class extends HTMLElement {
connectedCallback() {
setTimeout(() => {
this.removeAttribute("hidden");
}, Number(this.getAttribute("delay")));
}
});
</script>

You can set a timeout after rendering and use a CSS class to hide the element as follows:
<script>
import { onMount } from 'svelte';
export let timeout = 3000;
export let hidden = false;
onMount(() => {
setTimeout(() => {
hidden = true;
}, timeout);
});
</script>
<div class:hidden>
<p>Some cool content here</p>
</div>
<style type="text/css">
.hidden {
display: none;
}
</style>

Related

window.addEventListener works only after a refresh

I need a little help for one function which is working only after a refresh. I`m not experienced with javascript and i need just to add one small "div" to already compliled project.
The index.html is
...
<body>
<script src="runtime-es2015-container.js" type="module">
<script src="runtime-es5-container.js" nomodule defer>
<script src="polyfils-es-5.js" defer>
<script>
window.addEventListener("DOMContentLoaded", function() {
setTimeout(() => {
let envContainer = document.querySelector('.info');
envContainer.setAttribute('style', 'flex-direction:column:');
let envRow = document.createElement('div');
envRow.classList.add('instance');
envContainer.appendChild(envRow).innerText = 'some text ';
},100);
}
....
The functional is working only after refreshing the page. I gues the problem is with selecting the '.info' , which is loaded before the function is executed.
Thanks,
Svetoslav
Just made a testrun of this and it seem to be working just fine, the only thing that was missing from your code was a ) in the end..
To me it looks like your problem is elsewhere. Well unless the info object is not created by code, then the problem is that it does not yet exist when you run this code..
--- Update ---
OKay so the div is created by js code and you have to wait for it.. the best idea I have is to poll and wait for it, I have updated the example to do just that and also changed to code to create the div after the first run of the function to simulate your situation.
function update_info() {
if(document.querySelector('.info')) {
let envContainer = document.querySelector('.info');
envContainer.setAttribute('style', 'flex-direction:column:');
let envRow = document.createElement('div');
envRow.classList.add('instance');
envContainer.appendChild(envRow).innerText = 'some text ';
} else {
setTimeout(() => {
update_info();
},100);
}
}
window.addEventListener("DOMContentLoaded", function() {
update_info();
const infodiv = document.createElement('div')
infodiv.id = "info";
infodiv.classList.add("info")
infodiv.innerHTML = "this first div";
document.body.appendChild(infodiv);
})
<body>
I see you have some errors in the code, try using this code which i fixed and changed a little bit and let me know if it works
<script>
window.addEventListener("load", function() {
setTimeout(() => {
let envContainer = document.querySelector('.info');
envContainer.setAttribute('style', 'flex-direction:column');
let envRow = document.createElement('div');
envRow.classList.add('instance');
envContainer.appendChild(envRow).innerText = 'some text ';
},100);
}
</script>

How can I update a value inside onMount() in Svelte?

Im trying to change the value of one variable inside onMount, but i cant, this is my attempt, how can I achieve to print, for example this... Here the REPL in svelte.dev
<script>
import { onMount } from "svelte"
let qrActive = false
console.log(qrActive)
const handleQr = () => {
qrActive = !qrActive
}
const qr = (qrActive) => {
if (qrActive) {
console.log("working");
} else {
console.log("Nothing :v")
}
}
$: onMount( () => qr(qrActive))
</script>
<button on:click={handleQr}>
Change!
</button>
onMount only runs once, it cannot be run again.
you might be able to use beforeUpdate or afterUpdate or just reactivity
$: qr(qrActive)
The above code will execute qr everytime qrActive changes

how add click event and get the dom in the iframe with react-frame-component?

i use the react-frame-component create a iframe,i want to bind a click event on the iframe and get the dom that id is abc in the iframe. how do that?
above is my code,it's will output null, get the element is not working.what wrong with my code.Help will be appreciated.Thanks.
...
componentDidMount() {
var iframe = document.getElementById("ccc");
console.log(iframe);
var iwindow = iframe.contentWindow;
console.log(iwindow);
var idoc = iwindow.document;
console.log(idoc);
console.log(idoc.getElementById('abc'));
}
return (
<div>
<Frame id="ccc">
<div id="abc">
<div>this.state.show is true and now I'm visible</div>
</div>
</Frame>
</div>
);
Something like this might work...
import { FrameContextConsumer } from 'react-frame-component';
const MyComponent = (props) => {
const frameWindow = useRef(null);
const getInnerHTML = () => {
const iframeWindow = frameWindow.current;
if(!iframeWindow) return;
// here you got the iframe window object
// work with it as you like
};
return (
<Iframe onClick={getInnerHTML}>
<FrameContextConsumer>
{(frameContext) => {
const { document, window } = frameContext;
frameWindow.current = window;
return <div>Your content goes in this return statement</div>
}}
</FrameContextConsumer>
</Iframe>
)
};
You need to use contentDidMount prop (not componentDidMount).
contentDidMount and contentDidUpdate are conceptually equivalent to componentDidMount and componentDidUpdate, respectively. The reason these are needed is because internally we call ReactDOM.render which starts a new set of lifecycle calls. This set of lifecycle calls are sometimes triggered after the lifecycle of the parent component, so these callbacks provide a hook to know when the frame contents are mounted and updated.
This code should print console.log properly
export default class App extends Component {
componentDidMount() {}
contentMounted() {
console.log("---------1");
var iframe = document.getElementById("ccc");
console.log("1", iframe);
var iwindow = iframe.contentWindow;
console.log("2", iwindow);
var idoc = iwindow.document;
console.log("3", idoc);
console.log("4", idoc.getElementById("abc"));
}
render() {
return (
<div className="App">
<Frame id="ccc" contentDidMount={this.contentMounted}>
<div id="abc">
<div>this.state.show is true and now I'm visible</div>
</div>
</Frame>
</div>
);
}
}

How to run a function when a prop updates within the same component?

I have a prop called transcript inside one of my components. It gets updated when I speak a voice intent. I would like to run a function anytime it changes which takes in the transcript as an argument
Here I am trying to do an OnChange={} function inside the span which I have loaded the transcript into but I know this method won't work, it was simply the easiest way of explaining what I wanted to accomplish
import React, { Component } from "react";
import SpeechRecognition from "react-speech-recognition";
import { Button } from 'react-bootstrap';
class Dictaphone extends Component {
highlightOnRead=(transcript, cursor)=>{
console.log("transcript",transcript)
console.log("cursor",cursor.anchorNode.parentNode.id) //we only need the word
if(transcript.includes(" ")){
transcript = transcript.split(" ").pop()
}
if(transcript = cursor.textContent.toLowerCase()){
cursor.style.backgroundColor = 'yellow'; //highlight the span matching the intent
}
cursor = document.getElementById(cursor.anchorNode.parentNode.id).nextSibling.nextElementSibling;
return cursor
};
render() {
const {transcript, resetTranscript, browserSupportsSpeechRecognition} = this.props
var cursor=''
if (!browserSupportsSpeechRecognition) {
return null
}
if(transcript==="notes"||transcript==="cards"||transcript==="home"|| transcript==="settings" || transcript==="read document"){
this.libraryOfIntents(transcript,resetTranscript);
}
return (
<div>
<span id="transcriptSpan"className="transcriptspan" onChange={()=>{
if(this.props.readAlongHighlightState===true){
if(cursor===''){
this.highlightOnRead(transcript,window.getSelection())
}else{
this.highlightOnRead(transcript,cursor)
}
}
}}> {transcript} </span>
<Button variant="outline-dark" onClick={resetTranscript}>Reset</Button>
</div>
)
}
}
export default SpeechRecognition(Dictaphone)
You can use lifecycle method called componentDidUpdate
componentDidUpdate(prevProps) {
if (this.props.transcript !== prevProps.transcript) { // check if your props is changed
// Make your function call here
}
}

trying to get my button to change text without user interaction javascript

i made a button function that has a button with a word and when its clicked the definition shows. but now i'm trying to make it so that the buttons shows the definition every couple seconds with "SetInterval" without needing to be clicked and i don't know how to go about doing so can you please help.
'use strict';
//below is the function for the even
$(document).ready(function() {
//
function salutationsHandler(evnt) {
let box = $("#message-box");
if (box.hasClass("hidden")) {
box.attr("class", "");
$(evnt.target).text("1.Salutation");
} else {
box.attr("class", "hidden");
$(evnt.target).text('a greeting in words or actions');
}
}
//end of function
setInterval(salutationsHandler, 1000);
//start of another
function DiffidenceHandler(evnt2) {
let box2 = $("#message-box2");
if (box2.hasClass("hidden")) {
box2.attr("class", "");
$(evnt2.target).text("2.Diffidence");
} else {
box2.attr("class", "hidden");
$(evnt2.target).text("the quality of being shy");
}
console.log(evnt2);
}
//lets me target id
let salutationsGrab = $('#Salutations');
// adds event to said id
// event listeners grab events from functions
salutationsGrab.on('click', salutationsHandler);
let DiffidenceGrab = $("#Diffidence");
DiffidenceGrab.on("click", DiffidenceHandler);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>hello welcome to our dictionary</h1>
<h2>Click on button to reveal definition of word shown</h2>
<button id="Salutations">1.Saluation</button>
<div id="message-box"></div>
<br>
<button id="Diffidence">2.Diffidence</button>
<div id="message-box2"></div>
<br>
The function salutationsHandler needs the event object generated by an event to work. Instead of calling the function directly, you can use jQuery's .trigger() to "click" the button.
function salutationsHandler(evnt) {
const box = $("#message-box");
const target = $(evnt.target);
if (box.hasClass("hidden")) {
box.removeClass("hidden");
target.text("1.Salutation");
} else {
box.addClass("hidden");
target.text('a greeting in words or actions');
}
}
let salutationsGrab = $('#Salutations');
salutationsGrab.on('click', salutationsHandler);
setInterval(() => salutationsGrab.trigger('click'), 1000);
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>hello welcome to our dictionary</h1>
<h2>Click on button to reveal definition of word shown</h2>
<button id="Salutations">1.Saluation</button>
<div id="message-box">a greeting in words or actions</div>

Categories