jQuery .click() is clicking, but it shouldn´t - javascript

while testing my JavaScript I have the following problem:
$('#idOfMyElement').click();
is executed. But I want to verfiy with my test, that is is not executed, because it has the following CSS:
<span style="cursor: not-allowed; pointer-events: none;" id="idOfMyElement"></span>
I debugged it and it is sure, that when the .click() is executed, it has DEFINITELY the mentioned CSS-attributes. In my normal program it works (means that the click doesn´t work), but in my test the click works, even if it shouldn´t.
I have no clou, what might be the problem.
Thanks for your help!

Looks like in your test you are triggering the event programmatically by using $('#idOfMyElement').click();; in that case it is not bound by the CSS mouse rules, and thus the click handlers will get executed.
You need to check the mouse pointer rules before triggering the click event in your test suite.

Prevent the default click event using jQuery:
$('#idOfMyElement').on('click', function(e) {
e.preventDefault(); });
* UPDATE *
Now that I know what you're trying to do, I highly recommend using javascript over CSS for this because CSS does not work the way you're trying to use it – Javascript does. Instead of using CSS attributes, use Javascript variables.
When you want the element to be clickable,
$('#idOfMyElement').prop('disabled', false);
When it should be unclickable,
$('#idOfMyElement').prop('disabled', true);
The browser takes care of the cursor without needing CSS, and click events should react appropriately. Hope that was helpful!

Pointer events only respond correctly to a real pointer event. If you trigger click() function it fires in all times that you make it. Just add a condition reading if pointer events is active or replace it by a disabled attribute

Related

Prevent default events of medium-editor

How would i replace internally triggered events of medium-editor with my custom ones or simply change internally designed behaviour?
In this hierarchy
<div>
<textarea class='editable'></textarea>
</div>
I bind a click handler to the div and do e.stopPropagation() and e.preventDefault().
I also try adding after the instantiating of medium-editor.
var editor = new MediumEditor('.editable')
.subscribe("editableClick", function(e){
e.preventDefault();
});
Every way i try textarea gets focused and cursor starts to blink.
For example intial click event adds an element to the dom with a class .medium-editor-element should i dive to source to modify this behaviour?
Or maybe i would like it to work with not a click but a double click.
Anyone familiar with the internal workings of medium-editor?
After trial and error and the help of dev tools i found the way to do what i want.
But i think this question is still answerable because i did it by modifying the source of medium-editor.
So, in medium-editor.js in line 2725 there is setupListener function.
There are 3 main events attached there to case 'externalInteraction': 2731th line.
mousedown,click,focus.
Starting from 2959th line there are the attached handlers for those events.
handleBodyClick,handleBodyFocus,handleBodyMousedown
The mousedown is important for my case because it is the first one that fires and should be prevented and accepted in different cases.
In the end i added a dblclick and handleBodyDblClick to source then put some logic in handleBodyMousedown to prevent the default behaviour of mousedown event in some cases.
Anyway, from the source as i can understand there are no override methods or hooks to modify medium-editor internal events.
It would be nice to have that feature.
Or if i am wrong i would like to know if there is a better way to do all these.

How to trigger an event on a group of elements?

I have a listener on a group of elements:
$('a.menu__link').on('click',function() {alert('function was triggered');});
One element of which is:
<a class="menu__link menu__link--submenu Main" id="Events" href="#">Events</a>
I want to manually trigger a click on the element. Using Chrome dev tools, the event handler is:
a#Events.menu__link.menu__link--submenu.Main
However, the following code does not trigger the listener:
$('a#Events.menu__link.menu__link--submenu.Main').trigger('click');
I have tried every variation that I can think of, but I cannot find the correct reference to trigger the alert function.
What am I doing wrong?
You can use instead click instead of trigger like this to trigger a click :
$('#div').click();
Read more about click here
Here is a JsFiddle
I encased the trigger in a $(document).ready(function()) and that fixed it.
Kudos to Blazemonger for implying that it was a timing issue.
<script>$(document).ready(function() {
$('#Events').trigger('click');
$('#PastSeminars').addClass('menu__link--current');
});</script></body></html>
The lesson? Just because it is the last thing on the page, when in doubt, use document.ready.
Chrome blocks the click event from being programmatically fired. I'd come up with a new solution such as just calling the needed function wherever you need to trigger it.
You can read more about it here: https://teamtreehouse.com/community/why-does-my-onclick-event-not-fire-on-chrome

Is it possible to intercept/override all click events in the page?

