Get clicked element in Meteor? - javascript

I have HTML in the following format:
<div class="panel panel-1 active" data-chart="flight-chart">
<div class="row panel-header">
<div class="col-sm-3"><i class="fa fa-plane fa-4x"></i></div>
<div class="col-sm-9">
<div class="big">123,673</div>
<div class="small">flights added since 3/3/2016</div>
</div>
</div>
<div class="panel-footer">view more information</div>
</div>
I am capturing click events using the code below:
Template.infoPanel.events
'click .panel': (event, instance) ->
console.log 'panel click',event.target
The issue I am having is that depending on where in the .panel div I click, a different element is returned for event.target. So If I click on the .col-sm-9 div, that will be returned as the target even though the event is targeting it's parent .panel. Same goes for clicking on .panel-footer.
How can I get the .panel element 100% of the time from inside of the click event?

Use currentTarget instead:
console.log 'panel click', event.currentTarget
See the Event Maps section of the docs for more details.

Related

Focus an element within a ShadowDOM

I have a modal dialog created within a Shadow DOM and injected (using violentmonkey) into a page during document load. This dialog contains a simple form. The idea is to prompt the user for input.
When the dialog is created, it has focus. Elements can be tabbed, and I can hook key/mouse events. The problem arises when the window load event is triggered. Focus returns to the main body (verified by issuing document.activeElement in the console and by hooking focusin/out for both body and the shodowroot). I can hook the focusin event, but so far nothing I have tried will return focus to my dialog.
A cut down version of the dialog:
<div id="twifty-translate-dialogue" style="">
#shadow-root (open)
<div class="outer" style="z-index: 2147483647; pointer-events: none;">
<div class="container">
<div id="header" class="">
</div>
<div id="languages" class="">
</div>
<div class="buttons">
<button id="translate" class="button-translate" type="button">Translate</button>
<button id="cancel" class="button-cancel" type="button">Cancel</button>
</div>
</div>
</div>
I would expect the following to work:
window.onload = () => {
document.getElementById("twifty-translate-dialogue").shadowRoot.getElementById("translate").focus()
}
From what I've read, there should be two active elements. The #twifty-translate-dialogue and the shadow DOMs #translate. But:
document.activeElement
> <body>
document.getElementById("twifty-translate-dialogue").shadowRoot.getElementById("translate").focus()
document.activeElement
> #twifty-translate-dialogue
document.getElementById("twifty-translate-dialogue").shadowRoot.activeElement
> null
How can I restore focus?
Update:
A workaround:
window.onload = () => {
window.setTimeout(() => {
this.shadow.getElementById("translate").focus()
}, 1)
}
I'm guessing that the focus changes after the onload event, meaning that trying to set the focus in the handler will have no effect. By using a timeout, I've scheduled the focus call for after the completion of onload.
Is this a bug or standard behaviour? Is there a prefered way of setting the focus?

hover working properly with one class and not with another

