Clickoutside event doen't work on iframe - javascript

It's a rich-text editor,there is a div show the content users typed in, just like this:
<div class=‘content’>
<iframe data-role=text-editable.></iframe>
</div>
When i click a icon who's used to call the color panel,the panel will show.And i wish when i click outside the panel,it will be hide.so my code is:
var color_panel = $('.color-panel');
color_panel.on("clickoutside", function (e) {
var t = $(e.target);
if ($.contains(color_panel[0], t[0]))
return;
color_panel.hide();
})
It works well when i click outside the panel will disappear except i click the iframe.when i click the ifame,nothing happens,the panel is still shown,
Help......i want to know the reason .please...is the ifame not the dom element outside the panel?

You can listen for outside clicks by listening for clicks on the body element of the webpage (so, clicking on anything element) and then you can exclude your .color_panel from this event by making another event that says "when I get clicked on, ignore any other clicks". The effect will be exactly what you want, that you can listen for outside clicks:
var panelOpen = false;
$('body').click(function(event) {
if (panelOpen) {
panelOpen = false;
color_panel.hide();
}
});
$('.color_panel').click(function(event) {
panelOpen = true;
//callYourMethodToShowThePanelHere();
e.preventDefault(); // these methods will stop the body click event
e.stopPropagation();
return false;
});

Related

.click() event not working for mobile in Javascript

I am having a problem with my code, I have a hidden a href link that the href value is added once a click is detected in a image and the link is pass as a value the the hidden href. So once it clicks on the image in Javascript I am making the manually .click() to the hidden href tag but it is not working in mobiles. My code is below:
processGridClick : function(obj){
var objIndex = obj.getAttribute('data-item-number');
var docType = obj.getAttribute('data-doc-type');
if(obj.className.indexOf('single') > -1){
var documentURL = "";
var documentsJsonRoot = DocumentsMgr.documentationData.documents[objIndex];
if(docType == 'reportsList'){
documentURL = documentsJsonRoot.reportsList[0].url;
}else if(docType == 'attachmentList'){
documentURL = documentsJsonRoot.attachmentList[0].url;
}
dojo.attr('linkDocumentsSingle', "href", documentURL);
document.getElementById('linkDocumentsSingle').click();
}
}
The view is a table that is generated in base of a JSON object and it can have more than one row, the value of the href is passed in base of the image that they clicked. This works good for desktop but in mobile the .click is not working, I even tried to add manually the touchstart event to all the clickable elements with the code below but stills not working.
**(function(window){
// check for touch
if (Modernizr.touch) {
// run the forEach on each figure element
[].slice.call(document.querySelectorAll("figure")).forEach(function(el,i){
// check if the user moves a finger
var fingerMove = false;
el.addEventListener("touchmove",function(e){
e.stopPropagation();
fingerMove = true;
});
// always reset fingerMove to false on touch start
el.addEventListener("touchstart",function(e){
e.stopPropagation();
fingerMove = false;
});
// add hover class if figure touchend and fingerMove is false
el.addEventListener("touchend",function(e){
e.stopPropagation();
if (fingerMove == false) {
classie.toggle(el,"hover");
}
});
});
}
})(window);**
Will this work for mobile? Try simulating a mouse click...?
var ele = document.getElementById('linkDocumentsSingle');
ele.dispatchEvent(new MouseEvent('mousedown'));
ele.dispatchEvent(new MouseEvent('mouseup'));
Try to use this
In i phones there is a click event only for anchor tag or buttons. So for image, div or span you have to use tap event.
// listen for a touchstart event
$('img').on('touchstart.tap',function (e) {
// listen for a touchend event
$(e.target).one('touchend.tap',function() {
$(e.target).trigger('tap');
});
// cancel it in 150ms
setTimeout(function () {
$(e.target).off('touchend.tap');
},150);
});
This will trigger a tap event if a touchend follows a touchstart within 150ms (which you can adjust, of course). You could try using this in lieu of including jQuery mobile if a tap event is all you're after.
Note: For this i have examined you have included bootstrap js library

Hide div when user clicks outside unless closing lightbox