I've written an html5 application which is supposed to work on mobile devices. 90% of the time it works fine however in certain devices (mostly androids 4.0+) the click events fire twice.
I know why that happens, I'm using iScroll 4 to simulate native scrolling and it handles the events that happen inside the scroll.(line 533 dispatches the event if you're interested) Most of the time it works fine but in certain devices both the iScroll dispatched event and the original onClick event attached to the element are fired, so the click happens twice. I can't find a pattern on which devices this happen so I'm looking for alternatives to prevent double clicks.
I already came up with an ugly fix that solves the problem. I've wrapped all the clicks in a "handleClick" method, that is not allowed to run more often than 200ms. That became really tough to maintain. If I have dynamically generated content it becomes a huge mess and it gets worse when I try to pass objects as parameters.
var preventClick = false;
function handleClick(myFunction){
if (preventClick)
return;
setTimeout(function(){preventClick = true;},200);
myFunction.call():
}
function myFunction(){
...
}
<div onclick='handleClick(myfunction)'> click me </div>
I've been trying to find a way to intercept all click events in the whole page, and there somehow work out if the event should be fired or not. Is it possible to do something like that?
Set myFunction on click but before it's called, trigger handleClick()? I'm playing with custom events at the moment, it's looking promising but I'd like to not have to change every event in the whole application.
<div onclick='myfunction()'> click me </div>
You can do that with the following ( i wouldn't recommend it though):
$('body').on('click', function(event){
event.preventDefault();
// your code to handle the clicks
});
This will prevent the default functionality of clicks in your browser, if you want to know the target of the click just use event.target.
Refer to this answer for an idea on how to add a click check before the preventDefault();
I don't like events on attributes, but that's just me.
Thinking jquery: $(selector).click(function(){ <your handler code> } you could do something like:
$(selector).click(function(event){
handleClick(window[$(this).attr("onclick")]);
};
of course, there wouldn't be any parameters...

JQuery if statement for .is(':visible') not working

I have a div that when the page is loaded is set to display:none;. I can open it up using this simple code:
$(".field-group-format-toggler").click(function()
{
$(".field-group-format-wrapper").css({'display':'block'});
});
Once it's opened, I'd like the user to be able to close it so I tried using the .is(':visible') function and then wrapping my original code in an if statment but this time using display:none;
if($('.field-group-format-wrapper').is(':visible')){
$(".field-group-format-toggler").click(function()
{
$(".field-group-format-wrapper").css({'display':'none'});
});
}
This does not seem to work though and I am not getting any syntax errors that I know of.
I also tried this:
if ($('.field-group-format-wrapper').is(':visible'))
$(".field-group-format-toggler").click(function () {
$(".field-group-format-wrapper").css({'display':'none'});
});
... but that did not work either.
You can just use the toggle function:
$(".field-group-format-toggler").click(function()
{
$(".field-group-format-wrapper").toggle();
});
This will show the '.field-group-format-wrapper' elements if they are currently hidden and hide them if they're currently visible.
FYI the reason your code snippet in your question wasn't working is because you're only checking the visibility of the elements on dom ready, rather than on each click - so the event handler to show the elements will never be attached.
I guess your function is only being called on page load at which time all divs are hidden.
Why not check the visibility in the click event handler?
$('.field-group-format-toggler').click(function(){
var $wrapper = $('.field-group-format-wrapper'); //Maybe $(this).parent()?
if($wrapper.is(':visible'))
$wrapper.hide();
else
$wrapper.show();
As already mentioned, you can use the toggle function to achieve what you want.
To add a bit of extra information, when attaching events like you're doing, you're actually using a subscription model.
Registering an event puts it in a queue of events subscribed to that handler. In this case, when you add the second event to change the CSS, you're adding an event, not overwriting the first one.
Whilst thing isn't actually causing your problem, it's worth being aware of.

Locating an element in a 'Facebox' box

Heres my link:
http://tinyurl.com/6j727e
If you click on the link in test.php, it opens in a modal box which is using the jquery 'facebox' script.
I'm trying to act upon a click event in this box, and if you view source of test.php you'll see where I'm trying to loacte the link within the modal box.
$('#facebox .hero-link').click(alert('click!'));
However, it doesn't detect a click and oddly enough the click event runs when the page loads.
The close button DOES however have a click event built in that closes the box, and I suspect my home-grown click event is being prevented somehow, but I can't figure it out.
Can anyone help? Typically its the very last part of a project and its holding me up, as is always the way ;)
First, the reason you're getting the alert on document load is because the #click method takes a function as an argument. Instead, you passed it the return value of alert, which immediately shows the alert dialog and returns null.
The reason the event binding isn't working is because at the time of document load, #facebox .hero-link does not yet exist. I think you have two options that will help you fix this.
Option 1) Bind the click event only after the facebox is revealed. Something like:
$(document).bind('reveal.facebox', function() {
$('#facebox .hero-link').click(function() { alert('click!'); });
});
Option 2) Look into using the jQuery Live Query Plugin
Live Query utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements auto-magically, even after the page has been loaded and the DOM updated.
jQuery Live Query will automatically bind the click event when it recognizes that Facebox modified the DOM. You should then only need to write this:
$('#facebox .hero-link').click(function() { alert('click!'); });
Alternatively use event delegation
This basically hooks events to containers rather than every element and queries the event.target in the container event.
It has multiple benefits in that you reduce the code noise (no need to rebind) it also is easier on browser memory (less events bound in the dom)
Quick example here
jQuery plugin for easy event delegation
P.S event delegation is pencilled to be in the next release (1.3) coming very soon.

Categories

Resources