Prevent event propagation using Google Closure Library - javascript

Using Google Closure Library:
How can I handle clicking of an element for example a div but prevent firing the event handler when the user clicks the child elements of that element.
For example in the following code I want to fire the event handler when user click div1 but when he/she clicks 'span1' I want another event handler to be called without firing the handler of div1.
<div style="width: 400px" id="div1">
<span id="span1">click me to reload</span>
click here to Toggle accordion
</div>
UPDATE
JS Code:
/**** accordion ***/
var panels = goog.dom.getElementsByClass('newsColumnHeader', goog.dom.getElement('accordionContainer'));
var anims = {};
var open = null;
goog.array.forEach(panels, function(pane){
var animation = new goog.ui.AnimatedZippy(pane, goog.dom.getNextElementSibling(pane));
goog.events.listen(animation, goog.ui.Zippy.Events.TOGGLE, zippyToggle);
anims[goog.getUid(animation)] = animation;
});
function zippyToggle(event) {
var uid = goog.getUid(event.target);
// simple logic - only one open panel in one time
if (event.expanded && uid != open) {
if (open) {
anims[open].setExpanded(false);
}
open = uid;
}
}
/******************/
var refreshVarzesh3 = goog.dom.getElement("btnRefreshVarzesh3");
if (refreshVarzesh3 != null) {
goog.events.listen(refreshVarzesh3, goog.events.EventType.CLICK, function(event) {
/*doing something but not toggling accordion pane*/
});
}
HTML CODE:
<body>
<div class="main">
<div class="top">
<div id="toolbar">
<img src="css/img/contact.png" alt="تماس، پیشنهاد، گزارش خطا" title="تماس، پیشنهاد، گزارش خطا"/>
</div>
<img src="css/img/football_news.gif" alt="آخرین اخبار فوتبال"/>
</div>
<div class="middle">
<div class="left"></div>
<div class="right">
<div class="accordion" id="accordionContainer">
<div class="newsColumnHeader">
<div class="buttons">
<img id="btnRefreshVarzesh3" src="css/img/refresh.png" alt="به روز رسانی" title="به روز رسانی"/>
</div>
<%=lbls.getString("Varzesh3News")%>
</div>
<div class="newsList" id="varzesh3NewsContainer"></div>
<div class="newsColumnHeader"><%=lbls.getString("PersepolisNews")%></div>
<div class="newsList" id="persepolisNewsContainer"></div>
<div class="newsColumnHeader"><%=lbls.getString("EsteghlalNews")%></div>
<div class="newsList" id="esteghlalNewsContainer"></div>
<div class="newsColumnHeader"><%=lbls.getString("NavadNews")%></div>
<div class="newsList" id="navadNewsContainer"></div>
</div>
</div>
</div>
<div class="bottom"></div>
</div>

for pure javascript developers the answer is here but if you use Google Closure Library the following code is enough:
event.stopPropagation();

in the event handler of that click you have to use preventDefault()
for example:
document.getElementById('div1').onclick = function (event) {
//your code
event.preventDefault();
}

Just for Reference All events in Google Closure are derived from goog.events.Event
http://docs.closure-library.googlecode.com/git/class_goog_events_Event.html
For Example : goog.events.BrowserEvents
So first one is stopPropagation
this.getHandler().listen(element ,goog.events.EventType.CLICK, function (e){
e.stopPropagation();
});
Second one is goog.events.Event.stopPropagation is a static method
which in turn calls above method
goog.events.Event.stopPropagation = function(e) {
e.stopPropagation();
};
Edit :
Please do read - Dangers of Event Propagation

Related

Focus trap in a dialog modal and after exiting, focus on the last element clicked

