I want to know some detailed knowledge about HTML element event mechanism.
For example, we are calling javascript method in HTML's event attributes. How this event attributes handling this events internally.
First, it's about JavaScript API implemented into the browser and not the other way around. While you can either use the onclick="doSomeStuff()" attribute (see examples below), or the addEventListener method, now all methods allow you to bind the handler to an element but there are some little differences.
Method 1 - define your button with onclick attribute then define the handler
You can simply hook a handler to your HTMLElement like so, with the onclick attribute:
<button id="myButton" onclick="doSomeStuff()" type="button">
Click <span class="my-child-selector">ME</span>
</button>
<script>
function doSomeStuff(){
element.innerHTML = 'CLICKED ELEMENT';
}
</script>
The <script> tag must always come second, as we don't use DOMContentLoaded event (jQuery(document).ready(callback)). Notice we don't have access to the event object using this method.
Method 2 - define the onclick attribute via JavaScript
Sometimes we write like this, it's a little better way:
<button id="myButton" type="button">
Click <span class="my-child-selector">ME</span>
</button>
<script>
// elements
var element = document.getElementById('myButton'),
child = element.querySelector('.my-child-selector');
function doSomeStuff(event) {
// we have access to the event object
// get to know the event target
var target = event.target;
// respond only when the button element is clicked
if (target === element) {
element.innerHTML = 'CLICKED ELEMENT';
// or delegate to a child
} else if (target.parentNode === element) {
element.innerHTML = 'CLICKED CHILD';
}
}
// add listener to your element
element.onclick = doSomeStuff;
// alternativelly you can also write an anonymous function
// element.onclick = function(event){ /* do the stuff with event object access*/ };
</script>
Notice that we now HAVE access to the event object and we can properly delegate the handler.
Method 3 - define the button and attach handler via addEventListener
The new JavaScript API is a miles better way for performance, more flexibility and easier maintenance, basically the BEST way:
<button id="myButton" type="button">
Click <span class="my-child-selector">ME</span>
</button>
<script>
// elements
var element = document.getElementById('myButton'),
child = element.querySelector('.my-child-selector');
function doSomeStuff(event) {
// we have access to the event object
// get to know the event target
var target = event.target;
// respond only when the button element is clicked
if (target === element) {
element.innerHTML = 'CLICKED ELEMENT';
// or delegate to a child
} else if (target.parentNode === element) {
element.innerHTML = 'CLICKED CHILD';
}
}
// add listener to your element
element.addEventListener('click', doSomeStuff, false);
</script>
As an alternative to this method, you can also create an anonymous function as the handler, for unique use cases, when you want a certain behavior for a very specific element.
// add listener to your element
myUniqueElement.addEventListener('click', function (event){
// do some stuff with access to event object
}, false);
This is just about everything you need to know about handling and delegating events, but feel free to ask anything if you're not certain of something.
Related
What is the difference between click in
document.getElementById("myBtn").addEventListener("click", displayDate);
and onclick in
<!DOCTYPE html>
<html>
<body>
<h1 onclick="this.innerHTML='Ooops!'">Click on this text!</h1>
</body>
</html>
Are they both considered as events? Why can't we use click instead of onclick and visce versa?
The difference is that the first (click) is an event listener, and the second (onclick) is an event handler content attribute.
Event handler content attributes store an internal raw uncompiled handler, which produces an event listener via the event handler processing and getting the current value of the event handler algorithms.
In practice, this affects the scope, e.g.
(function() { var element = document.body;
var str = "console.log([typeof foo, typeof bar])";
var func = function() { console.log([typeof foo, typeof bar]); };
element.foo = 'foo';
var bar = 'bar';
element.setAttribute('onclick', str);
element.addEventListener('click', func);
element.click();
// Event handler content attribute logs ["string", "undefined"]
// Event listener logs ["undefined", "string"]
})();
I discourage using event handlers. They are an old reminiscence and are superseded by event listeners.
Yes, they are both events, simply put the same, and one use onclick when assign its handler inline, and the other click when assign using an event listener (which is the recommended way).
And you can't use them vice versa, as this is how it has to be done or they won't work.
Read more at MDN:
https://developer.mozilla.org/en-US/docs/Web/Events/click
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers
$("#profile-register #submit").click(function (e) {
e.preventDefault();
console.log("I executed")
})
successfully prevent the default the behavior,but code below can't
$("#profile-register #submit").onclick=function (e) {
e.preventDefault();
console.log("I executed")
}
it redirect the form with parameter,you can see it in the URL frame above
How to trigger multiple mouse-click events on arbitrarily many HTML elements covering each other?
I know you can use pointer-events: none; to let your click pass through your elements, but what if I want to trigger the mouse-click event on an element AND the mouse-click event on arbitrarily many other elements beneath it?
but what if I want to trigger the mouse-click event on an element AND the mouse-click event on arbitrarily many other elements beneath it?
Events bubble. Which means and event fired on an inner element, will also be received by the parent elements until the top most parent.
<div id="topmost">
<div id="second">
<p id="firstp"></p>
</div>
</div>
Assume you are using jquery. Below is how you would listen to click events from all elements below div.id="topmost".
Since the normal flow of events is for any click event (could be any other type of event) that is fired by any element with in the topmost div element will be bubbled to the outermost element, I only list to topmost click event and then check which element fired that event by checking the id of the target element. e.target will be the actual element that the click was performed on. You can either switch target.attr('id') or run it through if else conditions.
$(function () {
$("#topmost").on("click", function (e) {
e.preventDefault();
var target = $(e.target);
if(target.attr('id') === "idOfElement"){
// code to handle the event
}else{
});
A solution could be to track mouse move using :
$( document ).mousemove();
Store coordinates to a global variable then check its position when your element is clicked. That would give something like :
var mousePos = [0,0];
$( document ).mousemove(function( event ) {
mousePos[0] = event.pageX
mousePos[1] = event.pageY
});
$("#target").click(function(){
// Compare mouse coordinates and your items ones using offset, height and width
if(mousePos[0] > $('#target2').offset.left){
// Do whatever you are willing to do
}
});
I want add eventListener highlight buttonLockup with stackTemplate.
Can you guide to use this?
Thanks,
The event system in TVJS is extremely similar to that in a web browser. After all, it's just JS and a DOM. MDN's documentation on Event Handlers should be mostly relevant
To add an event listener to a specific button, just find that button (using ID or name or whatever), and use addEventListener.
var myButton = doc.getElementByName('buttonLockup')
var onSelect = function(ev) {
console.log('Button selected!')
}
myButton.addEventListener('select', onSelect)
However, depending on your use case, I've found Apple's approach in their sample apps to be quite useful. They rely on the fact that events bubble up to the root of the template, and just listen to them there. So for example:
// Given a TVML document has been presented with this somewhere in it
<buttonLockup action="doSomething">Do something</buttonLockup>
// When it's selected, doSomething
var globalOnSelect = function(ev) {
var target = ev.target;
var action = target.getAttribute('action')
if (action === 'doSomething') {
console.log('Do Something button selected');
doSomething();
}
}
doc.addEventListener('select', globalOnSelect);
I am not sure what to call this, all I can think of is a Repeater Button.
I want to press a button and it fires a function immediately once, eg MyZoom(InOrOut).
But if I keep the mouse button depressed it will keep firing that MyZoom(InOrOut) every one tenth of a second until I release the mouse button.
As you can probably guess from the function name, I will have 2 buttons, a zoom in and a zoom out. They will call MyZoom(-1) to make it smaller and MyZoom(1) to make it bigger.
<button onclick="MyZoom(-1);">Zoom Out</button>
<button onclick="MyZoom(1);">Zoom In</button>
How can I change this to include the repeating effect?
Use the onmousedown and onmouseup events.
In onmousedown start an interval and stop it in onmouseup.
Here's a small example using jQuery:
HTML:
<button class="zoomButton" data-zoom="out">Zoom Out</button>
<button class="zoomButton" data-zoom="in">Zoom In</button>
JavaScript:
var zoomIntervals = {};
$('.zoomButton').on('mousedown', function() {
var mode = $(this).data('zoom');
zoomIntervals[mode] = setInterval(function() {
// here you perform your action.
// check if mode == 'in' or mode == 'out' to determine if
// the user is zooming in or out
}, 100);
}).on('mouseup', function() {
var mode = $(this).data('zoom');
clearInterval(zoomIntervals[mode]);
del zoomIntervals[mode];
});
If you do not (want to) use jQuery, use addEventListener() to register the events and either access the data properties directly (not compatible with older browsers) or use e.g. the ID property to identify the buttons.
I would use jQuery for this. There is an event called mousedown and another event called mouseup that would help you to do that. Basically mousedown event starts a timer (repeating it) that gets stopped when mouseup event is fired.
You could have something like this:
$('#myzoominbutton').mousedown(function() {
alert('zooming is cool');
});
How can I access to an object who fires an eventListener event?
Let's say I have a mc:
var element = new MovieClip();
which has an eventlistener:
element.addEventListener(MouseEvent.CLICK, elementEventHandler);
And then, in the event handler, I want to add something to my mc:
function elementEventHandler(event:MouseEvent):void
{
var b1:balloon = new balloon("ballon1"); //this is another class.
event.target.addChild(b1);//this doesn't work.
}
So that is what I want to achieve... Recover the object who fired the event and then do crazy things with it (in this example, add another object in it).
If anybody has any idea, thanks in advance!
pd: yes, I know I can directly use the var element in this snippet, but in the real code I'm generating the mcs in a loop, according to a xml file.
function elementEventHandler(event:MouseEvent):void
{
// use the as-operator to cast the target into the class you need
var element:DisplayObjectContainer = e.target as DisplayObjectContainer;
// if the cast fails, element will be null, then we bail
if(!element) return;
// then, create your child and add it
var b1:balloon = new balloon("ballon1");
element.addChild(b1);
}
The reason you're getting an error is probably that the event is not coming directly from element but instead from one of its descendant objects.
"click" is a bubbling event.
Check out event flow in the DOM Level 3 Events spec to understand how the capture, target, and bubbling phases work:
http://www.w3.org/TR/DOM-Level-3-Events/#dom-event-architecture
So here's what I would do:
function elementEventHandler(event:MouseEvent):void
{
if (event.target != event.currentTarget)
// If event is not from "element", ignore it.
return;
...
}