HTML:
<div class="channellist"></div>
Using Ajax i am getting the channels dynamically when the page loads and appending in the channellist container. After appending my html looks like this.
<div class="channellist" id="channellist">
<div class="c01" id="c1"></div>
<div class="c01" id="c2"></div>
<div class="c01" id="c3"></div>
</div>
I tried like this
$('.channellist').hover(function() {
alert(this.id);
});
I got the alert message.
when i tried the hover on c01 class i didnt got the alert.
$('.c01').hover(function() {
alert(this.id);
});
I dont know where it is going wrong. Can anyone help to figure it out.
You need use event delegation, try this
$('.channellist').on('mouseenter mouseleave', '.c01', function() {
console.log(this.id);
});
// only for example
setTimeout(function () {
$('.channellist').html(
'<div class="c01" id="c1">1</div>' +
'<div class="c01" id="c2">2</div>' +
'<div class="c01" id="c3">3</div>'
);
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="channellist" id="channellist"></div>
$.on
The name "hover" used as a shorthand for the string "mouseenter
mouseleave". It attaches a single event handler for those two events,
and the handler must examine event.type to determine whether the event
is mouseenter or mouseleave. Do not confuse the "hover"
pseudo-event-name with the .hover() method, which accepts one or two
functions.
Using Ajax i am getting the channels dynamically
This can be sorted using event delegation like:
$('#channellist').on('mouseenter', '.c01', function() {
alert(this.id);
});
syntax of event delegation is something like:
$(staticParent).on(event, selector, callback);
where $(staticParent) should be the element which was available when DOM was ready, In your case it seems to be #channellist element.
Since code is dynamically attached to the div, onload of the document the event will not be present, So use .live event or use .on by delegating the event. Then event will execute. For your reference Check this link:
https://jsfiddle.net/HimeshS/ocxoy6c2/
https://jsfiddle.net/HimeshS/ocxoy6c2/
For .live:
$(.c01).live("mouseenter", function(){
alert(this.id);
});
<div class="channellist" id="channellist">
<div class="c01" id="c1"></div>
<div class="c01" id="c2"></div>
<div class="c01" id="c3"></div>
</div>
Your blocks are empty, their height is 0, and you can't hover on tham.
Try to make height more, or print some text inside,
Like:
<div class="channellist" id="channellist">
<div class="c01" id="c1">1</div>
<div class="c01" id="c2">2</div>
<div class="c01" id="c3">3</div>
</div>

using .load to load pages from a navbar

I'm using bootstrap's modal and I would like to have a navbar at the top of the modal that uses jquery's .load to change the view of the modal when clicked. I am able to get the modal up with the default view to show but I can't get the rest of the buttons to fire when clicked. Below id a simplified version of what I want. Thanks for any help.
<div class="modal-header">
<button type='button' class='close' data-dismiss='modal' aria-hidden='true'>X</button>
<h3 id="myModalLabel">Account Settings</h3>
</div>
<div class="modal-body">
<div class="btn-group">
<button id="account" class="btn">Account</button>
<button id="edit-account-users" class="btn">Users</button>
</div>
<div class="wrapper">
<!-- Content -->
</div>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss='modal' aria-hidden='true'>Close</button>
</div>
$(document).ready(function () {
accountData.init();
});
var accountData = {
'init' : function() {
$('.account-settings, #account-settings #account').click(function() {
$('#account-settings').load('/partials/account/index.html', function() {
$('#account-settings .wrapper').load('/partials/account/account_data.html');
});
});
$('#edit-account-users').click(function() {
$('#account-info .wrapper').load('/partials/account/account_users.html');
});
}
};
The reason your buttons didn't fire is because your event bindings may be attached to elements that no longer exist.
Say if you were to replace content using .load(), the original event handlers to the elements will be lost. That's why event delegation is very useful here, bind the event to the document instead of the individual element. (You're not going to replace document) So when the user clicks anything inside the page, the event will be picked up by document and delegated to a child element according to the selector provided, eg. #edit-account-users.
Use event delegation .on() instead of .click().
$(document).on('click', '#edit-account-users', function() {
$('#account-info .wrapper').load('/partials/account/account_users.html');
});
Read more about .on(): http://api.jquery.com/on/

fadeOut not working

I am new to web design. I am making my resume now. I have navigation div like this:
<div id="nav" class="grid_12">
<div id="Home" class="grid_3">
<div class="button">
Home
</div>
</div>
<div id="Life" class="grid_3">
<div class="button">
Life
</div>
<img src="img/someimg.jpg">
</div>
<div id="Portfolio" class="grid_3">
<div class="button">
Portfolio
</div>
</div>
<div id="Contact" class="grid_3">
<div class="button">
Home
</div>
</div>
</div>
Then I have a script for the navigation:
<script type="text/javascript>
$("#nav img").hide();
$(".button").focus(function() {
$(this).next("img").fadeIn("slow");
}).blur(function() {
$(this).next("img").fadeOut("slow");
});
</script>
I want it so when someone holds the mouse over the button the image will appear under it. It is properly hiding the image, but fadeIn not working. I have no idea why it is not working.
.focus is bound to the "focus" event (I linked to a description of what it is rather than the event standard). This is most common when you tab to or click on text inputs, but it can apply to other elements as well.
The mouseenter (also mouseover, but the former is not triggered repeatedly when child elements are also hovered) event occurs when a mouse enters an element. The opposite is mouseleave (mouseout). http://api.jquery.com/mouseenter/
try putting your script inside a ready event of the document :
<script type="text/javascript>
$(document).ready(function(){
$("#nav img").hide();
$(".button").focus(function() {
$(this).next("img").fadeIn("slow");
}).blur(function() {
$(this).next("img").fadeOut("slow");
});
});
</script>
I believe you're using the 960gs, and one thing I have noticed is this: your four grid_3 divs are nested within your grid_12. The 960gs includes two classes called .alpha and .omega to fix the nested margins when a grid is inside a parent grid. You need to put the .alpha class on the first child div - which in this case is your <div id="#home"> and the .omega class on the last child div which is your <div id="Contact">. This will fix the margins you will have on the internal nested four grid_3's.

Separate touch events of parent and child

I use jquery for my web application. I want it to be correct for desktop browsers and mobile brousers for touchscreen devices.
I have a div, and some elements inside it:
<div class="well listItem element-div alert-error" data-state="removing">
<strong>Item title</strong> <small>Items count</small>
<div class="pull-right" style="margin-top: -5px;">
<a class="btn btn-success approve-button"><i class="icon-ok icon-white"></i></a>
<a class="btn btn-danger cancel-button"><i class="icon-remove icon-white"></i></a>
</div>
</div>
I catch click and touchend event for .listItem class (top-level div) and same events for every a element (for .approve-button and .cancel-button), but when I'm click on desktop browser on 'a' element, it works correct, and when I am pressing on 'a' element in iOS Safari browser, or WindowsPhone InternetExplorer, works only event for parent div, but not for 'a'. If I remove event listener for parent div, events for 'a' elements works correct in mobile browsers. I want parent-div event works when I touch a free space of it, and when I touch 'a' element - I want only 'a' event listener to go on. Can you advise me how to separate them?
Have you tried to check event target?
$(".listItem").on("click", function(event){
if (event.target === this) {
// clicked exactly on this element
}
});
I've had a similar problem, only my content was more nested. You want to exclude the areas (divs, classes or otherwise) where you expect to handle other events, using :not selector, like so:
<article>
<div class="title">
<span class="title"></span>
<div class="buttons">
<div class="minimize">+</div>
<div class="remove">x</div>
</div>
</div>
<div class="post">
...
</div>
</article>
With jQuery:
$("article :not(.buttons, .minimize, .remove)").click(function (event) {
// toggle display value of div.post
});
This triggers a click event anywhere inside article, except for the .buttons, .minimize and .remove divs.

Categories