GetElementby More Item - javascript

I use the VideoJS framework, i want know when the user pause the video. The video go to pause when i click on "Play button" and on video:
var vjs = document.getElementById("really-cool-video_html5_api"); // on video
var vjs = document.getElementById("really-cool-video").getElementsByClassName("vjs-play-control")[0]; // click button play
I with Listener, see if the user click on this "div" :
vjs.addEventListener("click", checkPause, false);
but it control only when i click on document.getElementById("really-cool-video").getElementsByClassName("vjs-play-control")[0] i want, both 2 div in my listener... I can't change the HTML and tell the div with the same name... How i can do a Listener of two elements?

You're probably better off using video.js's api to listen for pause events instead. There are ways to pause the video without clicking (keyboard control) and clicks that do not pause the video (play).
videojs('really-cool-video').on('pause', checkPause)

You have the same named variables your attaching listeners to. Try changing the second vjs to vjsBtn like so...
var vjsInnerBtn = document.getElementById("really-cool-video_html5_api"); // on video
var vjsPlayerBtn = document.getElementById("really-cool-video").getElementsByClassName("vjs-play-control")[0]; // click button play
Now you are free to accomplish this.
vjsInnerBtn.addEventListener("click", checkPause, false);
vjsPlayerBtn.addEventListener("click", checkPause, false);

I'm assuming jQuery is available to you, since you've tagged it. This makes things much easier for you, because you simply have to fill the selector with the elements you want the event handler attached to:
$('#really-cool-video_html5_api, #really-cool-video .vjs-play-control').on('click', checkPause);
Note, this still adds multiple event handlers, this must be done if you want the same functionality triggered from a click on two different elements.

have you considers store them in an array? like
var controls['video'] = document.getElementById("really-cool-video_html5_api"); // on video
controls['pause_btn'] = document.getElementById("really-cool-video").getElementsByClassName("vjs-play-control")[0];
//Here you add the addEvenListener with the array elements.
is the same approach to using different variables but you can iterate them if you want to attach them same event listener or use a function for that

Related

Adding custom event to programatically open contextmenu

