I have a JavaScript code snippet "Code Snippet 1 - that plays html videos loaded via Ajax on Users Touch Interaction" that uses the on('touchstart')
jQuery method to attach event Listeners. I need to be able to Toggle the event Listeners on and off or remove and rebind them. The problem that I am having is the on('touchstart')
method continues to call the function (plays all videos on page) each user interactions.
I need the event Listener to call the functions on the initial touch interaction, then disable, until ajax loads more content "Videos". After each Ajax Success I would like to rebind/re-add the event Listener, so the function works again.
Code Snippet 1
function videoEvents2() {
Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
get: function() {
return !!(this.currentTime > 0 && !this.paused && !this.ended && this.readyState > 2);
}
});
$(document).on('click', 'body', playVideoOnLowPower);
$(document).on('touchstart', 'body', playVideoOnLowPower);
function playVideoOnLowPower() {
try {
const videoElements = document.querySelectorAll("video");
for (i = 0; i < videoElements.length; i++) {
if (videoElements[i].playing) {
// video is already playing so do nothing
console.log('Playing');
} else {
// video is not playing so play video now
videoElements[i].play();
console.log('Not Playing');
}
}
} catch (err) {
console.log(err);
}
}
}
I've already tried the following solutions with no success.
Attempt 1. Adding Boolean Attribute {once: true}
to the eventlistener, but it did not provided the desired results. The Boolean attribute will only allow the functions to execute once.
Attempt 2.I used the one()
instead of on()
method for the eventlistener, however it provides the same results as {once : true}
Attempt 3. I've tried the document.body.addEventListener
& document.body.removeEventListener
method with the eventListeners reformatted like this "See Code Snippet Below this paragraph", however the "removeEventListener" method executes immediately instead of when the function is called.
document.body.addEventListener("click", playVideoOnLowPower, {
once: true
});
document.body.addEventListener("touchstart", playVideoOnLowPower, {
once: true
});
function dsdvideoEvents3 {
document.body.removeEventListener("click", playVideoOnLowPower, {
once: true
});
document.body.removeEventListener("touchstart", playVideoOnLowPower, {
once: true
});
}
Attempt 4. I'm currently researching more Boolean Attributes, the Unbind & Rebind Methods, Delegation Methods, SetTimOut, and SetInterval methods, but I have not had any success.
Create a flag which hold the count of click for example here I have created var clickCount = 0;
and increase it when you call playVideoOnLowPower()
and reset it to 0 on ajaxCall
success. Also check the clickCount
value in playVideoOnLowPower
method, if it is more than 0 return without doing anything otherwise execute your logic. See the following example.
var clickCount = 0;
Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
get: function() {
return !!(this.currentTime > 0 && !this.paused && !this.ended && this.readyState > 2);
}
});
document.body.addEventListener("click", playVideoOnLowPower);
document.body.addEventListener("touchstart", playVideoOnLowPower);
function playVideoOnLowPower() {
try {
if (clickCount > 0) {
return;
}
clickCount = 1;
const videoElements = document.querySelectorAll("video");
for (i = 0; i < videoElements.length; i++) {
if (videoElements[i].playing) {
// video is already playing so do nothing
console.log('Playing');
} else {
// video is not playing so play video now
videoElements[i].play();
console.log('Not Playing');
}
}
} catch (err) {
console.log(err);
}
}
$("#getVideo").off("click").on("click", function() {
getVideo()
});
function getVideo() {
$.ajax({
url: 'https://dummyjson.com/http/200/mov_bbb.mp4',
success: function(data) {
if (data.status == 200) {
var videoHtml = `<video width="400" controls>
<source src="https://www.w3schools.com/html/${data.message}" type="video/mp4">
</video>`;
}
$('#main2').append(videoHtml);
videoEvents();
clickCount = 0;
}
});
}
function videoEvents() {
$("video").on('play', function() {
$(this).prop('muted', false);
});
$("video").on('pause', function() {
$(this).prop('muted', true);
});
$("video").on('ended', function() {
$(this).prop('muted', true);
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main2"></div>
<button id="getVideo">Add next video</button>