I'm currently using the following code to allow a user to show/hide a div on click.
When clicking anywhere outside of the div, it closes the div.
However, there is a link within the div which can open a lightbox. When a user goes to close that lightbox, it also closes the div that the link was contained. Is there anything I can add into the script to stop that from happening?
$(document).ready(function(){
$("a.dropdown-link").click(function(evt) {
evt.preventDefault();
var $div = $(this).next('.info-container');
$(".info-container").not($div).slideUp();
if ($div.is(":visible")) {
$div.slideUp()
} else {
$div.slideDown();
}
});
$(document).click(function(e){
var p = $(e.target).closest('.dropdown').length
if (!p) {
$(".info-container").slideUp();
}
});
$('.movie-link').magnificPopup({type:'iframe'});
});
<a class="dropdown-link" href="#"><div class="dropdown dropdown-processed">More info</div></a>
<div class="info-container" style="display: none;">Video preview: <a class="movie-link" href="videourl"></a></div>
I'm using Magnific Popup for the lightbox: http://dimsemenov.com/plugins/magnific-popup/
My JavaScript knowledge is pretty basic so any help is appreciated.
In the "click to close div function, you can check if the lightbox is on or not. A simple if ($("#lightbox").css("display") == "none") should be able to do the trick
EDIT: put this line after the $(document).ready line
var state = 0; // default state
$('.movie-link').click(function() { state = 1; }); // state = 1, lightbox on
in the source code, on line 384, insert this code
state = 2; //state = 2, lightbox close button clicked
the idea is not firing the "close div" function when the state is 1 (lightbox is on and clicking random stuffs inside, or outside the lightbox) or 2 (lightbox's close button got clicked), and return state to 0 when it was 2
so instead of the if I provided in the comment use this
if (state == 2) {
state = 0;
} else if (state == 0) {
//rest of the code
}
this is just something I put together and haven't tested yet, so I don't actually know if it works or not so just back up your js files just in case.
EDIT 2:
remove all the changes in edit 1 and use this on instead of the if (state == 2) {
if (e.target != $('.mfp-bg')[0] and e.target != $('.mfp-wrap')[0]) {
EDIT 3
var e_class = $(e.target).attr('class');
if (e_class != 'mfp-close' && e_class != 'mfp-container') {
working example: http://imgcrash.comeze.com/test.html
I'm not 100% without actually testing this out but you may be running into issues with $(document).click(...); since clicking anywhere on the document would trigger this event.
When you close the popup you're probably triggering this event and sliding up the info-container div.
It seems that you're looking for clicks on the divs with the class .dropdown. Why not use something like:
$('.dropdown').click(function(e) { ... });
Try this:
$("a.dropdown-link").click(function(evt) {
evt.preventDefault();
evt.stopPropagation(); //We stop the propagation of the event
//Changed it to slideToggle and added stop to prevent weird animation
//on multiple clicks
$(this).next('.info-container').stop().slideToggle()
});
$(document).click(function(e){
//Check if it has the class info-container
if (!$(e.target).hasClass("info-container")) {
$(".info-container").slideUp();
}
});
$('.movie-link').magnificPopup({type:'iframe'});
Fiddle

Hide Specific Div on the user event (i.e click)

I open the my notifications are by clicking on bell image on top of page it just alight and open correctly
but now i want whenever user click inside the div of notification then notification box appear same as it but whenever clicks outside div it closes (div id is HSnotifications)
Have the document listen to the click event.
$(document).on('click', function (e) {
e.preventDefault();
var $target = $(e.target);
// You are checking the current clicked element is the div
// or any of the descendants of the notifications div
if ($target.closest('#HSnotifications').length) {
// Clicked inside the notifications.
// do something
} else if ($target.is('#showNotificationsBtn')) {
// If bell button is clicked open the notification
$('#HSnotifications').show();
} else {
// close notifications
$('#HSnotifications').hide()
}
});
Check Fiddle
This should do what you need. When clicking the background overlay, hide/close the HSnotifications.
<script>
$(document).ready(function() {
$('.ui-panel-content-wrap').click(function (event) {
if ($(event.target).hasClass('ui-panel-content-wrap')){
$('#HSnotifications').hide();
}
});
});
</script>

How to close a javascript menu

I'm creating pulldown menus that must be clicked on to open. This code lets the user opening menus just fine. The only problem is I haven't figured out how to close the menus yet by clicking outside the menus. I tried adding the "document.onclick" shown, but it takes effect even in the menus.
I think I need to prevent document.onclick from being captured by other elements, but am not sure how to do this cross-platform. Can someone please show me how?
<script type="text/javascript">
var lastOpenedMenuId = null;
function showMenu(menuId) {
if (lastOpenedMenuId != null && lastOpenedMenuId != menuId) {
hideLastOpenedMenu();
}
setMenuVisibility(menuId, 'visible');
lastOpenedMenuId = menuId;
}
function hideMenu(menuId) {
setMenuVisibility(menuId, 'hidden');
}
function hideLastOpenedMenu() {
if (lastOpenedMenuId != null) {
hideMenu(lastOpenedMenuId);
}
}
function setMenuVisibility(menuId, visibleOrHidden) {
var menuElement = document.getElementById(menuId);
menuElement.style.visibility = visibleOrHidden;
}
document.onclick = hideLastOpenedMenu;
</script>
<div onmousedown="showMenu('foodmenu')"><a>FOOD</a></div>
<div id="foodmenu" onmouseup="hideMenu('foodmenu');">
Meat
Tofu
</div>
Thanks in advance.
I have made some progress and have reformulated the question here:
How to stop onclick event in div from propagating to the document?
Depending on whether you have a page layout like this:
<body>
<div id="menu"><!--Menu Stuff--></div>
<div id="main"><!--Main page stuff--></div>
</body>
you could put the onClick handler to close the menu on the div with the id "main" which should work
Someone pointed me to a solution that uses addEventListener. Say, the div is the menu. This code allows the user to click on the document outside the div to do something, such as close the menu. Clicking on the div (say, on a link) will not propagate to the document.
<head>
<script>
function menuHandler(event) {
alert("div clicked");
// Don't propogate the event to the document
if (event.stopPropagation) {
event.stopPropagation(); // W3C model
} else {
event.cancelBubble = true; // IE model
}
}
document.onclick = function() {
alert('document clicked');
};
function addListener() {
var foodMenuElement = document.getElementById('foodmenu');
if (foodMenuElement.addEventListener) {
foodMenuElement.addEventListener('click', menuHandler, false);
} else {
foodMenuElement.attachEvent('onclick', menuHandler);
}
}
</script>
</head>
<body onload="addListener()">
<div id="foodmenu" style="border: 1px solid red;">Click inside this div</div>
or click outside the div.
</body>
Note that the third argument "false" to addEventListener means "fire the event during the capturing phase", but the value doesn't matter because the event propagation is canceled in menuHandler.
This solution works, but I'd like to do the same thing more simply, without addEventListener, so have posted a question at How to stop onclick event in div from propagating to the document?

How to get Javascript event to fire only when the background is clicked (and not other elements)?

I'm trying to write a web app which replaces the context menu (right-click menu) with my own customized ones. I want it so that when the user clicks on a table row, they get one certain context menu and when they click on the background of the page, they get a different one.
I have already written the menus and gotten them working. The problem comes in when trying to figure out how to get the background's menu to show ONLY when clicking on the background and how to get the table row's menu to show when that is clicked.
I tried using document.body.oncontextmenu for the body and and setting the oncontextmenu function for each table row, but the body's oncontextmenu function overrides the row's so I get the wrong menu. The menu for the table rows DOES work if I stop using the body's menu, so that's not the issue.
I could be using the wrong events, so is there a different event for just the background (and not the elements on top of the background)? Or a way to "prioritize" the events so the table row's function takes precedence?
This is how the code looks:
var tableMenu;
var bodyMenu;
window.onload = function()
{
bodyMenu = new rightClickMenu("bodyMenu");
document.body.oncontextmenu = function() { bodyMenu.show(); tableMenu.hide(); }
bodyMenu.add("Add Entry", function()
{
alert("ADD");
});
tableMenu = new rightClickMenu("tableMenu", "tblSims");
simRows = getElementsByClassName("trSimRow");
for (var i in simRows)
simRows[i].oncontextmenu = function() { tableMenu.show(this.id.substring(2)); bodyMenu.hide(); }
tableMenu.add("Delete Entry", function(mac)
{
alert("DELETE");
});
document.body.onclick = function()
{
bodyMenu.hide();
tableMenu.hide();
};
}
You can capture the target element, e.g.:
$('*').click(function(e) {
alert(e.target);
alert(e.target.tagName);
if(e.target.tagName == 'html') {
// show background menu
}
});
You have to work with the Javascript Event Propagation model. What happens is that your click event is automatically passed down the layers of objects on a page that have been registered as event listeners, unless you explicitly tell it to stop, try something like this:
function setupClickHandlers()
{
document.getElementsByTagName('body')[0].onclick = doBodyMenu;
document.getElementById('tableID').onclick = doTableMenu;
}
function doBodyMenu()
{
//do whatever it does
}
function doTableMenu(e)
{
//do whatever it does
//stop the event propagating to the body element
var evt = e ? e : window.event;
if (evt.stopPropagation) {evt.stopPropagation();}
else {evt.cancelBubble=true;}
return false;
}
This should deal with the way each browser handles events.
$( document ).ready(function() {
var childClicked = false;
// myContainer is the nearest container div to the clickable elements
$("#myContainer").children().click(function(e) {
console.log('in element');
childClicked = true;
});
$("#myContainer").click(function(e){
if(!childClicked) {
console.log('in background');
e.preventDefault();
e.stopPropagation();
}
childClicked = false;
});
});
#myContainer {
width:200px;
height:200px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myContainer" style="">
link
<div style="width:50px;height:50px;background-color: white;">
another link
</div>
</div>

Categories