As said in the title, I am trying to customize the contextmenu event. The situation is this: I want to catch the event, preventing it from firing on some elements (I'm ok here, all good), then I want to call it targeting another element (this is not working). At first I just tried dispatching it by creating a custom event and using myTargetElement.dispatchEvent(), the custom element does fire, but context menu won't open.
The reason I need this is that I want to open the contenteditable context menu when the user clicks anywhere. I've tried something similar to the last example on this MDN page, and I logged the event type, it is firing. Here's some example code of what I'm doing.
HTML
<div id="prevent">This div will prevent default event behaviour.</div>
<div id="my-target" contenteditable>Fire here the event and open context menu</div>
For instance, I cannot put one div inside the other.
JS
function showMenu(){
const preventer = document.getElementById('prevent');
const myTarget = document.getElementById('my-target');
const myEvent = new Event('contextmenu', {
bubbles:false //I had to use this, as setting it true was logging an error on Firefox
});
myTarget.dispatchEvent(myEvent);
console.log(myEvent.type); //it does log the event name
}
The listener that prevents default is not important, as when I just run the showMenu() (even when removing every other bit of js) on console it still has not the intended effect. I'm also able to listen to the 'contextmenu' event when I add a listener and run showMenu().
I'm beginning to think that there is not a direct solution to this, but workarounds and ideas would be really appreciated.

Looking for Javascript / jQuery Event trigger

I have got a javascript based menu generator that is from an external source. The menu functionality occurs via a click event bound to a specific ID... pretty standard.
What I want to do is perform another action on the DOM AFTER that click event fires.
I would rather not hack the code that came in the menu package.
I tried attaching my own click handler - but there isn't an obvious way of ensuring my click handler fires AFTER the menu system's handler. One approach I considered was basing an event on the addition/removal of a class that occurs with the menu system's click handler. But - I quickly found that there is no event based on the change of class on an element (that I know of).
Any ideas? (without hacking the original menu system's js)
You can use the javascirpt Mutation Observer, here is a great article about the subject : Listening to the DOM changes with MutationObserver
OR in an old fashion
If I understand, (1) you can add your own click event listener, (2) you want execute your code after a class name change on the menu element.
In that case, you can use a setInterval to check if the class has changed and if so, trigger your action.
Something like that :
myOnClickFunction(){
var menu = document.querySelector('#MyMenuID');
var timer = setInterval(() => {
if(menu.classList.contains('TheClassNameYouWantToCheck')){
//Clear the interval
clearInterval(timer);
//Execute your actions here
}
}, 50);
//You can also add a maximum checking time
//after 5 seconds the function stop checking for changes
setTimeout(()=>clearInterval(timer), 5000);
}

Removing a listener class doesn't stop a sound event associated Jquery Javascript

I'm playing a sound when hovering on an image (this is working fine already) and want to include a button to turn this off if desired. Unfortunately I haven't been able to make it work.
My current code goes like:
For creating the sound
//a bunch of code to generate the audio that ends on
var mouseoversound = createsoundbite('mysound.mp3')
For triggering it
$(".play").mouseover(function() {
mouseoversound.play();
});
The listener element
<%= image_tag "image.png", class:'logo-image play' %>
I thought that the simplest solution for disabling it was to remove the class 'listening' for the event (i.e. '.play') in the element listener, so I tired:
$(".sound").click(function(){
$(".logo-image").removeClass("play");
});
//.sound is the class of the button that's intended to block it.
Although the latter script does successfully remove the class 'play' the sound keeps playing every time I hover over the image. What am I missing? shouldn't the sound just stop playing?
Do you see any other solution to this?
Cheers
The issue is because the event handler is bound to the element. Removing the class after the event is bound does not affect that binding. To affect the event handler, you can call off(), like this:
$(".sound").click(function(){
$(".logo-image").off('mouseover');
});
Alternatively, if you want to toggle the sound functionality based on the class, you can keep your current logic and check that the element still has the class in the mouseover handler:
$(".logo-image").mouseover(function() {
if ($(this).hasClass('play') {
mouseoversound.play();
}
});
$(".sound").click(function(){
$(".logo-image").toggleClass("play");
});

onclick element for an element that is not created yet

I am using the google search API and I want that when you click on an image, this image will be copied to a different location.
I created a fiddle here: http://fiddle.jshell.net/wjewg062/
It works this way: The user types in a term in the input field and images will be displayed. When he/she clicks on one twice it will displayed in the image div.
I put the onClick event listener on to the searchresults div, hence the extra click in the beginning. However, I want it to be displayed on the first click.
Now, if I comment this out
var searchresults = document.getElementById('searchresults');
searchresults.addEventListener("click", function(event){
event.preventDefault();
imageing();
});
it doesn't work. The images will be links. I believe the reason for this is that the results are displayed in gs-image-box and not created yet. I tried calling the imaging function in different other functions like the searchImg or the OnLoad but nothing work.
I thought of using a check if element is clicked function described here Detect if I'm clicking an element within an element
but I think there must be an easier way.
I'm running out of ideas, can anyone give an idea or hint?
Thanks !
The images are dynamically created right? Check out this post Event binding on dynamically created elements?
In short, events are attached to elements upon pageload. so a newly created dynamic element such as the ones that google creates, aren't attached to the event. so google probably has a way to circumvent the whole "you need to load the page to attach events to elements" thing but it requires an extra click. Using the syntax found in the post should help you.
By the way. Using Jquery doesn't really show down your site because it's usually cached in the client's browser.
The info you need is already in your searchresults eventListener. The target of this event will be the image you click, even if you add the event on a div higher in the structure.
A javascript event will by default be dispatched from the top element (window) all the way through the element that received the click, then will go back to the top. Any element that is an ancestor of the element that was clicked will receive the event info, so you can listen on any ancestor, but the target remains the element that was actually clicked.
In your case, by simply passing the target to your imageing() function, you can apply the behaviors you want without any extra manipulations.
One problem you might face, is if user clicks on searchresult but not on an img element. Then you'll have a bug, so you should handle these cases.
Something like this:
var searchresults = document.getElementById('searchresults');
searchresults.addEventListener("click", function (event) {
console.log(event.target, this);
event.preventDefault();
if(event.target.tagName == 'IMG'){
imageing(event.target);
}
});
function imageing(targetImg) {
var imageresult = document.getElementsByClassName('gs-image-box');
var xu = document.getElementById('companylogo');
var imgsrc = targetImg.src;
xu.src = imgsrc;
}
http://fiddle.jshell.net/pwjLrfnt/3/

Delegated event triggering even when it shouldn't

I have the following code:
// Define controls
$('.play-video').click(function(){
// Get the video element
var video = $(this).parent().parent().find('video');
// Play the video
$(video).get(0).play()
// Remove the play class and add the pause class so the same button will pause the video
$(this).removeClass('play-video');
$(this).addClass('pause-video');
// Set pause text
$(this).text('Pause');
});
$(document).on('click','.pause-video',function(){
console.log('pausing...');
// Get the video element
var video = $(this).parent().parent().find('video');
// Play the video
$(video).get(0).pause()
// Remove the play class and add the pause class so the same button will pause the video
$(this).removeClass('pause-video');
$(this).addClass('play-video');
// Set pause text
$(this).text('Play');
});
Problem is, that the second click event should trigger on .pause-video only but also triggers on .play-video
Question is: What did I do wrong?
Thanks in advance,
G3
You've attached the "play" event handler directly to the button instead of using delegation. That handler will continue to fire because of that, even if you change the class.
Delegation works through event bubbling, and the selector you pass in to the .on() call is re-examined with every event. That is not the case with handlers that are directly attached: once those are active, they're active until they're removed or until the DOM element itself is removed. Changing the particulars of the DOM element won't make a difference.
Your problem can therefore be solved by using delegation for both cases.
Your code is close. but your first event handler also needs to be delegated too:
$(document).on('click', '.play-video', click(function(){
try to stop immediage propagation $('.play-video').click
The problem is that jQuery can't track object changes on the fly. Just use one click event, and determine what to do inside this:
$('.play-stop-video').click(function(){
if($(this).hasClass('play')) {
// Current play button code here....
}
if($(this).hasClass('stop')) {
// Current stop button code here....
}
$(this).toggleClass('play').toggleClass('stop');
});
$(something).click( ... will runs when the page loads, and attach the click events to the play and stop buttons. However, you don't have any stop buttons at this time, so the click event for this will be discarded...

Categories

Resources