jQuery code does not work - javascript

I tried to implement this javascript code taken from the other thread here:
css 'pointer-events' property alternative for IE, but I cannot make it work. When I click the target iframe element, the desired "click-through" effect did not come to reality. I tried it in jsfiddle.com too but it doesn't work either... I must have missed something important. Can someone show me how to do this code correctly in jsfiddle? Thank You very much.
$(document).ready(function() {
$(document).on('mousedown', '#iframe_1', function (e) {
$(this).hide();
var BottomElement = document.elementFromPoint(e.clientX, e.clientY);
$(this).show();
$(BottomElement).mousedown(); //Manually fire the event for desired underlying element
return false;
});
});
The iframe won't even hide... https://jsfiddle.net/c4vttL6t/

The event is not fired because you have to register the event on the content of the iframe, not in the iframe itself. You can achieve this with something like this:
var iframeBody = $('body', $('#iframe-1')[0].contentWindow.document);
$(iframeBody).on('mousedown', function(event) {
$('#iframe-1').hide();
return false;
});
But beware, if you are loading content from other site, this could not work.
Code taken from here
Update: Maybe this code could help you, taking into consideration that the iframe are one on top of the other:
// iframe-1 mousedown handler
var iframeBody1 = $('body', $('#iframe-1')[0].contentWindow.document);
$(iframeBody1).on('mousedown', function(e) {
//$('#iframe-1').hide();
// alert mousedown 1
alert('mousedown 1');
return false;
});
// iframe-2 mousedown handler
var iframeBody2 = $('body', $('#iframe-2')[0].contentWindow.document);
// search and trigger mousedown handler on X element
var iframeDocument1 = $("#iframe-1")[0].contentWindow.document;
// iframe-2 mousedown handler
$(iframeBody2).on('mousedown', function(e) {
//$('#iframe-2').hide();
// calculate position relative to element if necessarily
$(iframeDocument1.elementFromPoint(e.pageX, e.pageY)).mousedown();
// Alert mousedown 2
alert('mousedown 2');
// as you are using iframe I think hide and show is not necessary
// because you can trigger mousedown handler on a particular element
//$('#iframe-2').show();
return false;
});

Related

jQuery mouse event blocks default propagation

