Make an onclick event react different when click second time - javascript

I have a button on my website, which plays the music when you click on it and in the same time it changes the text inside of the button (to "Go to SoundCloud".)
I want that button (with the new text on it) to redirect to SoundCloud when I click on it.
Now I got both when click first time, which is redirect to SoundCloud and play the track. (plus it changes the text)
Any ideas, how to solve this problem? Thx!
var links = document.getElementById("playButton");
links.onclick = function() {
var html='<iframe width="100%" height="450" src="sourceOfMyMusic"></iframe>';
document.getElementById("soundCloud").innerHTML = html;
var newTexts = ["Go to SoundCloud"];
document.getElementById("playButton").innerHTML = newTexts;
newTexts.onclick = window.open('http://soundcloud.com/example');
};

Use a variable that indicates whether it's the first or second click.
var first_click = true;
links.onclick = function() {
if (first_click) {
// do stuff for first click
first_click = false;
} else {
// do stuff for second click
}
}

Just redefine the onclick after the first function call.
Put the onclick on the button instead of the html.
document.getElementById("playButton").onclick=window.open('http://soundcloud.com/example');

Another option in some cases is to use a ternary operator and a boolean toggle expression:
let btn = document.querySelector('.button');
let isToggledOn = false;
btn.addEventListener ('click', function(e) {
e.target.textContent = !isToggledOn ? 'Is ON' : 'Is OFF';
isToggledOn = !isToggledOn;
});

newTexts.onclick is not creating a function to open a window, it is simply taking the return value of window.open which is being executed right away.
It should look like:
newTexts.onclick = () => window.open('http://soundcloud.com/example');
Also this will not work as intended because newTexts is not the actual DOM element, you need to attach the new onclick on the element and not the array...
But to other answers in this page, the logic is hard to read, so I'd advise to refactor the logic to be more readable.

Related

HTML buttons will only work only on webpage re/-load

EDIT : Thanks to everyone who tried to help me. I appreciate the tips guys.
I changed my window.onloadand inserted the two event listeners inside of it.
After that I took the idea of #Ito Pizarro , and implemented it in my own way.
The result looks like this :
function openDoor() {
var x_1 = document.getElementById('img1');
var x_2 = document.getElementById('img2');
is_visible = (x_1.style.visibility == "hidden");
if (is_visible) {
x_1.style.visibility = "visible";
}
else {
x_2.style.visibility = "hidden";
}}
And I also did the same for my closeDoor() function.
END OF EDIT
I create a HTML page, with two buttons. Every button has its purpose when it's being clicked. The first one will show an image of an opened door. The second button will show an image of a close door. When the page is loaded no image is being shown. They appear only if their button is clicked.
Tried to created a nested if-statement with the a global bool that will make it run infinitely.
Also tried a for & while loop.
But I am new to programming and I struggle a bit.
window.onload = function () {
document.getElementById('OpenDoor').addEventListener("click", function () { openDoor() })
}
window.onload = function () {
document.getElementById('CloseDoor').addEventListener("click", function () { closeDoor() })
}
function openDoor(){
document.getElementById('img1').style.visibility = "visible";
}
function closeDoor(){
document.getElementById('img2').style.visibility = "visible";
}
In the code exist two problems :
I load the page and click the "close door" button and the closed door image appears. If I decide to open the door again by pressing the "open door" button, it wont do it.
I load the page and click the "open door" button first. The open door image appears and the if I click on the "close door" button and the image also appears, but I cant repeat the process by re-clicking the "open door" to reopen it.
You are assining a function on the onload event twice. By doing this the first delaration will never be triggered.
It should be more something like :
window.onload = function () {
document.getElementById('OpenDoor').addEventListener("click", function () { openDoor() })
document.getElementById('CloseDoor').addEventListener("click", function () { closeDoor() })
}
Don't forget to validate the answer if you have what you were looking for
EDIT: In addition to lucien-dulac's point about window.onload…
It looks like your two event handlers do a single thing to either of two separate elements.
openDoor() will only ever make #img1 visible.
closeDoor() will only ever make #img2 visible.
If you want subsequent clicks on #OpenDoor or #CloseDoor to change the visibility style of their respective target elements — #OpenDoor controls #img1, #CloseDoor controls #img2 — you would need to write a toggle into openDoor() and closeDoor().
Something like…
function openDoor(){
var el = document.getElementById('img1'),
is_visible = ( el.style.visibility === "visible" );
if ( is_visible ) {
el.style.visibility = "hidden";
} else {
el.style.visibility = "visible";
}
}

