<html>
<head>
<style>
.inactiveLink {
pointer-events: none;
cursor: default;
}
</style>
</head>
<body>
<p> You have won a prize. Click here within <div id='clock'></div> seconds ...</p>
<script>
var time = 10;
var f = function counttime(){document.getElementById('clock').innerHTML--;}
function stoptime(){cleatInterval(f);}
if(time){
document.getElementById('clock').innerHTML = time;
var h = setInterval(f,1000);
setTimeout(function(){clearInterval(h);
document.getElementById('clock').innetHTML = "Time's up!";
}, time*1000);
}
</script>
</body>
</html>
I'm trying to create a basic webpage, that says "You have won a prize. Click here within 10 seconds ..." when it opens. You have 10 seconds to click "here" to get your prize. After 10 seconds, "here" should be unclickable. I added a CSS part about being unclickable, which is called "inactiveLink". I don't know how i should implement the change of anchor tag after 10 seconds, to JS. (I'm thinking about after 10 sec, a in HTML should be changed to a with id inactiveLink)
You were almost there :)
I would use a class that uses the CSS-rule pointer-events: none and then use JS to add that class to the link after 10 seconds:
const a = document.getElementById('a');
setTimeout(() => a.className = 'unclickable', 10000);
.unclickable { pointer-events: none; }
<a id="a" href="">Hurry up</a>
Use setAttribute to make it unclickable. Maybe make a class called "unclickable" with all of the CSS you want.
You can see this thread for more information on how to set your link so that it won't fire an event upon click. Check the second answer (not the one that the user marked as correct).
The best way to do it is by removing the attribute href removeAttribute("href");.
Note: that pointer-events:none only prevents mouse clicks but if you used the tab key and pressed ENTER over the link it will still be followed.
function myFunction() {
document.getElementById("anc").removeAttribute("href");
}
<a id="anc" href="google.com">Click Me.</a>
<button onclick="myFunction()">Disabler</button>
anchor tags dont have a disabled attribute, but one approach you can take is to style a button like a link. Something link this for example:
const buttonEl = document.querySelector('#target');
const handler = e => {
console.log('Button is still active!');
};
buttonEl.addEventListener('click', handler);
setTimeout(() => {
buttonEl.disabled = true;
}, 2000);
button {
all: unset;
color: blue;
cursor: pointer;
text-decoration: underline;
}
button:disabled {
color: gray;
cursor: not-allowed;
}
<button id="target" type="button">Click the button</button>
Related
Dears,
I have an assignment that is to create a repeated fade-out effect by using setInterval and using the DOM className method, below is my code:
<!DOCTYPE html>
<html>
<style>
.mystyle {
background-color: coral;
padding: 16px;
opacity: 0;
transition: opacity 1s linear;
}
</style>
<body>
<div id="myDIV"></div>
<p>Click the button to set a class for myDIV:</p>
<button onclick="setInterval()">Try it</button>
<script>
setInterval(change, 2000)
function change() {
function subchange1(){
document.getElementById("myDIV").className = "mystyle";
};
function subchange2(){
document.getElementById("myDIV").className = "";
};
}
</script>
</body>
</html>
However, it shows no change at all, could you tell me where i get wrong and how to correct it? Thanks very much!
You've used setInterval() as a user defined function. It needs two arguments one is callback function and other is time interval. You should've used and remove the setInterval in JS.
<button onclick="setInterval(change, 2000)">Try it</button>
In change() function you just declared the functions. You didn't call them back. It will not give you expected output even if you call them.
For your code to work you need to check if myDiv has class .mystyle. For that you'll need to use if-else statements.
Here's a Working code :-
let myDiv = document.getElementById("myDIV");
function change() {
if (myDiv.className === "mystyle") {
myDiv.className = "";
} else {
myDiv.className = "mystyle";
}
}
function startAnimation() {
setInterval(change, 2000);
};
#myDIV {
background-color: #1a8cff;
padding: 16px;
transition: opacity 1s linear;
}
.mystyle {
background-color: coral;
opacity: 0;
}
<div id="myDIV"></div>
<p>Click the button to set a class for myDIV:</p>
<button onclick="startAnimation()">Try it</button>
Since this is an assignment that you have to complete, I will only list the issue I notice and let you fix them as an exercise.
You have a <style> tag directly inside the <html>. You should have that style inside of a <head> element.
Code functions called inside of the <script> tag are executed directly and immediately. You are calling setInterval(change, 2000) directly so there is no need to to add it to the <button> tag. If you want the repeated action to only start when you press the button, you need to call setInterval, this line setInterval(change, 2000), inside of another function, like start for example. Then you add start to onclick like this: onclick="start()".
The change function has 2 function declarations in it but no function calls. This means that the two functions inside of it, subchange1 and subchange2 are never called. To use a function you need to call it. You should move those two functions outside, after the change function, and then you can call them by using subchange1() and subchange2().
That will fix your code issues but don't have correct logic to implement the function requirements. You can search for class toggle function and find different ways of doing it. I suggest in going with the one that better matches what you have already learned.
This looks like a medium to advanced assignment. The best way to solve these will be to start simple and test your code as you progess. It will be very dificult to write everything and test. I highly suggest you write a simple function call, like alert(7), and then add it to the button, test the button, then add it to a function, test the function with the button, then use it with setInterval. This will make sure you have things working before you add more complexity.
Good luck with you assignment :)
After few research, i found that it is highly the cause of the async nature of the codes of Javascript, i found using setTimeout can overcome this issue and my code is below:
<!DOCTYPE html>
<html>
<head>
<style>
.mystyle {
background-color: coral;
padding: 16px;
opacity: 0;
transition: opacity 1s linear;
}
</style>
</head>
<body>
<div id="myDIV" >
<p>I am myDIV.</p>
</div>
<p>Click the button to set a class for myDIV:</p>
<button onclick="change()">Try it</button>
<script>
function change(){
let abc = document.getElementById("myDIV");
abc.className = "mystyle";
setTimeout(function() {abc.className = "";}, 1000);
setTimeout(change, 2000);
};
</script>
</body>
</html>
I have a page with about 10 iframes. Only 1 of these iframes are visible and the index of the visible iframe changes every page reload. The visible iframe only contains a style of display: block, it doesn't contain anything else that I can use to select it like a name or title.
Example:
<div class="container">
<iframe style="display: none; width: 310px; height: 100px; border: 0px;
user-select: none;">
<html>
<body>
<div class="button"/>
</body>
</html>
</iframe> <--- not visible
<iframe style="display: block; width: 310px; height: 100px; border: 0px;
user-select: none;">
<html>
<body>
<div class="button"/> // need to click this!
</body>
</html>
</iframe> <--- visible :)
</div>
My question is how can I select the iframe with the display: block style in puppeteer and then click the button inside it.
I've tried to solve this by getting all the iframes on a page, looping over then and selecting the one with a display style of 'block':
// select all iframes
const Frames = await page.frames();
// loop over iframes and check if iframe display is block or none.
Frames.forEach(async (item, i) => {
const frame = await item.contentFrame();
const showingIframe = await page.evaluate(
() => window.getComputedStyle(frame.querySelector('iframe')).display
);
if (showingIframe === 'block') {
console.log('showing');
// click button
} else {
console.log('not showing');
}
});
You can easily find an element if the styling is very specific. No need to go through all frames for that.
const selector = `iframe[style*="display: block"]`
const visibleIframe = document.querySelector(selector);
console.log({ visibleIframe });
Clicking a button inside that can be done in a lot of ways. Here is a plain javascript solution,
visibleIframe.contentDocument.querySelector(".button").click()
Codesandbox link
Learn more about asterisk in Attribute selector
So I've finally solved this, thank you to #Md. Abu Taher for pointing me in the right direction.
try {
const selector = `iframe[style*='display: block']`;
await page.frames().find((frame) => frame.click(selector, { delay: 8000 }));
} catch (error) {}
What this does it it finds all the iframes on the page. It then finds and clicks on the iframe that matches the selector defined above, this holds down the button for 8 seconds which bypasses StockX captcha (or rather completes it as a user would).
Currently, I have a button class which lets me place a clickable button inside a sentence, and a div class which lets me add content to the button which I placed at the end of the paragraph containing the sentence.
This is an example of how I use them
Try to click <button class="col">THIS</button> and see what happens.
<div class="con">nice!</div>
Did you try?
When this text is displayed on the page, the two sentences are placed inside two different paragraphs, so the div object is placed between them.
Here is a snippet with the css classes and the javascript.
( function() {
coll = document.getElementsByClassName("col");
conn = document.getElementsByClassName("con");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].setAttribute('data-id', 'con' + i);
conn[i].setAttribute('id', 'con' + i);
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = document.getElementById(this.getAttribute('data-id'));
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
} )();
.col {
cursor: help;
border-radius: 0;
border: none;
outline: none;
background: none;
padding: 0;
font-size: 1em;
color: red;
}
.con {
padding: 0 1em;
max-height: 0;
overflow: hidden;
transition: .3s ease;
background-color: yellow;
}
Try to click <button class="col">THIS</button> and see what happens.
<div class="con">nice!</div>
Did you try?
I wonder if it is possible to implement a shortcut to place the two objects with one command, that is to obtain the previous example by using something like this
Try to click [[THIS|nice!]] and see what happens.
Did you try?
What I mean is that the command [[THIS|nice!]] should place the object <button class="col">THIS</button> in the same position and the object <div class="con">nice!</div> at the end of the paragraph containing the command.
Is it possible to implement such a command (or a similar one)?
EDIT
I forgot to say that the content of the button, ie what is written inside the div, should also be possible to be a wordpress shortcode, which is a shortcut/macro for a longer piece of code or text.
Using jQuery, closest() find the nearest <p> element and add <div class="con">nice!</div> after <p> element. To toggle you can use class active and add or remove .con element.
$('.col').click(function(){
let traget = $(this).closest('p');
if(traget.hasClass('active')) {
traget.removeClass('active');
traget.next('.con').remove();
} else {
traget.addClass('active');
traget.after(`<div class="con">${$(this).data('message')}</div>`);
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Try to click <button class="col" data-message="Hello">THIS</button> and see what happens.</p>
<p>Did you try?</p>
You usually dont use div to type text. you use it to define areas or group items. you could obtain what youre asking for in a 1 sentence like this:
html
<h1> some random text <a class="btnID">button</> some more text<h1>
css
.btnID {
color: red;
}
I have a markup that contains five boxes, a next button, and a kind of navigation menu, which I can use to point to a specific box. The next button id used to perform a translation of the boxes, which works the way thought it was. But the indicators doesn't work properly.
Here's my code:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="style.css">
<script src="script.js" defer></script>
</head>
<body>
<!-- Boxes -->
<div class="box current-box">0</div>
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<!-- End Boxes -->
<button class="next_button">Next</button>
<!-- Navigation -->
<div class="numbers-nav">
<button class="number">0</button>
<button class="number">1</button>
<button class="number">2</button>
<button class="number">3</button>
<button class="number">4</button>
</div>
<!-- End Navigation -->
</body>
</html>
CSS
*{
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
.box{
width: 100px;
height: 100px;
background: yellow;
transform: translateX(0px);
transition: transform 0.5s linear;
border: 1px solid #000;
text-align: center;
line-height: 100px;
font-family: 'Lucida Sans Unicode', sans-serif;
}
.numbers-nav{
display: inline-flex;
margin-left: 10px;
}
.number{
display: block;
}
JAVASCRIPT
var nextButton = document.querySelector('.next_button'); // The 'Next' button
var boxes = document.getElementsByClassName('box'); // Get all the yellow squares within the document
var boxesList = Array.from(boxes); // Creates an array with the boxes
var numbersNav = document.querySelector('.numbers-nav'); // Get the container of all indicators (the numbers)
var numbers = Array.from(numbersNav.children); // Creates an array with all the numbers itself
var transitionCompleted = true; // Indicates that the transition is complete
function transitioned(e) {
console.log('=== transition finished ===');
transitionCompleted = true;
}
window.addEventListener('DOMContentLoaded', function(){
var currentBox = document.querySelector('.current-box');
currentBox.style.transform = 'translateX(' + 100 + 'px)';
// Prevent multiple click when transition
boxesList.forEach(function (box, index) {
box.addEventListener('transitionend', transitioned);
box.addEventListener('webkitTransitionEnd', transitioned);
box.addEventListener('oTransitionEnd', transitioned);
box.addEventListener('MSTransitionEnd', transitioned);
});
// When the user clicks, translate the 'current-box' to 0px and then translate its next sibling 100px to the right
nextButton.addEventListener('click', translateNext);
// When the user clicks a number, repeat the translateNext function until 'current box' match the clicked number
numbersNav.addEventListener('click', moveToSpecificBox);
});
function translateNext(e){
console.log('Transition completed: ' + transitionCompleted);
if(transitionCompleted == true){
transitionCompleted = false;
var currentBox = document.querySelector('.current-box');
var nextBox = currentBox.nextElementSibling;
currentBox.style.transform = 'translateX(' + 0 + 'px)';
nextBox.style.transform = 'translateX(' + 100 + 'px)';
currentBox.classList.remove('current-box');
nextBox.classList.add('current-box');
}
}
function moveToSpecificBox(e) {
console.log('=== translating until an specific box ===');
var targetNumber = e.target.closest('.number');
// Discovers the position of the number inside the navigation box has been clicked
var targetIndexNumber = numbers.findIndex(function(number){
return number === targetNumber}
);
// Indicates the box that should have the 'current-box' class until the end of this code block.
var boxTarget = boxesList[targetIndexNumber];
while(!boxTarget.classList.contains('current-box')){
translateNext();
}
}
The idea is that the moment I click the next button, the box with the “current-box” class has a transformation, moving to its starting position, while the next box is moved 100px to the right, and becomes the "current box".
All boxes have their transition monitored to prevent functionality from triggering while elements are still moving. Therefore, while the transition is not finished, clicking in the next button doesn’t perform any action.
The navigation menu has indicators that are used to point to a specific box. When a number is clicked, it should repeat the functionality of the next button until the pointed box has the "current box" class.
If I click 2 as soon as the page loads, for example, the following should happen:
1st
Translate box 0 to 0px
Translate box 1 to 100px
Box 0 loses current-box class
box 1 receives the class "current-box"
2nd
Translate box 1 to 0px
Translate box 2 to 100px
Box 1 loses current-box class
box 2 receives the "current-box" class
Since box 2 is now the current one, the loop should stop. The following code snippet is responsible for doing that:
while(!boxTarget.classList.contains('current-box')){
translateNext();
}
That code checks to see if the pointed box has the class "current box" and if it does not, the function "translateNext" will be executed.
The problem is that the code is generating an infinite loop.
I think this is happening because of the event listener that is monitoring the transition. The elements never get their transition finished, so the transitionedCompleted become permanently false.
It's possible to see what is happening adding an limit to the loop, like this one:
var stop = 0;
while(!boxTarget.classList.contains('current-box')){
If(stop >= 5){ break }
translateNext();
stop++;
}
The translateNext function is executed only once, the transitionCompleted variable gets the false value, and its value is never changed again.
So, how can I call a function within a loop, while transition listener still works?
I don't think that you would want to use the while loop. Because, what is there to loop over?
In your code the transitioned function is fired whenever a transition is ended. So I would recommend that you call translateNext in that function. This way translateNext will only be called whenever a transition has finished and the next transition has to begin.
One of JavaScript's features is events. They enable you to trigger functions when certain events occur. It is a powerful feature and utilizing them can be a strong paradigm to work from.
function transitioned(e) {
console.log('=== transition finished ===');
transitionCompleted = true;
translateNext();
}
And in your translateNext function you are selecting the nextElementSibling of the current element. You can use this to check if the current element is the last element. And make the function keep going until the last element has been reached. Add the following if statement.
var currentBox = document.querySelector('.current-box');
var nextBox = currentBox.nextElementSibling;
if (nextBox === null) {
return;
}
This statement checks if the nextElementSibling is there will stop the function from running when it is not there.
I hope this will help.
I have a div that displays a little popup menu when clicked. I want users to be able to click anywhere in the body of the site to close the popup, but when I add code for that, the popup cant be opened at all anymore.
So I tried adding an if-statement so that the closemenu() function will only try close the popup if its already open, but it seems like the statement is evaluating to false even if the popup is open.
Here is the HTML for showing the popup:
<div class="popcolor" onclick="showmenu()"> Click!
<span class="popupcolor" id="myPopup">Pop!</span>
</div>
Here is the css:
.popcolor .show {
visibility: visible;
-webkit-animation: fadeIn 0.5s;
animation: fadeIn 0.5s;
}
Here is the Javascript:
function showmenu() {
var popup = document.getElementById("myPopup");
popup.classList.toggle("show");
}
function closemenu() {
var popup = document.getElementById("myPopup");
if (popup.style.visibility == "visible") {
popup.classList.toggle("close");
};
}
Here is the HTML for closing the popup:
<body onclick="closemenu()">
I've been through every post I can find on this for solutions, and I'm still stuck. Any help is appreciated.
You can use the getComputedStyle() method on the window object, to calculate the style rules that result from the classes applied to your popup element.
This gives you a reliable way of determining the values of different styling rules that result from, say, the 'close' class being applied to popup
Something along the lines of this should work for you:
function closemenu() {
var popup = document.getElementById("myPopup");
// Get the computed style, that is the combination of styles
// resulting from your CSS classlist, etc
var computedStyle = window.getComputedStyle(popup, null);
// Get visibility value from computed styles
var visiblityValue = computedStyle.getPropertyValue("visibility")
if (visiblityValue == "visible") {
popup.classList.toggle("show"); // Correct this from "close" to "show"
};
}
There are also some other functional issues with your implementation which are causing problems. Consider updating your showmenu() method to:
function showmenu(event) {
// Prevent event propagation, which would cause closemenu to call
// after this method is called
event.stopPropagation()
var popup = document.getElementById("myPopup");
popup.classList.toggle("show");
}
For more information on getComputedStyle(), see the MDN documentation
Problem here is that click event triggered from div bubbles up to body which eventually closes the popup.
function showmenu(e) {
e.stopPropagation();
console.log('toggle');
document.getElementById("myPopup").classList.toggle("close");
}
function closemenu(e) {
e.stopPropagation();
console.log('hide');
document.getElementById("myPopup").classList.add("close");
}
#myPopup.close {
visibility: hidden;
}
body {
border: 1px solid #ccc;
padding: 2rem;
}
<body onclick="closemenu(event)">
<div class="popcolor" onclick="showmenu(event)"> Click!
<span class="popupcolor close" id="myPopup">Pop!</span>
</div>
</body>
P.S. Use event.stopPropagation() to cancel/consume event
Because the visibility property is being set at the class level, the style information isn't available in the style property of your element. Maybe instead of checking for a specific style, you can check to see if the 'show' class is currently assigned to your element like so:
function closemenu() {
var popup = document.getElementById("myPopup");
if (popup.classList.contains("show")) {
popup.classList.toggle("close");
};
}
Problem in your code is with the use of JavaScript functions.
Try this simple example I took from W3Schools and enhanced it for your case.
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_add_class
There seems to be some issue with W3CSchool TryIt Editor page. Here is the link to JSBin for the same code: https://jsbin.com/xefolinape/edit?html,output
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.mystyle {
width: 100%;
padding: 25px;
background-color: coral;
color: white;
font-size: 25px;
box-sizing: border-box;
}
</style>
</head>
<body>
<p>Click the "Try it" button to add the "mystyle" class to the DIV element:</p>
<button onclick="myFunction()">Try it</button>
<button onclick="myFunctionClose()">Close it</button>
<script>
function myFunction() {
var element = document.getElementById("myDIV");
element.classList.add("mystyle");
}
function myFunctionClose() {
var element = document.getElementById("myDIV");
element.classList.remove("mystyle");
}
</script>
</body>
</html>
Hope this helps!