I have an issue with a full-body-overlay effect when clicking on any link.
The wanted effect is:
when any link of the page is "pushed" (mousedown or touchstart), an image overlay appears on the top of the whole body (hiding the complete content of the page)
when the link is (or should be) "released" (mouseup or touchend), the overlay should disappear and the original clicked link target should happen (the "href" attribute must be followed for instance).
The first part is OK: I added an event handler listening the "mousedown touchstart" events on every links. The second part is more complicated as the overlay does not trigger the "release" action of the link (the overlay is over the content with the link). So I attached a "mousedown touchend" event handler on the whole document, which works, but the default behavior of the clicked link (go to its "href" attribute for instance) is never fired :(
Here is my JS:
$(document).ready(function(){
// the full-page overlay selector
var $overlay = $('.body-overlay');
// a flag to keep a trace of clicked element
var overlay_triggered = false;
// the "mousedown" event handler
function show_overlay(evt)
{
var $target = $(evt.target);
if (overlay_triggered === false) {
$overlay.show();
overlay_triggered = $target;
$(document).on('mouseup touchend', hide_overlay);
}
return true;
}
// the "mouseup" event handler
function hide_overlay(evt)
{
if (overlay_triggered !== false) {
$(document).off('mouseup touchend', hide_overlay);
$overlay.hide();
// !!! - here I try to trigger a classic click but it never works
$(overlay_triggered).click();
overlay_triggered = false;
}
return true;
}
// attachment of the mousedown handler on all links
$(document).on('mousedown touchstart', 'a', show_overlay);
});
I made a JS Fiddle to show it more clearly.
Does someone know about any mistake here ? Is my logic wrong ?
The problem is caused by the way jQuery executes .click(). It is a shortcut for jQuery's trigger('click') method, and this is what the documentation says:
Although .trigger() simulates an event activation, complete with a synthesized event object, it does not perfectly replicate a naturally-occurring event.
The solution is to call the click method on the DOM element itself. It seems though that the MDN documentation announces the same limitations apply to that method:
The HTMLElement.click() method simulates a mouse click on an element.
However, the click() method will not initiate navigation on an <a> element.
...but in trying this with the current versions of Firefox, Chrome and Edge, the DOM click method does launch the <a> navigation (also when href has a http URL).
So, change this:
overlay_triggered = $target;
to:
overlay_triggered = evt.target;
And change this (which was overkill anyway):
$(overlay_triggered).click();
to:
overlay_triggered.click();
See the updated jsfiddle.
I am not exactly sure why this won't work but I got it working by changing $(overlay_triggered).click(); to window.location = $(overlay_triggered).attr("href");
I have slightly modified the JS part of yours, and all is okay now
The thing i did is holding the target's href value in a variable ( I stored the target's href value in 'href' vaiable in the code below ), and after that "window.location = href;" in 'hide_overlay' function does the trick.
<script>
$(document).ready(function(){
// the full-page overlay selector
var $overlay = $('.body-overlay');
// a flag to keep a trace of clicked element
var overlay_triggered = false;
var href = false;
// the "mousedown" event handler
function show_overlay(evt)
{
var $target = $(evt.target);
href = evt.target.href;
if (overlay_triggered === false) {
$overlay.show();
overlay_triggered = $target;
$(document).on('mouseup touchend', hide_overlay);
}
return true;
}
// the "mouseup" event handler
function hide_overlay(evt)
{
if (overlay_triggered !== false) {
$(document).off('mouseup touchend', hide_overlay);
$overlay.hide();
// !!! - here I try to trigger a classic click but it never works
if( href ) {
window.location = href;
}
overlay_triggered = false;
}
return true;
}
// attachment of the mousedown handler on all links
$(document).on('mousedown touchstart', 'a', show_overlay);
});
</script>

Get the type of the element which is dragged at the moment

In my site there is a div which shows up if you drag something into the browser and disappears if you dropped it.
function startDraghandler() {
$("*").on("dragover", function(event) {
$("*").off("dragover");
$("#uploadbox").animate({bottom:"+=360px"}, 250);
$("*").on("mouseover", function() {
$("#uploadbox").animate({bottom:"-=360px"}, 250);
$("*").off("mouseover");
startDraghandler();
})
});
}
But I don't want the div to show up if you dragged something from the site itself, only when it's coming from outside the browser. If you drag an element from the site, I want something different to happen. But I don't know how to do this, because all I've found on the internet is how to get the type of the dragged element when it's dropped.
Thanks for your help
There is not possible to know the data in the dragEvents except in the dragStart and dragEnd events.
But could exist a workaround, test this and tell me if it works ok for you:
// Variable declaration
var insidePage = false;
// When any element on document is dragged, set the var in true value.
$(document).on("dragstart", function(evt) {
insidePage = true;
});
$(document).on("dragend", function(evt) {
insidePage = false;
});
// Only executes the function if the element that is dragged is coming from outside the document
$(document).on("dragover", function(evt) {
if(!insidePage){
// Code to drag from outside
}
});

Prevent all javascript events from firing

