Related
I want the user to be able to touch and hold a button, and after a certain period of time, a function is called.
E.g. the button text starts as black, turns orange after 0.2s of pressing, and then green after 0.5s of pressing. If it is green, a function, myFunction(), is triggered.
I have made a start on it, more help would be appreciated. Thanks :)
var btn = document.getElementById("pressBtn");
var pressedTime = 0;
var elaspedHoldTime;
btn.onmousedown = function() {
if (pressedTime != 0) {
pressedTime = performance.now();
} else {
elaspedHoldTime = performance.now() - pressedTime;
}
if (elaspedHoldTime > 200) {
btn.style.color = "orange";
}
if (elaspedHoldTime > 1000) {
btn.style.color = "green";
}
};
btn.addEventListener("mouseup", function() {
elaspedHoldTime = performance.now() - pressedTime;
btn.style.color = "black";
if (elaspedHoldTime > 500) {
console.log("Call Function Here");
}
pressedTime = 0;
elaspedHoldTime = 0;
});
<button id="btn">Button Text</button>
(It also has a bug for some reason)
UPDATED
for not fully functioanlity I edited the code and also changed the logic
I come up with variable timerValue which increases in every 0.1s when mouse is pressed and when that timerValue reaches 2, button changes color to orange and on 5 changes on red and prints triggered as well
and on mouseup which will be called after user picks up finger from mouse, timerValue backs to 0 and resets also button class
interval is variable where are I store setInterval function and on mouse release I clear it
I included also paragpraph tag where is shown the timer to understand how it works
const btn = document.querySelector(".btn")
const timer = document.querySelector("p") //can be deleted
let timerValue = 0
let interval;
const mousePress = () => {
interval = setInterval(() => {
timerValue++
timer.innerHTML = timerValue //can be deleted
if(timerValue === 2) btn.classList.toggle("orange")
if(timerValue === 5) {
btn.classList.toggle("red")
console.log("triggered")
}
}, 100)
}
const mouseRelease = () => {
clearInterval(interval)
timerValue = 0
timer.innerHTML = timerValue //can be deleted
btn.className = "btn"
}
btn.addEventListener("mousedown", mousePress)
btn.addEventListener("mouseup", mouseRelease)
.btn.orange{
color: orange;
}
.btn.red{
color: red;
}
<button class="btn">Click</button>
<p></p>
mousedown, mouseup, touchstart, touchend triggers just once when the key is pressed.
To check, if the user is still holding it, you can check for a truly variable inside a setTimeout() function-call, stop the timeout on release or use a setInterval()-function-call that only runs when it's pressed.
For example:
let pressed = false;
button.addEventListener("mousedown", () => {
pressed = true;
setTimeout(() => {
if (pressed) { ... }
}, 200);
});
button.addEventListener("mouseup", () => { pressed = false; });
let timer = null;
button.addEventListener("mousedown", () => {
pressed = true;
timer = setTimeout(() => { ... }, 200);
});
button.addEventListener("mouseup", () => { clearTimeout(timer) });
As there is already an answer with setTimeout(), here is another solution with setInterval().
let vars = {
interval: null, // used to store the interval id
start: 0, // changes to Date.now() on every start.
// used to avoid myFunction be called more than once per "hold"
myFunctionCalled: false
}, myFunction = () => console.log("Yes...?");
button.addEventListener("mousedown", (event) => {
// avoid start w/ rightclick
if (event.which == 1) {
vars.start = Date.now();
vars.myFunctionCalled = false;
vars.interval = setInterval(() => {
let dur = Date.now() - vars.start;
if (dur > 1000) {
button.style.color = "green";
if (!vars.myFunctionCalled) {
vars.myFunctionCalled = true;
myFunction();
}
} else if (dur > 500) {
button.style.color = "orange";
} else if (dur > 100) {
button.style.color = "red";
}
}, 10);
}
});
// using window, so the user can move the mouse
window.addEventListener("mouseup", (event) => {
// checking again for the mouse key, to avoid disabling it on rightlick
if (vars.interval && event.which == 1) {
// stop the interval and reset the color to default
clearInterval(vars.interval);
button.style.color = "";
vars.interval = null;
}
})
<button id="button">Hold me</button>
If you're making it for a touchscreen, you need to use TouchEvents:
ontouchstart -> when a target is being pressed by a finger
ontouchmove -> the active finger moves off the target
ontouchcancel -> when the the target has lost focus of a touch event
ontouchend -> lifting the finger off of the target
MouseEvents are reserved for mouse / trackpad-controlled devices, such as Computers.
TouchEvents are reserved for touch-screen devices, such as tablets and phones.
Also read this answer for code.
I have a button that disappears by a function after one second.
if I click on the button, I want the function will reset and I will get one another second to click. And-I want the button will disappeared if I did not click this second.
(if I click in a second, the button doesn't disappeared, if I miss one second, it is disappeared, but if I click, I'll get another second, and so on...)
This is my code:
HTML:
<button id="btn">click
</button>
JavaScript:
let btn = document.querySelector('#btn');
btn.addEventListener('click', ()=>{
click();
})
setTimeout(function click() {
btn.style.display = ('none');
}, 1000);
That code doesn't work.
I am an absolute beginner, so any feedback will help me.
If my question is not understood, please write to me in the comments or edit the question.
This is my suggestion:
var c = 10;
var timer;
clock();
function clock() {
timer = setInterval(countdown, 1000);
}
function countdown() {
counter.innerHTML = --c;
if (c === 0) {
btn.style.display = 'none';
clearInterval(timer);
}
}
btn.onclick = function() {
clearInterval(timer);
c = 10;
counter.innerHTML = c;
clock();
};
<button id="btn">Click me before it's too late (<span id="counter">10</span>)</button>
Change your javascript to the following:
let btn = document.querySelector('#btn');
btn.addEventListener('click', ()=>{
click();
})
function click() {
setTimeout(function() {
btn.style.display = 'none';
}, 1000);
}
Click was not defined properly :)
You should try jQuery, it'll make your learning a lot easier!
Also press f12 on Google Chrome to show developer console, errors will show up there.
You need to apply the display:none inside setTimeout. Here is an example.
let btn = document.querySelector('#btn');
let time = document.querySelector('#time');
const timeLimit = 10;
let timeoutId, intervalId;
time.innerText = timeLimit;
let startTime;
window.onload = () => {
startTime = Date.now();
startTimer();
removeButton();
}
btn.addEventListener('click', stop);
function stop() {
intervalId && clearInterval(intervalId);
timeoutId && clearTimeout(timeoutId);
}
function startTimer() {
let count = 1;
intervalId = setInterval(() => {
if(count === 10) clearInterval(intervalId);
time.innerText = timeLimit - count;
count++;
}, 1000);
}
function removeButton() {
timeoutId = setTimeout(() => {
btn.style.display = 'none';
}, timeLimit*1000);
}
<button id="btn">Click me. I am disappearing ⏳ <span id="time"></span></button>
How do I pause and resume the setInterval() function using Javascript?
For example, maybe I have a stopwatch to tell you the number of seconds that you have been looking at the webpage. There is a 'Pause' and 'Resume' button. The reason why clearInterval() would not work here is because if the user clicks on the 'Pause' button at the 40th second and 800th millisecond, when he clicks on the 'Resume' button, the number of seconds elapsed must increase by 1 after 200 milliseconds. If I use the clearInterval() function on the timer variable (when the pause button is clicked) and then using the setInterval() function on the timer variable again (when the resume button is clicked), the number of seconds elapsed will increase by 1 only after 1000 milliseconds, which destroys the accuracy of the stopwatch.
So how do I do that?
You could use a flag to keep track of the status:
var output = $('h1');
var isPaused = false;
var time = 0;
var t = window.setInterval(function() {
if(!isPaused) {
time++;
output.text("Seconds: " + time);
}
}, 1000);
//with jquery
$('.pause').on('click', function(e) {
e.preventDefault();
isPaused = true;
});
$('.play').on('click', function(e) {
e.preventDefault();
isPaused = false;
});
h1 {
font-family: Helvetica, Verdana, sans-serif;
font-size: 12px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Seconds: 0</h1>
<button class="play">Play</button>
<button class="pause">Pause</button>
This is just what I would do, I'm not sure if you can actually pause the setInterval.
Note: This system is easy and works pretty well for applications that don't require a high level of precision, but it won't consider the time elapsed in between ticks: if you click pause after half a second and later click play your time will be off by half a second.
You shouldn't measure time in interval function. Instead just save time when timer was started and measure difference when timer was stopped/paused. Use setInterval only to update displayed value. So there is no need to pause timer and you will get best possible accuracy in this way.
While #Jonas Giuro is right when saying that:
You cannot PAUSE the setInterval function, you can either STOP it (clearInterval), or let it run
On the other hand this behavior can be simulated with approach #VitaliyG suggested:
You shouldn't measure time in interval function. Instead just save time when timer was started and measure difference when timer was stopped/paused. Use setInterval only to update displayed value.
var output = $('h1');
var isPaused = false;
var time = new Date();
var offset = 0;
var t = window.setInterval(function() {
if(!isPaused) {
var milisec = offset + (new Date()).getTime() - time.getTime();
output.text(parseInt(milisec / 1000) + "s " + (milisec % 1000));
}
}, 10);
//with jquery
$('.toggle').on('click', function(e) {
e.preventDefault();
isPaused = !isPaused;
if (isPaused) {
offset += (new Date()).getTime() - time.getTime();
} else {
time = new Date();
}
});
h1 {
font-family: Helvetica, Verdana, sans-serif;
font-size: 12px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>Seconds: 0</h1>
<button class="toggle">Toggle</button>
Why not use a simpler approach? Add a class!
Simply add a class that tells the interval not to do anything. For example: on hover.
var i = 0;
this.setInterval(function() {
if(!$('#counter').hasClass('pauseInterval')) { //only run if it hasn't got this class 'pauseInterval'
console.log('Counting...');
$('#counter').html(i++); //just for explaining and showing
} else {
console.log('Stopped counting');
}
}, 500);
/* In this example, I'm adding a class on mouseover and remove it again on mouseleave. You can of course do pretty much whatever you like */
$('#counter').hover(function() { //mouse enter
$(this).addClass('pauseInterval');
},function() { //mouse leave
$(this).removeClass('pauseInterval');
}
);
/* Other example */
$('#pauseInterval').click(function() {
$('#counter').toggleClass('pauseInterval');
});
body {
background-color: #eee;
font-family: Calibri, Arial, sans-serif;
}
#counter {
width: 50%;
background: #ddd;
border: 2px solid #009afd;
border-radius: 5px;
padding: 5px;
text-align: center;
transition: .3s;
margin: 0 auto;
}
#counter.pauseInterval {
border-color: red;
}
<!-- you'll need jQuery for this. If you really want a vanilla version, ask -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="counter"> </p>
<button id="pauseInterval">Pause</button></p>
I've been looking for this fast and easy approach for ages, so I'm posting several versions to introduce as many people to it as possible.
i wrote a simple ES6 class that may come handy.
inspired by https://stackoverflow.com/a/58580918/4907364 answer
export class IntervalTimer {
callbackStartTime;
remaining = 0;
paused = false;
timerId = null;
_callback;
_delay;
constructor(callback, delay) {
this._callback = callback;
this._delay = delay;
}
pause() {
if (!this.paused) {
this.clear();
this.remaining = new Date().getTime() - this.callbackStartTime;
this.paused = true;
}
}
resume() {
if (this.paused) {
if (this.remaining) {
setTimeout(() => {
this.run();
this.paused = false;
this.start();
}, this.remaining);
} else {
this.paused = false;
this.start();
}
}
}
clear() {
clearInterval(this.timerId);
}
start() {
this.clear();
this.timerId = setInterval(() => {
this.run();
}, this._delay);
}
run() {
this.callbackStartTime = new Date().getTime();
this._callback();
}
}
usage is pretty straightforward,
const interval = new IntervalTimer(console.log('aaa'), 3000);
interval.start();
interval.pause();
interval.resume();
interval.clear();
My simple way:
function Timer (callback, delay) {
let callbackStartTime
let remaining = 0
this.timerId = null
this.paused = false
this.pause = () => {
this.clear()
remaining -= Date.now() - callbackStartTime
this.paused = true
}
this.resume = () => {
window.setTimeout(this.setTimeout.bind(this), remaining)
this.paused = false
}
this.setTimeout = () => {
this.clear()
this.timerId = window.setInterval(() => {
callbackStartTime = Date.now()
callback()
}, delay)
}
this.clear = () => {
window.clearInterval(this.timerId)
}
this.setTimeout()
}
How to use:
let seconds = 0
const timer = new Timer(() => {
seconds++
console.log('seconds', seconds)
if (seconds === 8) {
timer.clear()
alert('Game over!')
}
}, 1000)
timer.pause()
console.log('isPaused: ', timer.paused)
setTimeout(() => {
timer.resume()
console.log('isPaused: ', timer.paused)
}, 2500)
function Timer (callback, delay) {
let callbackStartTime
let remaining = 0
this.timerId = null
this.paused = false
this.pause = () => {
this.clear()
remaining -= Date.now() - callbackStartTime
this.paused = true
}
this.resume = () => {
window.setTimeout(this.setTimeout.bind(this), remaining)
this.paused = false
}
this.setTimeout = () => {
this.clear()
this.timerId = window.setInterval(() => {
callbackStartTime = Date.now()
callback()
}, delay)
}
this.clear = () => {
window.clearInterval(this.timerId)
}
this.setTimeout()
}
The code is written quickly and did not refactored, raise the rating of my answer if you want me to improve the code and give ES2015 version (classes).
I know this thread is old, but this could be another solution:
var do_this = null;
function y(){
// what you wanna do
}
do_this = setInterval(y, 1000);
function y_start(){
do_this = setInterval(y, 1000);
};
function y_stop(){
do_this = clearInterval(do_this);
};
The following code, provides a precision way to pause resume a timer.
How it works:
When the timer is resumed after a pause, it generates a correction cycle using a single timeout, that will consider the pause offset (exact time when the timer was paused between cycles). After the correction cycle finishes, it schedules the following cycles with a regular setInteval, and continues normally the cycle execution.
This allows to pause/resume the timer, without losing the sync.
Code :
function Timer(_fn_callback_ , _timer_freq_){
let RESUME_CORRECTION_RATE = 2;
let _timer_statusCode_;
let _timer_clockRef_;
let _time_ellapsed_; // will store the total time ellapsed
let _time_pause_; // stores the time when timer is paused
let _time_lastCycle_; // stores the time of the last cycle
let _isCorrectionCycle_;
/**
* execute in each clock cycle
*/
const nextCycle = function(){
// calculate deltaTime
let _time_delta_ = new Date() - _time_lastCycle_;
_time_lastCycle_ = new Date();
_time_ellapsed_ += _time_delta_;
// if its a correction cicle (caused by a pause,
// destroy the temporary timeout and generate a definitive interval
if( _isCorrectionCycle_ ){
clearTimeout( _timer_clockRef_ );
clearInterval( _timer_clockRef_ );
_timer_clockRef_ = setInterval( nextCycle , _timer_freq_ );
_isCorrectionCycle_ = false;
}
// execute callback
_fn_callback_.apply( timer, [ timer ] );
};
// initialize timer
_time_ellapsed_ = 0;
_time_lastCycle_ = new Date();
_timer_statusCode_ = 1;
_timer_clockRef_ = setInterval( nextCycle , _timer_freq_ );
// timer public API
const timer = {
get statusCode(){ return _timer_statusCode_ },
get timestamp(){
let abstime;
if( _timer_statusCode_=== 1 ) abstime = _time_ellapsed_ + ( new Date() - _time_lastCycle_ );
else if( _timer_statusCode_=== 2 ) abstime = _time_ellapsed_ + ( _time_pause_ - _time_lastCycle_ );
return abstime || 0;
},
pause : function(){
if( _timer_statusCode_ !== 1 ) return this;
// stop timers
clearTimeout( _timer_clockRef_ );
clearInterval( _timer_clockRef_ );
// set new status and store current time, it will be used on
// resume to calculate how much time is left for next cycle
// to be triggered
_timer_statusCode_ = 2;
_time_pause_ = new Date();
return this;
},
resume: function(){
if( _timer_statusCode_ !== 2 ) return this;
_timer_statusCode_ = 1;
_isCorrectionCycle_ = true;
const delayEllapsedTime = _time_pause_ - _time_lastCycle_;
_time_lastCycle_ = new Date( new Date() - (_time_pause_ - _time_lastCycle_) );
_timer_clockRef_ = setTimeout( nextCycle , _timer_freq_ - delayEllapsedTime - RESUME_CORRECTION_RATE);
return this;
}
};
return timer;
};
let myTimer = Timer( x=> console.log(x.timestamp), 1000);
<input type="button" onclick="myTimer.pause()" value="pause">
<input type="button" onclick="myTimer.resume()" value="resume">
Code source :
This Timer is a modified and simplified version of advanced-timer, a js library created by myself, with many more functionalities.
The full library and documentation is available in NPM and GITHUB
let time = document.getElementById("time");
let stopButton = document.getElementById("stop");
let timeCount = 0,
currentTimeout;
function play() {
stopButton.hidden = false;
clearInterval(currentTimeout);
currentTimeout = setInterval(() => {
timeCount++;
const min = String(Math.trunc(timeCount / 60)).padStart(2, 0);
const sec = String(Math.trunc(timeCount % 60)).padStart(2, 0);
time.innerHTML = `${min} : ${sec}`;
}, 1000);
}
function pause() {
clearInterval(currentTimeout);
}
function stop() {
stopButton.hidden = true;
pause();
timeCount = 0;
time.innerHTML = `00 : 00`;
}
<div>
<h1 id="time">00 : 00</h1>
<br />
<div>
<button onclick="play()">play</button>
<button onclick="pause()">pause</button>
<button onclick="stop()" id="stop" hidden>Reset</button>
</div>
</div>
I have subscribed to more than 300 Youtube channels in past 10 years, and now I have to clean my Youtube, unsubscribing all one by one will take some time, is there a way to unsubscribe all the cannels at once?
Step 1: Go to https://www.youtube.com/feed/channels and scroll to the bottom of the page to populate all items to the screen.
Step 2: Right-click anywhere on the page and click "Inspect Element" (or just "Inspect"), then click "Console", then copy–paste the below script, then hit return.
Step 3:
var i = 0;
var myVar = setInterval(myTimer, 3000);
function myTimer () {
var els = document.getElementById("grid-container").getElementsByClassName("ytd-expanded-shelf-contents-renderer");
if (i < els.length) {
els[i].querySelector("[aria-label^='Unsubscribe from']").click();
setTimeout(function () {
var unSubBtn = document.getElementById("confirm-button").click();
}, 2000);
setTimeout(function () {
els[i].parentNode.removeChild(els[i]);
}, 2000);
}
i++;
console.log(i + " unsubscribed by YOGIE");
console.log(els.length + " remaining");
}
Step 4: Sit back and watch the magic!
Enjoy!!
NOTE: If the script stops somewhere, please refresh the page and follow all four steps again.
Updating the answer provided by everyone else (as the latest update did not work for me):
var i = 0;
var count = document.querySelectorAll("ytd-channel-renderer:not(.ytd-item-section-renderer)").length;
myTimer();
function myTimer () {
if (count == 0) return;
el = document.querySelector('.ytd-subscribe-button-renderer');
el.click();
setTimeout(function () {
var unSubBtn = document.getElementById("confirm-button").click();
i++;
count--;
console.log(i + " unsubscribed");
console.log(count + " remaining");
setTimeout(function () {
el = document.querySelector("ytd-channel-renderer");
el.parentNode.removeChild(el);
myTimer();
}, 250);
}, 250);
}
For me this did the trick.
Youtube Channel Unsubscriber (Works April-2020)
Access the link : https://www.youtube.com/feed/channels
Press F12
Insert the code below in your console
function youtubeUnsubscriber() {
var count = document.querySelectorAll("ytd-channel-renderer:not(.ytd-item-section-renderer)").length;
var randomDelay = 500;
if(count == 0) return false;
function unsubscribeVisible(randomDelay) {
if (count == 0) {
window.scrollTo(0,document.body.scrollHeight);
setTimeout(function() {
youtubeUnsubscriber();
}, 10000)
}
unsubscribeButton = document.querySelector('.ytd-subscribe-button-renderer');
unsubscribeButton.click();
setTimeout(function () {
document.getElementById("confirm-button").click()
count--;
console.log("Remaining: ", count);
setTimeout(function () {
unsubscribedElement = document.querySelector("ytd-channel-renderer");
unsubscribedElement.parentNode.removeChild(unsubscribedElement);
unsubscribeVisible(randomDelay)
}, randomDelay);
}, randomDelay);
}
unsubscribeVisible(randomDelay);
}
youtubeUnsubscriber();
References
https://github.com/vinnyfs89/youtube-unsubscriber
This is a little addition to the best answer:
You can also use jscompress[dot]com to compress the script, then add javascript: at the beginning of the script, and add it to your bookmarks — you can run it from there — just in case you're not comfortable using console or something like that.
Most effective values:
(copy all above this, including the last)
var i = 0;
var myVar = setInterval(myTimer, 200);
function myTimer () {
var els = document.getElementById("grid-container").getElementsByClassName("ytd-expanded-shelf-contents-renderer");
if (i < els.length) {
els[i].querySelector('[aria-label="Unsubscribe from this channel."]').click();
setTimeout(function () {
var unSubBtn = document.getElementById("confirm-button").click();
}, 500);
setTimeout(function () {
els[i].parentNode.removeChild(els[i]);
}, 1000);
}
i++;
console.log(i + " unsubscribed by YOGIE");
console.log(els.length + " remaining");
}
Updating MordorSlave answer. Just did it a moment ago.
Go to https://www.youtube.com/feed/channels and copy/paste the following in the console:
var i = 0;
var myVar = setInterval(myTimer, 200);
function myTimer() {
var els = document.getElementById("contents").getElementsByClassName("ytd-subscribe-button-renderer");
if (i < els.length) {
els[i].querySelector('.ytd-subscribe-button-renderer').click();
setTimeout(function() {
var unSubBtn = document.getElementById("confirm-button").click();
}, 500);
setTimeout(function() {
els[i].parentNode.removeChild(els[i]);
}, 1000);
}
i++;
console.log(i + " unsubscribed");
console.log(els.length + " remaining");
}
https://gist.github.com/itsazzad/c1d86c5db86258ca129554a7b9ed92a7
Use the DELAY const wisely; consider your net speed.
// Go to the following link in your YouTube: https://www.youtube.com/feed/channels
// Scroll the page all the way down until you reach the very last subscribed channel in your list
const DELAY = 100;
const delay = ms => new Promise(res => setTimeout(res, ms));
const list = document.querySelectorAll("#grid-container > ytd-channel-renderer");
for (const sub of list) {
await delay(DELAY);
sub.querySelector("#subscribe-button > ytd-subscribe-button-renderer > paper-button").click();
await delay(DELAY);
document.querySelector("#confirm-button > a").addEventListener('click', async event => {
await delay(DELAY);
console.log(sub.querySelector("#text").innerText);
await delay(DELAY);
});
await delay(DELAY);
document.querySelector("#confirm-button > a").click()
await delay(DELAY);
}
Go to https://www.youtube.com/feed/channels.
Scroll all the way down till you see the last subscribed channel.
Open the javascript console, paste the following code and hit enter
let btns = document.querySelectorAll('paper-button > yt-formatted-string');
for (let i = 0; i < btns.length; i += 1) {
if (btns[i].innerText.toLowerCase() === 'subscribed') {
btns[i].click();
document.getElementById('confirm-button').click();
}
}
Note: For me this method worked on Firefox. Chrome was giving warnings and the page became unresponsive. Worked on Oct 20th 2020 for an account with 956 subscribed channels.
Hmm, wish I'd googled before rolling out my own. I had some fun with async and await with this. The screen does some ugly flashing while it's trying to unsubscribe stuff, but this does the job pretty well.
One prerequisite for this script to catch all channels in one go is to "exhaust" the scroller in the page ie., keep scrolling until you reach the end of your channel list. As others have stated, head on over to YouTube Channels, open the developer console and paste the script that follows.
I've commented in relevant parts, in case this ends up becoming a learning experience for someone ;)
/**
* Youtube bulk unsubsribe fn.
* Wrapping this in an IIFE for browser compatibility.
*/
(async function iife() {
// This is the time delay after which the "unsubscribe" button is "clicked"; Tweak to your liking!
var UNSUBSCRIBE_DELAY_TIME = 2000
/**
* Delay runner. Wraps `setTimeout` so it can be `await`ed on.
* #param {Function} fn
* #param {number} delay
*/
var runAfterDelay = (fn, delay) => new Promise((resolve, reject) => {
setTimeout(() => {
fn()
resolve()
}, delay)
})
// Get the channel list; this can be considered a row in the page.
var channels = Array.from(document.getElementsByTagName(`ytd-channel-renderer`))
console.log(`${channels.length} channels found.`)
var ctr = 0
for (const channel of channels) {
// Get the subsribe button and trigger a "click"
channel.querySelector(`[aria-label^='Unsubscribe from']`).click()
await runAfterDelay(() => {
// Get the dialog container...
document.getElementsByTagName(`yt-confirm-dialog-renderer`)[0]
// and find the confirm button...
.querySelector(`#confirm-button`)
// and "trigger" the click!
.click()
console.log(`Unsubsribed ${ctr + 1}/${channels.length}`)
ctr++
}, UNSUBSCRIBE_DELAY_TIME)
}
})()
If someone is looking for a working solution, the following script worked for me:
Go to https://www.youtube.com/subscription_manager and run
$$('.yt-uix-button-subscribed-branded').forEach(function(el) { el.click(); $$('.overlay-confirmation-unsubscribe-button').forEach(function(el) { el.click(); }); console.log('Bye YouTube'); });
Ref: https://www.reddit.com/r/youtube/comments/ad3jv5/mass_unsubscribe_script/
My solution, most up to date i think, but things always changing...
var unsubBtns = document.querySelectorAll(' div:nth-child(2) > div:nth-child(2) > div:nth-child(2) > ytd-subscribe-button-renderer:nth-child(1) > paper-button:nth-child(1)');
var i = 0;
var interV = setInterval(function(){
unsubBtns[i].click();
i++;
document.querySelector('yt-formatted-string.style-blue-text').click()
}, 1000);
Extending on Jani's answer, this one has a DOM progress counter. Absolutely no jQuery.
(function() {
var i = 0;
var ytdElem = document.querySelector("ytd-page-manager ytd-browse.ytd-page-manager");
ytdElem.innerHTML = '<div style="font: 11pt arial; background: yellow; color: white" id="ytdjsds"></div>' + ytdElem.innerHTML;
var element = document.getElementById("ytdjsds");
var count = document.querySelectorAll("ytd-channel-renderer:not(.ytd-item-section-renderer)").length;
if (count == 0) {
element.innerHTML = "No subscriptions were found on your account.";
return;
}
element.innerHTML = `Deleting subscription 1 of ${count}`;
function myTimer() {
if (count == 0) {
element.innerHTML = `Successfully deleted subscriptions`;
return;
}
element.innerHTML = `Deleting subscription ${i + 1} of ${count}`;
el = document.querySelector('.ytd-subscribe-button-renderer');
el.click();
document.getElementById("confirm-button").style.display = "none";
setTimeout(function() {
var unSubBtn = document.getElementById("confirm-button").click();
i++;
setTimeout(function() {
el = document.querySelector("ytd-channel-renderer");
el.parentNode.removeChild(el);
myTimer();
}, 250);
}, 250);
}
myTimer();
})();
as of October 2021
from this page https://www.youtube.com/feed/channels
var list = $$('yt-formatted-string.ytd-subscribe-button-renderer')
function foo($$) {
if (list.length === 0) return
var el = list.pop()
el.click()
setTimeout(_=>{
var cancel = $$('yt-formatted-string.yt-button-renderer')[1]
cancel.click()
console.log('done')
setTimeout(_=>{foo($$)},100)
}, 100)
}
foo($$)
How we can check mouse holed some seconds on an element.
Means that the function should execute only if the user holds the mouse more than minimum seconds(eg:3 sec) on an element.
Many of the answers found in the stack, but that solutions are delaying the execution, but I want to check mouse holed or not, If yes, execute the function else don't make any action.
Already asked same question before, but not yet get the answer exactly what I looking
Is it possible?
I think you are looking for this, here if a div gets hover and hold mouse for at least 3 seconds then do your stuff like below
var myTimeout;
$('div').mouseenter(function() {
myTimeout = setTimeout(function() {
alert("do your stuff now");
}, 3000);
}).mouseleave(function() {
clearTimeout(myTimeout);
});
here's a custom jquery function for that
$.fn.mouseHover = function(time, callback){
var timer;
$(this).on("mouseover", function(e){
timer = setTimeout(callback.bind(this, e), time);
}.bind(this)).on("mouseout", function(e){
clearTimeout(timer);
})
};
$('#my-element').mouseHover(3000, function(){ alert("WHOOPWhOOP");});
just in case OP meant click and hold.
$.fn.mouseHold = function(time, callback) {
var timer;
$(this).on("mousedown", function(e){
e.preventDefault();
timer = setTimeout(callback.bind(this, e), time);
}.bind(this)).on("mouseup", function(e){
clearTimeout(timer);
})
}
jsfiddle: http://jsbin.com/huhagiju/1/
Should be easy enough:
$('.your-element').on('mousedown', function(event) {
var $that = $(this);
// This timeout will run after 3 seconds.
var t = setTimeout(function() {
if ($that.data('mouse_down_start') != null) {
// If it's not null, it means that the user hasn't released the click yet
// so proceed with the execution.
runMouseDown(event, $that);
// And remove the data.
$(that).removeData('mouse_down_start');
}
}, 3000);
// Add the data and the mouseup function to clear the data and timeout
$(this)
.data('mouse_down_start', true)
.one('mouseup', function(event) {
// Use .one() here because this should only fire once.
$(this).removeData('mouse_down_start');
clearTimeout(t);
});
});
function runMouseDown(event, $that) {
// do whatever you need done
}
Checkout
Logic
The mousedown handler records the click start time
The mouseup handler records the mouse up time and calculate time difference if it exceeds 3 secs then alerts the time else alerts less than 3 seconds
HTML
<p>Press mouse and release here.</p>
Jquery
var flag, flag2;
$( "p" )
.mouseup(function() {
$( this ).append( "<span style='color:#f00;'>Mouse up.</span>" );
flag2 = new Date().getTime();
var passed = flag2 - flag;
if(passed>='3000')
alert(passed);
else
alert("left before");
console.log(passed); //time passed in milliseconds
})
.mousedown(function() {
$( this ).append( "<span style='color:#00f;'>Mouse down.</span>" );
flag = new Date().getTime();
});
This is all about logic.
You just have a variable to tell you if you have been listening on this for some time like 3 seconds.
If you are listening for more than that, which is not possible since you should had reset it, so then reset it. Else you do your work.
var mySpecialFunc = function() { alert("go go go..."); };
var lastTime = 0;
var main_id = "some_id" ;// supply the id of a div over which to check mouseover
document.getElementById(main_id).addEventListener("mouseover",function(e) {
var currTime = new Date().getTime();
var diffTime = currTime - lastTime;
if(diffTime > 4000) {
// more than 4 seconds reset the lastTime
lastTime = currTime;
alert("diffTime " + diffTime);
return ;
}
if(diffTime > 3000) {
// user had mouseover for too long
lastTime = 0;
mySpecialFunc("info");
}
// else do nothing.
});
This is a basic code, i think you can improve and adjust according to your requirements.
Here's some code (with a fiddle) that does what you want...
(it also shows how bored I am tonight)
var props = {
1000: { color: 'red', msg: 'Ready' },
2000: { color: 'yellow', msg: 'Set' },
3000: { color: 'green' , msg: 'Go!' }
};
var handles = [];
var $d = $('#theDiv');
$d.mouseenter(function () {
$.each(props, function (k, obj) {
handles[k] = setTimeout(function () {
changeStuff($d, obj);
}, k);
});
}).mouseleave(function () {
$.each(handles, function (i, h) {
clearTimeout(h);
});
reset($d);
});
function reset($d) {
$d.css('backgroundColor', 'orange');
$d.text('Hover here...');
}
function changeStuff($node, o) {
$node.css('backgroundColor', o.color);
$node.text(o.msg);
}