Stop a portion of Javascript function from auto firing

Is it possible to stop the script and wait for user input before continuing it?
Here is the portion that I need to stop:
var nName = document.getElementById("b1");
nName.innerHTML = "Continue";
document.getElementById("b1").onclick = newName();
So "b1" is a HTML button, I want to stop it after
nName.innerHTML = "Continue";
and wait for user click on the button before firing
document.getElementById("b1").onclick = newName();
using return completely stop the script. Is there any other possible way to do this?
You do not need to stop the script. You cannot.
Pass references to the functions (no paranthesis on the function names) like so:
document.getElementById("b1").onclick = newName;
Example:
function firstClick(){
document.getElementById('b1').innerHTML = "Continue"
// override the first click listener. "firstClick" will no longer be called.
document.getElementById('b1').onclick = newName;
}
function newName(){
document.getElementById('b1').innerHTML = "Good Job!"
}
// listen for first click
document.getElementById('b1').onclick = firstClick
<button id=b1>Click Me!</button>
In order to fully understand what is going on, I do must refer you do Google and Documentation, and most of all - Experimentation.
But in short, in not technical terms.
onclick does nothing on its own. It needs to be told what it does. The browser will do what you tell it to. There can only be 1 function assigned to it. So if you do onclick=a; onclick=b; onclick=c, only c will be called.
If you assign the function name with paranthesis onclick = newName(), what you are doing is you are running the newName() and assigning its return to the onclick. So in this case - nothing. If you do onclick=newName the borwser will automatgically add the paranthesis.
You could even create a 'triaging' function to decide what the next steps are:
function triage(){
var el = document.getElementById('b1');
if (el.innerHTML == "Continue"){
el.innerHTML = 'Good Job!';
}else{
el.innerHTML = 'Continue';
}
}
// listen for first click
document.getElementById('b1').onclick = triage
<button id=b1>Click Me!</button>

Query selector to select Button A only if site does not have Button B

I'm creating a Chrome Browser Extension that clicks some buttons automatically whenever they appear. I'm using arrive.js for the watching, which uses a query Selector to watch for the html elements to click on.
var buttonA = 'a[data-test="begin-session-button"]'
var buttonB = 'a[data-test="skill-header-practice-button"]'
document.arrive(buttonA, function () {
document.querySelector(buttonA).click();
});
document.arrive(buttonB, function () {
document.querySelector(buttonB).click();
});
The Problem I have is some sites have both buttons buttonA and buttonB. As of now both buttons would be clicked and it is a matter of luck which one gets clicked last.
Whenever there is a site with buttonA and buttonB, only click buttonA. So I'm looking to alter the query for buttonB like:
document.arrive(buttonB + ' :not:' + buttonA, function () {
document.querySelector(buttonB).click();
});
As a query in the Chrome Browser Console this would look like:
document.querySelector(
'a[data-test="skill-header-practice-button] ' +
':not:a[data-test="begin-session-button"]'
)
This is bad syntax and not working in the chrome brower console. How would the Correct Syntax look like?
Could you not do something like this
document.arrive(buttonA, function () {
document.querySelector(buttonA).click();
});
document.arrive(buttonB, function () {
if(document.querySelector(buttonA) == null){
document.querySelector(buttonB).click();
}
});
I can't say that I have used the arrive library before though so I could be completely wrong
i guess this is simpler to do it "programatically" than with complex selectors, something like (works with your code because buttonA is global, be careful that this var must be accessible to the function):
var buttonA = 'a[data-test="begin-session-button"]'
var buttonB = 'a[data-test="skill-header-practice-button"]'
document.arrive(buttonA, function () {
document.querySelector(buttonA).click();
});
document.arrive(buttonB, function () {
var buttA = document.querySelector(buttonA);
if(buttA === null){
document.querySelector(buttonB).click();
}
});