I am working on a firebug like javascript element selector, but cannot figure out how to stop all JavaScript events from firing when clicked. The firebug lite plugin (https://getfirebug.com/firebuglite) is doing exactly what I want, but cannot figure out what they are doing.
Any help would be appreciated.
Senario:
User selects element inspector
User clicks on element
onClick, mousedown, mouseup should NOT fire
I have tried the following with no luck:
function stopEvents(el){
for(var key in window) {
if (key.indexOf("on") == 0)
el.addEventListener(key.substr(2), stop, false);
}
}
function StopEvent(pE)
{
stopEvents(pE);
if (!pE)
if (window.event)
pE = window.event;
else
return;
if (pE.cancelBubble != null)
pE.cancelBubble = true;
if (pE.stopPropagation)
pE.stopPropagation();
if (pE.preventDefault)
pE.preventDefault();
if (window.event)
pE.returnValue = false;
if (pE.cancel != null)
pE.cancel = true;
}
EDIT:
$('.somediv').on("click", function(e){
//Stop bubbling and propagation
StopEvent(e);
//EDIT: Still not working with this
e.stopImmediatePropagation();
//RUN only my code here
console.log("My code is running still");
return false;
});
If there is another library such as YUI binding events to the same DOM element. It will fire there event after mine. I cannot seem to hijack the event to stop this from happening.
EDIT:
I cannot use disabled because I need to be able to fire my event. If I did the following, I wouldn't be able to fire the above event. I cannot attach a parent event either because the DOM will stop firing all events on the Tree for that node.
$('.somediv').on("mouseover", function(e){
$(this).attr("disabled", "disabled");
});
EDIT:
The events I want to disable are already created before my script runs. These events could be any javascript library such as YUI, Dojo, jQuery, JavaScript etc...
Disabling all events on the page is very easy. Hard part is to restore them when needed.
document.body.innerHTML = document.body.innerHTML;
This will effectively remove all events bound to DOM nodes by replacing the DOM with it's "virgin" copy.
Most of the time user won't even notice the redraw.
You can't "disable" all of them without also intercepting the actual event binding, so you'd have to end up with something like this:
(function(prototypes) {
prototypes.forEach(function(prototype) {
var eventTracker = {};
var oldAEL = prototype.addEventListener;
prototype.addEventListener = function(a,b,c) {
if (!eventTracker[a]) { eventTracker[a] = true; }
return oldAEL.call(this, a, function(evt) {
console.log(a, eventTracker[a]);
if(eventTracker[a] === true) {
b(evt);
}
},c);
};
prototype.toggleEvent = function(name, state) {
eventTracker[name] = state;
};
});
}([Document.prototype, HTMLElement.prototype, ...]));
example: http://jsfiddle.net/BYSdP/1/
the button gets three click listeners, but if the second button is clicked, the event regulator for "click" is set to false, so none of the events will actually trigger the originally supplied code. Note that this also makes debugging a LOT harder, because you're wrapping handlers in anonymous functions.
event.stopImmediatePropagation() keeps the rest of the handlers from being executed and prevents the
event from bubbling up the DOM tree.
Example:
$( "p" ).click(function( event ) {
event.stopImmediatePropagation();
});
$( "p" ).click(function( event ) {
// This function won't be executed
$( this ).css( "background-color", "#f00" );
});
Source: https://api.jquery.com/event.stopimmediatepropagation/

jQuery click event triggered multiple times off one click

I am having trouble with multiple clicks being registered in jQuery when only one element has been clicked. I have read some other threads on Stack Overflow to try and work it out but I reckon it is the code I have written. The HTML code is not valid, but that is caused by some HTML 5 and the use of YouTube embed code. Nothing that affects the click.
The jQuery, triggered on document.ready
function setupHorzNav(portalWidth) {
$('.next, .prev').each(function() {
$(this).click(function(e) {
var target = $(this).attr('href');
initiateScroll(target);
console.log("click!");
e.stopPropagation();
e.preventDefault();
return false;
});
});
function initiateScroll(target) {
var position = $(target).offset();
$('html, body').animate({
scrollLeft: position.left
}, 500);
}
}
Example HTML
<nav class="prev-next">
Prev
Next
</nav>
In Firefox one click can log a "Click!" 16 times! Chrome only sees one, but both browsers have shown problems with the above code.
Have I written the code wrongly or is there a bug?
-- Some extra info ------------------------------------------
setupHorzNav is called by another function in my code. I have tested this and have confirmed it is only called once on initial load.
if ( portalWidth >= 1248 ) {
wrapperWidth = newWidth * 4;
setupHorzNav(newWidth);
}
else
{
wrapperWidth = '100%';
}
There are mutiple instances of nav 'prev-next'. All target different anchors. All are within the same html page.
<nav class="prev-next">
Prev
</nav>
Try unbinding the click event like this
$(this).unbind('click').click(function (e) {
});
You don't need .each() for binding event handlers. Try this instead:
$('.next, .prev').click(function(e){
var target = $(this).attr('href');
initiateScroll(target);
console.log("click!");
e.stopPropagation();
e.preventDefault();
return false;
});
EDIT:
I think it is the way you are attaching the event handler from within the setupHorzNav function that is causing it. Change it to attach it only once from say, $(document).ready() or something.
I have managed to get the situation of multiple event handlers by attaching the event handlers from a function that gets called from event handler. The effect is that the number of click event handlers keeps increasing geometrically with each click.
This is the code: (and the jsfiddle demo)
function setupNav() {
$('.next, .prev').each(function () {
$(this).click(function (e) {
setupNav();
var target = $(this).attr('href');
console.log("click!");
e.stopPropagation();
e.preventDefault();
return false;
});
});
}
setupNav();
See how calling the setupNav() function from the click event handler adds multiple eventhandlers (and the click log message) on successive clicks
Since it is not clear from your question whether you are calling the binding function multiple times, a quick and dirty fix would be:
$('.next, .prev').unbind('click').click(function() {
...
});
What you are doing here is unbinding any previously bound event handlers for click and binding afresh.
Are there no other click bindings elsewhere?
Are you loading the page with ajax?
You could also try this:
$('.next, .prev').click(function (e) {
var target = $(this).attr('href');
initiateScroll(target);
console.log("click!");
e.stopPropagation();
e.preventDefault();
return false;
});

Prevent keydown() from being captured by document binding

I'm not exactly sure how to phrase this, so I couldn't search it. Basically, I have a keydown() bind on $(document). I'd like to show() another div, and have all keydown events be rerouted to this div and prevented from firing off in the document handler. Is this even possible, or would I have to put all my main keybindings on another div and work from there?
e.stopPropagation, or
e.preventDefault (depending on the situation)
Where e is the event.
Ex:
function onKeyDown(e) {
doStuff();
e.preventDefault();
}
e.preventDefault() will prevent the default behaviour of an event. What you need is to use
e.stopPropagation(), so that the event does not bubble up the DOM structure.
$(element).keydown(function(e) {
// do the task
// allow the default behaviour also
e.stopPropagation();
//^. BUT stop the even bubbling up right here
});
e.stopProgation(), can be bit confusing to grasp on the first but I created a demo with click event to explain it.
Hope it helps!!
Try:
​$(document).on('keydown', function (evt) {
$('#foo').show().trigger(evt);
});​​​​​
$('#foo').on('keydown', function (evt) {
console.log(evt);
return false; // this is very important. Without it, you'll get an endless loop.
});
​
demo: http://jsfiddle.net/Z7vYK/
The only way I can think of to even have a keydown event run on something other than an input or document, is to manually trigger it. You could have a global variable keep track of whether or not your div is showing, then trigger the event on your div accordingly.
Here's one such solution
HTML
Show div
<div id="hiddendiv"></div>​
Javascript
var showing = false;
function showdiv()
{
showing = true;
$('#hiddendiv').show(200);
}
// Set up events on page ready
$(function() {
$(document).keydown(function(e) {
// If the div is showing, trigger it's keydown
// event and return
if(showing)
{
$('#hiddendiv').data('keydown_event', e).keydown();
return true;
}
alert('Document keydown! Keycode: ' + e.keyCode);
// Otherwise do the normal keydown stuff...
});
// Keydown for the hidden div
$('#hiddendiv').keydown(function() {
e = $(this).data('keydown_event');
alert('Hiddendiv keydown! Keycode: ' + e.keyCode);
// Make sure to stop propagation, or the events
// will loop for ever
e.stopPropagation();
return false;
});
});
​
As you can see, the #hiddendiv keydown event is being triggered by the document keydown event. I've also included a slight hack to get the event object to the hidden div using the jQuery data function.
Here's a demonstration of the code: http://jsfiddle.net/Codemonkey/DZecX/1/

Categories

Resources