jquery draggable in iframe won't click - javascript

I have created a draggable within an iframe from it's parent and I would like to attach an event for when the draggable is clicked.
The draggable works by itself and all the click functions work by themselves, however as soon as you mix the two together the left click events stop working. If I remove the iframe and put the draggable and click bindings in a seperate page it works fine.
parent.html
<iframe id="siteframe" src="http://jsfiddle.net/kyT6N/show/light/">
parent.js
$('#siteframe').load(function () {
$('#siteframe').contents().find('.draggable').draggable({ delay:200, iframeFix: true});
$('#siteframe').contents().find('.draggable').bind('mouseup',function() {
alert('mouse up');
});
$('#siteframe').contents().find('.draggable').click(function() {
alert('click');
});
$('#siteframe').contents().find('.draggable').on('click', function() {
alert('click');
});
});
iframe.html
<div class="draggable">draggable</div>
JSFiddle code:
http://jsfiddle.net/A5T3Q/
JSFiddle demo:
http://jsfiddle.net/A5T3Q/show/light/
EDIT:
After investigating a bit further it seems that it's the iframeFix: true option that messes with the click function, I'm guessing this is because it overlays the iframe? is there anything that can be done about this?

I think it is the problem that jquery ui create iframeFix mask too fast immediately after the mousedown event occured , but the delay is only use for mousestart control . So this can be optimized by add a function _iframeFix .
_iframeFix: function(event){
//patch for iframe
var o=this.options;
if(o.iframeFix === true){
$("div.ui-draggable-iframeFix").each(function() {
this.parentNode.removeChild(this);
});
}
$(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
$('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')
.css({
width: this.offsetWidth+"px", height: this.offsetHeight+"px",
position: "absolute", opacity: "0.001", zIndex: 1000
})
.css($(this).offset())
.appendTo("body");
});
}
remove the iframe mask code in the _mouseCapture function ,and to create iframe mask after delay .
Also , you should add a mouseup event handle for the drag element in the iframe to endup the timeout control
if(o.iframeFix&&o.delay){
that.element
.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
}
And final in the _mouseup function, clear the mouseup handle ,clear the timeout
_mouseUp: function(event) {
$(document)
.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
var o=this.options;
if(o.iframeFix&&o.delay){
mouseHandled = false;
this.element
.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
}
if(this._mouseDelayTimer) clearTimeout(this._mouseDelayTimer);
if (this._mouseStarted) {
this._mouseStarted = false;
if (event.target === this._mouseDownEvent.target) {
$.data(event.target, this.widgetName + '.preventClickEvent', true);
}
this._mouseStop(event);
}
return false;
},

Your code is right, but, you are loading iframe from different URL.
If parent domain and iframe url domain is different then javascript don't allows you to access iframe element.

Related

jQuery stopPropagation not stopping click through