I have multiple modals with different id's.
<div id="#Modal" tabindex="-1" class= active" style="left: Opx;" role="dialog" >
<div id="#Modal-text' tabindex="0">
<div class="container">
<div class= close-btn">
<a class="closer noprint href=" javascript:void(0) aria-label="Close dialog" tabindex="0"></a>
</div>
</div>
<div class= content">..modal content goes here</div>
<div class="focus-guard" tabindex="0"></div>
</div>
<div id="#Modal-anothertext' tabindex="0"></div>
<div id="#Modal-sample' tabindex="0"></div>
</div>
The jquery function add a focus guard div and add an event listener to it whenever a tab or keyboard navigation, through it, it will go again to the close button:
"use strict"
jquery(document).ready(function ($) {
// Check if modal exists
if ($(" [id+='Modal-']").length {
// Check id's if containstring of 'Modal-' and check if modal has child with #focus-guard
if ($("[id*='Modal-']").find("focus-guard").length === 0) {
console.log("does not exist");
const focusGuard = document.createElement("div");
focusGuard.setAttribute("class", "focus-guard");
focusGuard.setAttribute("tabindex", "0");
// Add focus guard to parent
$("[id*='Modal-']").append(focusGuard);
// The closer button is being added in the DOM upon clicking modal, that's why I used DOMNodeInserted
$(document).bind("DOMNodeInserted", function (e) {
if (e.target.className="container") {
const close = document.querySelector(".closer");
console.log(close);
focusGuard.addEventListener("focus", () => {
close.focus();
});
}
});
}
});
}
Have tried also some possible selectors and isolating a single modal.
Unfortunately, the eventlistener on focus guard div does not trigger and I cannot target speciffically the "closer noprint" class.
I know it's not right to have a selector like an array("[id=Modal-]"*) to refer to the parent element of the modal but since it's multiple, not sure if this will be the right thing to do. Might there be a simple solution for this one.
Also stuck with a function that focuses on the last item clicked after dismissing the modal.

How to prevent child element executing onmousedown event

I've got the following markup on the page
<div id="box">
<div id="box_child_one"></div>
<div id="box_child_two"></div>
<div id="box_child_three"></div>
</div>
I need to trigger the onmousedown event on all elements inside the #box div so i've got this javascript code:
var element = "#box";
document.querySelector(element).onmousedown = function() {
alert("triggered");
};
However, I do not want onmousedown being triggered on the #box_child_three element.
How can I achieve this?
Thank you.
Check event.target to find out which element was actually clicked on.
var element = "#box";
document.querySelector(element).onmousedown = function(e) {
if (e.target.id !== "box_child_three") {
alert("triggered");
}
};
<div id="box">
<div id="box_child_one">one</div>
<div id="box_child_two">two</div>
<div id="box_child_three">three</div>
</div>
You need to stopPropagation for the event when element three is clicked so that it doesn't bubble up to the parent (box) element.
document.getElementById('box').addEventListener('click', () =>
alert('triggered')
);
document.getElementById('box_child_three').addEventListener('click', e =>
e.stopPropagation()
);
<div id="box">
<div id="box_child_one">one</div>
<div id="box_child_two">two</div>
<div id="box_child_three">three</div>
</div>
<div id="box">
<div id="box_child_one" trigger></div>
<div id="box_child_two" trigger></div>
<div id="box_child_three"></div>
</div>
<script>
document.querySelector('#box').onclick = function(e){
if(e.target.hasAttribute('trigger')){
alert('event fired')
}
}
</script>
I'd go for this. As you are now no longer relying on an id to carry this out making it more re-usable

JS mouse trigger bad

I have a problem with some hover mouse events using javascript. When I pass over one of the entries the reference image is shown but the event is alternate. How fix it? I want to display the current image in "hover" and hide it when it's over the box without alterations.
I try set an interval, stop propagation...
HTML CODE:
<div class="d-inline-block">
<div class="hover_collaborazioni">
<span class="home_collaboration-hover"><?php the_field('nome')?></span>
<span class="text-16"><?php the_field('anno')?></span>
</div>
<div class="modal z-index-100">
<div class="modal-contenuto">
<?php the_post_thumbnail('single-post-thumbnail'); ?>
</div>
</div>
</div>
JS CODE:
let linkModal = document.querySelectorAll(".home_collaboration-hover");
linkModal.forEach(item => {
item.addEventListener("mouseenter", (event) => {
item.parentElement.parentNode.querySelector(".modal").classList.add("d-block");
item.parentElement.parentNode.querySelector(".modal").classList.add("d-flex");
});
item.addEventListener("mouseleave", (event) => {
item.parentElement.parentNode.querySelector(".modal").classList.remove("d-block");
item.parentElement.parentNode.querySelector(".modal").classList.remove("d-flex");
});
}

Get id of main div using JavaScript

How can I get the div id for a button and identify whether it's within one of two possible ids? For example, we have a call-to-action button that could be inside a div with the id="new" or id="current". Here are a few examples:
<div id="new">
Download
</div>
or
<div id="current">
Download
</div>
It's possible the id could be in a parent or parent's parent div, such as this:
<div id="new">
<div class="something">
Download
</div>
</div>
or this:
<div id="new">
<div class="row">
<div class="col-md-6">
Download
</div
</div>
</div>
We'd like our landing page developers to be able to develop the pages without having to ever touch the JavaScript for this functionality. We're ultimately trying to pass along this value in a URL string, such as this:
fileref.setAttribute("src", "https://oururl.html?cStatus=" + cStatus);
Make this slight modification: onclick="cStatus(this)" and then:
function cStatus(elem) {
var els = [];
while (elem) {
els.unshift(elem);
elem = elem.parentNode;
if (elem.id == "new") {
// has new
break;
} else if (elem.id == "current") {
// has current
break;
}
}
}
In the onclick callback you can get the parent element using $(this).parent() and then check its id.

Jquery - Adding event to specific div that shares class name with others

I'm looking to add a mouseup event to a series of divs, that when clicked, reveal a child div ('menu'). All the parent divs share the same class, for example:
<div class="container">
<div class="menu"><p>Text</p></div>
</div>
<div class="container">
<div class="menu"><p>Text</p></div>
</div>
etc...
However, I'd like the event to only trigger when I've clicked that particular 'container'. When I click on another 'container', I'd like the same thing to happen, however, I'd also like the previously opened 'menu' to hide. The only way I have managed to do this (being a JQuery noob), is to create variables for each container, as well as giving them unique classes. For example:
$(document).mouseup (function (e){
var buttonOne = $(".containerOne");
var buttonTwo = $(".containerTwo");
var menuOne = $(".containerOne").find(".menu");
var menuTwo = $(".containerTwo").find(".menu");
if(buttonOne.is(e.target)){
menuOne.toggle(100);
menuTwo.hide();
}
else if(buttonTwo.is(e.target)){
menuTwo.toggle(100);
menuOne.hide();
}
else {
$(".menu").hide();
}
});
Quick JSFiddle
This then creates lines and lines of code the more containers I add, and I feel there is almost certainly an easier way of doing this. Apologies if this was written poorly, it's been a long day, ha.
Add a new class to the containerxxx element then use a simple click handler
<div class="containerOne container">
<div class="menu">
<p>Text</p>
</div>
</div>
<div class="containerTwo container">
<div class="menu">
<p>Text</p>
</div>
</div>
then
var $menus = $('.container .menu');
$('.container').mouseup(function (e) {
var $menu = $(this).find('.menu').toggle();
$menus.not($menu).hide()
});
Demo: Fiddle
How about something like
$(".container").on("click", function() {
var mine = $(".menu", this).toggle(100);
$(".menu").not(mine).hide();
});

Categories

Resources