How can one <img> tag be used to execute 2 different js functions?

How can I set up one image, that when clicked changes to another image and then when clicked again reverts back to the original image while still carrying out functions independently. In my example I want a Play button that when pressed turns to a pause button. However I need to have both play and pause functionalities when the correct button is pressed. These work on do different buttons but I would like the one button to have all the functionality. I have tried a few things but everytime, one of the play/pause functions are not letting the other work.
$('#startSlider').click(function (){
if (document.getElementById("startSlider").src = "Play.png"){
document.getElementById("startSlider").src = "Pause.png";
scrollSlider();
}
else if (document.getElementById("startSlider").src != "Play.png"){
clearTimeout(tmOt);
document.getElementById("startSlider").src = "Play.png";
}
});
<img src="Play.png" id="startSlider"/>
problem is in your if block,
you are using = not ==
if (document.getElementById("startSlider").src = "Play.png"){// you are assigning here not comparing
you are assigning play.png every times when the click calls on the image.
you are using jquery then why are you not using this to make it more simple.
$('#startSlider').click(function (){
if (this.src == "play.png"){
this.src = "pause.png";
}else{
this.src = "play.png";
}
});
check this fiddle
I like using classes in these situations as it makes the code a little easier to follow:
$('#startSlider').click(function (){
$(this).toggleClass('pause')
if ( $(this).hasClass('pause') ) {
// Button is paused change to play
$(this).attr('src', 'Play.png')
// Pause function goes here
} else {
// Button is play change to pause
$(this).attr('src', 'Pause.png')
//play function goes here
}
})
You can do this with a little state machine. You keep the states inside an object, and handle the next state in the event listener of the button:
var states = {
_next: 'play',
next: function() {
return this[this._next]()
},
play: function() {
img.src = 'pause.jpg'
button.textContent = 'Pause'
this._next = 'pause'
},
pause: function() {
img.src = 'play.jpg'
button.textContent = 'Play'
this._next = 'play'
}
}
button.addEventListener('click', states.next.bind(states))
This is more of a general answer to your problem, that you'd have to adapt to your code.
DEMO: http://jsbin.com/moxoca/1/edit *
* The images might take a second to load.

using onbeforeunload event, url change on selecting stay on this page

Rewriting the question -
I am trying to make a page on which if user leave the page (either to other link/website or closing window/tab) I want to show the onbeforeunload handeler saying we have a great offer for you? and if user choose to leave the page it should do the normal propogation but if he choose to stay on the page I need him to redirect it to offer page redirection is important, no compromise. For testing lets redirect to google.com
I made a program as follows -
var stayonthis = true;
var a;
function load() {
window.onbeforeunload = function(e) {
if(stayonthis){
a = setTimeout('window.location.href="http://google.com";',100);
stayonthis = false;
return "Do you really want to leave now?";
}
else {
clearTimeout(a);
}
};
window.onunload = function(e) {
clearTimeout(a);
};
}
window.onload = load;
but the problem is that if he click on the link to yahoo.com and choose to leave the page he is not going to yahoo but to google instead :(
Help Me !! Thanks in Advance
here is the fiddle code
here how you can test because onbeforeunload does not work on iframe well
This solution works in all cases, using back browser button, setting new url in address bar or use links.
What i have found is that triggering onbeforeunload handler doesn't show the dialog attached to onbeforeunload handler.
In this case (when triggering is needed), use a confirm box to show the user message. This workaround is tested in chrome/firefox and IE (7 to 10)
http://jsfiddle.net/W3vUB/4/show
http://jsfiddle.net/W3vUB/4/
EDIT: set DEMO on codepen, apparently jsFiddle doesn't like this snippet(?!)
BTW, using bing.com due to google not allowing no more content being displayed inside iframe.
http://codepen.io/anon/pen/dYKKbZ
var a, b = false,
c = "http://bing.com";
function triggerEvent(el, type) {
if ((el[type] || false) && typeof el[type] == 'function') {
el[type](el);
}
}
$(function () {
$('a:not([href^=#])').on('click', function (e) {
e.preventDefault();
if (confirm("Do you really want to leave now?")) c = this.href;
triggerEvent(window, 'onbeforeunload');
});
});
window.onbeforeunload = function (e) {
if (b) return;
a = setTimeout(function () {
b = true;
window.location.href = c;
c = "http://bing.com";
console.log(c);
}, 500);
return "Do you really want to leave now?";
}
window.onunload = function () {
clearTimeout(a);
}
It's better to Check it local.
Check out the comments and try this: LIVE DEMO
var linkClick=false;
document.onclick = function(e)
{
linkClick = true;
var elemntTagName = e.target.tagName;
if(elemntTagName=='A')
{
e.target.getAttribute("href");
if(!confirm('Are your sure you want to leave?'))
{
window.location.href = "http://google.com";
console.log("http://google.com");
}
else
{
window.location.href = e.target.getAttribute("href");
console.log(e.target.getAttribute("href"));
}
return false;
}
}
function OnBeforeUnLoad ()
{
return "Are you sure?";
linkClick=false;
window.location.href = "http://google.com";
console.log("http://google.com");
}
And change your html code to this:
<body onbeforeunload="if(linkClick == false) {return OnBeforeUnLoad()}">
try it
</body>
After playing a while with this problem I did the following. It seems to work but it's not very reliable. The biggest issue is that the timed out function needs to bridge a large enough timespan for the browser to make a connection to the url in the link's href attribute.
jsfiddle to demonstrate. I used bing.com instead of google.com because of X-Frame-Options: SAMEORIGIN
var F = function(){}; // empty function
var offerUrl = 'http://bing.com';
var url;
var handler = function(e) {
timeout = setTimeout(function () {
console.log('location.assign');
location.assign(offerUrl);
/*
* This value makes or breaks it.
* You need enough time so the browser can make the connection to
* the clicked links href else it will still redirect to the offer url.
*/
}, 1400);
// important!
window.onbeforeunload = F;
console.info('handler');
return 'Do you wan\'t to leave now?';
};
window.onbeforeunload = handler;
Try the following, (adds a global function that checks the state all the time though).
var redirected=false;
$(window).bind('beforeunload', function(e){
if(redirected)
return;
var orgLoc=window.location.href;
$(window).bind('focus.unloadev',function(e){
if(redirected==true)
return;
$(window).unbind('focus.unloadev');
window.setTimeout(function(){
if(window.location.href!=orgLoc)
return;
console.log('redirect...');
window.location.replace('http://google.com');
},6000);
redirected=true;
});
console.log('before2');
return "okdoky2";
});
$(window).unload(function(e){console.log('unloading...');redirected=true;});
<script>
function endSession() {
// Browser or Broswer tab is closed
// Write code here
alert('Browser or Broswer tab closed');
}
</script>
<body onpagehide="endSession();">
I think you're confused about the progress of events, on before unload the page is still interacting, the return method is like a shortcut for return "confirm()", the return of the confirm however cannot be handled at all, so you can not really investigate the response of the user and decide upon it which way to go, the response is going to be immediately carried out as "yes" leave page, or "no" don't leave page...
Notice that you have already changed the source of the url to Google before you prompt user, this action, cannot be undone... unless maybe, you can setimeout to something like 5 seconds (but then if the user isn't quick enough it won't pick up his answer)
Edit: I've just made it a 5000 time lapse and it always goes to Yahoo! Never picks up the google change at all.

Categories

Resources