I have a panzoom plugin that is working well. When I click on var elem it adds a small div cp_select in the correct location. Then, when I click on that newly created cp_select div, it removes that div. So you can add and remove it accordingly. However, when I click on the cp_select div, it removes it then immediately adds it back in because the click is propagating through. I have tried event.stopPropagation() and event.stopImmediatePropagation() with no luck. Any ideas how to prevent the cp_select firing the map_click(e)?
window.panzoom = panzoom(elem, {
onClick(e) {
map_click(e);
}
})
function map_click(e) {
$(".map_cont").prepend('<div class="cp_select" style="left:'+calc_x+'px ;top:'+calc_y+'px"></div>');
}
$('body').on('click', '.cp_select', function(event) {
event.stopImmediatePropagation()
$(this).remove()
return false;
});
The problem must be specifically with however panzoom is dealing with its onClick, or otherwise in code not shown in the question; if I substitute a plain click event handler on the window in place of your panzoom call, event.stopPropagation() works as expected.
// nonessential code removed and simplified for demo
function map_click() {
$(".map_cont").prepend('<div class="cp_select"></div>');
}
$('body').on('click', '.cp_select', function(event) {
$(this).remove();
event.stopPropagation();
});
window.onclick = map_click // stand-in for your panzoom function
.cp_select {
border: 3px solid;
height: 20px; width: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
(click anywhere)
<div class="map_cont"></div>

prevent all MouseClick event until page load

I have a situation in which i have to prevent all MouseClick events until the page loads.
i have 1 javascript function defined on page load like
onload="init();"
Now in function init(), we are showing tree and select a particular node of it.
function init() {
ExpandAncestors(node);
ExpandNode(node);
setTimeout("treeScrollToView()", 1000);
}
Now i want to prevent all the mouse click event on tree/page until whole tree is not fully shown.
I have searched through some of the posts related to my question but that uses event.preventDefault() but i dont have Event object here.
Any help is greatly appreciated.
You can use:
CSS
body {
pointer-events:none;
}
and then on page load reactivate them
$(document).ready(() => {
$('body').css('pointer-events', 'all') //activate all pointer-events on body
})
Explanation
pointer-events:none; blocks all mouse interaction with the elements it's applied to - Since the body is usually the parent of all the elements in your page, it would case them not to react to any mouse interaction at all.
Keep in mind that all mouse interaction would be blocked this way, not only mouse clicks but mouse hover, mouse up's etc etc..
I think the basic need is to prevent user from clicking the tree area. I would prefer to display an overlay div rather than playing with the tree mouse click events.
You can show a loading overlay on the tree part until it is loaded. once done, you can hide the loading and show your original tree.
Ref: How to completely DISABLE any MOUSE CLICK
JavaScript Only
You can have an event listener along with a boolean. onclick disables a click. oncontextmenu disables right clicks.
(function(){window.onload = function () {
var allowClicks = false;
document.onclick = function (e) { !allowClicks&&e.preventDefault(); }
document.oncontextmenu = function (e) { !allowClicks&&e.preventDefault(); }
document.getElementById('myElement').onload = function () { allowClicks = true; }
}());
myElement is your element which you can replace with whatever
Use this with one element
If you want to disable mouse clicks for just one element, do:
(function(){window.onload = function () {
var allowClicks = false,
elem = document.getElementById('myElement');
elem.onclick = function (e) { !allowClicks&&e.preventDefault(); }
elem.oncontextmenu = function (e) { !allowClicks&&e.preventDefault(); }
elem.onload = function () { allowClicks = true; }
}());
onload="init();" here you can have event object.
pass event as argument.
onload="init(event);"
now you can use that in init() function.
Try utilizing $.holdReady()
$.holdReady(true);
$(window).off("click");
$("*").each(function(i, el) {
this.onclick = function(e) {
e.preventDefault();
}
});
function init() {
$("div").on("click", function() {
alert($.now())
})
}
setTimeout(function() {
$.holdReady(false);
}, 7000)
$(function() {
init()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<body>
<div>click</div>
click
</body>

Close a div by clicking outside

I want to hide a div by clicking on the close link in it, or by clicking anywhere outside that div.
I am trying following code, it opens and close the div by clicking close link properly, but if I have problem to close it by clicking anywhere outside the div.
$(".link").click(function() {
$(".popup").fadeIn(300);
}
);
$('.close').click(function() {
$(".popup").fadeOut(300);
}
);
$('body').click(function() {
if (!$(this.target).is('.popup')) {
$(".popup").hide();
}
}
);
<div class="box">
Open
<div class="popup">
Hello world
<a class="close" href="#">Close</a>
</div>
</div>
Demo:
http://jsfiddle.net/LxauG/
An other way which makes then your jsfiddle less buggy (needed double click on open).
This doesn't use any delegated event to body level
Set tabindex="-1" to DIV .popup ( and for style CSS outline:0 )
DEMO
$(".link").click(function(e){
e.preventDefault();
$(".popup").fadeIn(300,function(){$(this).focus();});
});
$('.close').click(function() {
$(".popup").fadeOut(300);
});
$(".popup").on('blur',function(){
$(this).fadeOut(300);
});
You need
$('body').click(function(e) {
if (!$(e.target).closest('.popup').length){
$(".popup").hide();
}
});
I'd suggest using the stopPropagation() method as shown in the modified fiddle:
Fiddle
$('body').click(function() {
$(".popup").hide();
});
$('.popup').click(function(e) {
e.stopPropagation();
});
That way you can hide the popup when you click on the body, without having to add an extra if, and when you click on the popup, the event doesn't bubble up to the body by going through the popup.
You'd better go with something like this. Just give an id to the div which you want to hide and make a function like this.
call this function by adding onclick event on body.
function myFunction(event) {
if(event.target.id!="target_id")
{
document.getElementById("target_id").style.display="none";
}
}
Add a transparent background taking up the whole window size, just before your popup div
.transparent-back{
position: fixed;
top: 0px;
left:0px;
width: 100%;
height: 100%;
background-color: rgba(255,255,255,0.5);
}
Then on its click, dismiss the popup.
$(".transparent-back").on('click',function(){
$('popup').fadeOut(300);
});
This question might have been answered here. There might be some potential issues when event propagation is interrupted, as explained by Philip Walton in this post.
A better approach/solution would be to create a custom jQuery event, e.g. clickoutside. Ben Alman has a great post (here) that explains how to implement one (and also explains how special events work), and he's got a nice implementation of it (here).
More reading on jQuery events API and jQuery special events:
Introduction to custom events
jQuery event extensions
var modal = document.getElementById("reject-popup");
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
//for closeing the popover when user click outside it will close all popover
var hidePopover = function(element) {
var elementScope = angular.element($(element).siblings('.popover')).scope().$parent;
elementScope.isOpen = false;
elementScope.$apply();
//Remove the popover element from the DOM
$(element).siblings('.popover').remove();
};
$(document).ready(function(){
$('body').on('click', function (e) {
$("a").each(function () {
//Only do this for all popovers other than the current one that cause this event
if (!($(this).is(e.target) || $(this).has(e.target).length > 0)
&& $(this).siblings('.popover').length !== 0 && $(this).siblings('.popover').has(e.target).length === 0)
{
hidePopover(this);
}
});
});
});

Hiding Bootstrap Popover on Click Outside Popover

I'm trying to hide the Bootstrap Popover when the user clicks anywhere outside the popover. (I'm really not sure why the creators of Bootstrap decided not to provide this functionality.)
I found the following code on the web but I really don't understand it.
// Hide popover on click anywhere on the document except itself
$(document).click(function(e) {
// Check for click on the popup itself
$('.popover').click(function() {
return false; // Do nothing
});
// Clicking on document other than popup then hide the popup
$('.pop').popover('hide');
});
The main thing I find confusing is the line $('.popover').click(function() { return false; });. Doesn't this line add an event handler for the click event? How does that prevent the call to popover('hide') that follows from hiding the popover?
And has anyone seen a better technique?
Note: I know variations of this question has been asked here before, but the answers to those questions involve code more complex than the code above. So my question is really about the code above
I made http://jsfiddle.net/BcczZ/2/, which hopefully answers your question
Example HTML
<div class="well>
<a class="btn" data-toggle="popover" data-content="content.">Popover</a>
<a class="btn btn-danger bad">Bad button</a>
</div>
JS
var $popover = $('[data-toggle=popover]').popover();
//first event handler for bad button
$('.bad').click(function () {
alert("clicked");
});
$(document).on("click", function (e) {
var $target = $(e.target),
var isPopover = $target.is('[data-toggle=popover]'),
inPopover = $target.closest('.popover').length > 0
//Does nothing, only prints on console and wastes memory. BAD CODE, REMOVE IT
$('.bad').click(function () {
console.log('clicked');
return false;
});
//hide only if clicked on button or inside popover
if (!isPopover && !inPopover) $popover.popover('hide');
});
As I mentioned in my comment, event handlers don't get overwritten, they just stack. Since there is already an event handler on the .bad button, it will be fired, along with any other event handler
Open your console in the jsfiddle, press 5 times somewhere on the page (not the popover button) and then click bad button you should see clicked printed the same amount of times you pressed
Hope it helps
P.S:
If you think about it, you already saw this happening, especially in jQuery.
Think of all the $(document).ready(...) that exist in a page using multiple jquery plugins. That line just registers an event handler on the document's ready event
I just did a more event based solution.
var $toggle = $('.your-popover-button');
$toggle.popover();
var hidePopover = function() {
$toggle.popover('hide');
};
$toggle.on('shown', function () {
var $popover = $toggle.next();
$popover.on('mousedown', function(e) {
e.stopPropagation();
});
$toggle.on('mousedown', function(e) {
e.stopPropagation();
});
$(document).on('mousedown',hidePopover);
});
$toggle.on('hidden', function () {
$(document).off('mousedown', hidePopover);
});
short answer
insert this to bootstrap min.js
when popout onblur will hide popover
when popout more than one, older popover will be hide
$count=0;$(document).click(function(evt){if($count==0){$count++;}else{$('[data-toggle="popover"]').popover('hide');$count=0;}});$('[data-toggle="popover"]').popover();$('[data-toggle="popover"]').on('click', function(e){$('[data-toggle="popover"]').not(this).popover('hide');$count=0;});
None of the above solutions worked 100% for me because I had to click twice on another, or the same, popover to open it again. I have written the solution from scratch to be simple and effective.
$('[data-toggle="popover"]').popover({
html:true,
trigger: "manual",
animation: false
});
$(document).on('click','body',function(e){
$('[data-toggle="popover"]').each(function () {
$(this).popover('hide');
});
if (e.target.hasAttribute('data-toggle') && e.target.getAttribute('data-toggle') === 'popover') {
e.preventDefault();
$(e.target).popover('show');
}
else if (e.target.parentElement.hasAttribute('data-toggle') && e.target.parentElement.getAttribute('data-toggle') === 'popover') {
e.preventDefault();
$(e.target.parentElement).popover('show');
}
});
My solution, works 100%, for Bootstrap v3
$('html').on('click', function(e) {
if(typeof $(e.target).data('original-title') !== 'undefined'){
$('[data-original-title]').not(e.target).popover('hide');
}
if($(e.target).parents().is('[data-original-title]')){
$('[data-original-title]').not($(e.target).closest('[data-original-title]')).popover('hide');
}
if (typeof $(e.target).data('original-title') == 'undefined' &&
!$(e.target).parents().is('.popover.in') && !$(e.target).parents().is('[data-original-title]')) {
$('[data-original-title]').popover('hide');
}
});

attach an event to the body when ul is visible, then remove it when invisible

I have a <ul> that when clicked, toggles the visibility of another <ul>. How can I attach an event to the body of the page when the <ul>s are revealed so that the body will hide the <ul>.
I am new to writing these sorts things which bubble, and I cannot figure out why what I have done so far seems to work intermittently. When clicked several times, it fails to add the class open when the secondary <ul> is opened.
And of course, there may be an entirely better way to do this.
$(document).on('click', '.dd_deploy', function (e) {
var ul = $(this).children('ul');
var height = ul.css('height');
var width = ul.css('width');
ul.css('top', "-" + height);
ul.fadeToggle(50, function () {
//add open class depending on what's toggled to
if (ul.hasClass('open')) {
ul.removeClass('open');
} else {
ul.addClass('open');
}
//attach click event to the body to hide the ul when
//body is clickd
$(document).on('click.ddClick', ('*'), function (e) {
e.stopPropagation();
//if (ul.hasClass('open')) {
ul.hide();
ul.removeClass('open')
$(document).off('click.ddClick');
// }
});
});
});​
http://jsfiddle.net/JYVwR/
I'd suggest not binding a click event in a click event, even if you are unbinding it. Instead, i would do it this way:
http://jsfiddle.net/JYVwR/2/
$(document).on('click', function (e) {
if ( $(e.target).is(".dd_deploy") ) {
var ul = $(e.target).children('ul');
var height = ul.css('height');
var width = ul.css('width');
ul.css('top', "-" + height);
ul.fadeToggle(50, function () {
//add open class depending on what's toggled to
if (ul.hasClass('open')) {
ul.removeClass('open');
} else {
ul.addClass('open');
}
});
}
else {
$('.dd_deploy').children('ul:visible').fadeOut(50,function(){
$(this).removeClass("open");
})
}
});​
If you need to further prevent clicking on the opened menu from closing the menu, add an else if that tests for children of that menu.
You dont' really need all that code. All you need is jquery's toggle class to accomplish what you want. simple code like one below should work.
Example Code
$(document).ready(function() {
$('ul.dd_deploy').click(function(){
$('ul.dd').toggle();
});
});​​​​
Firstly, you are defining a document.on function within a document.on function which is fundamentally wrong, you just need to check it once and execute the function once the document is ready.
Secondly why do you want to bind an event to body.click ? it's not really a good idea.
Suggestion
I think you should also look at the hover function which might be useful to you in this case.
Working Fiddles
JSfiddle with click function
JSfiddle with hover function

Categories

Resources