mootools click:relay not firing on ipad/iphone - javascript

I am just creating a click event with mootools as follows:
$$('body').addEvent('click:relay(div.smart-bg)', function(){
xxxxxxxxxxx
});
However, this doesn't seem to fire on an iPad (whereas other click events do fire). Is this something to do with the fact it is a dynamic element added and that I am using :relay?
Any pointers greatly appreciated.
Ad.

I've run into similar problems when I added a delegated click event on a div.
This article from quirksmode may help:
There must be a reason for this behaviour. I don’t know what that reason is, but currently I think that it’s a memory management problem. Apparently, making all elements on a page clickable demands too many resources, and the Apple engineers decided to disable it.
and...
Fortunately it’s pretty easy to solve: you have to make the element clickable by giving it an onclick event handler of its very own. That handler can be empty; as long as it’s present it will make any element clickable.
Perhaps in your case...
$$('.smart-bg').each(function(el) {
el.onclick = function() {};
});
Although of course, given that it is a delegated event, you'll have to be sure to recreate the onclick handler on each .smart-bg element you dynamically create.

Related

Understanding JavaScript events and applying jQuery events/plugins?

I have a bunch of jQuery functions that use the .on event because I want to prevent reapplying the event to the same element.
However some people created plugins (e.g. Owl Carousel) and I don't know how to prevent this event from reapplying.
Currently I am using the plugin as following:
HTML:
<div class="init-owl"></div>
JS:
$('.init-owl').owlCarrousel();
$('.init-owl').removeClass('init-owl');
Whenever a second element gets loaded in the page using e.g. AJAX, I want to only apply the event to the newly added element.
Question: What I dont understand is how the event stays stuck to the DOM?
To better grip what is happening, I was wondering how an event in general gets connected to the DOM?
Is there a better way to prevent events applying to the same DOM elements?
If I wish to write my own plugins, I would need to know how javascript works, right?
Question: What I dont understand is how the event stays stuck to the DOM?
Once an event is bound to an object, it gets removed when the object gets garbaged collected. So if a DOM element is really gone and there are no references to it, then the event will get swept up as well.
To better grip what is happening, I was wondering how an event in general gets connected to the DOM?
I'm not sure how far you want to dive into this. Maybe it would help if you stop thinking about the DOM and events and look more at just regular events bound to objects. Basically an object does something, or something is done to it and some underlying code (in the browser's code in this case) triggers an event on that object. The implementations between browsers may differ, but basically you will have a key or string (the event name) that maps to a collection of functions. When you add an event listener, you add another function to this collection. Then when something triggers that event, it iterates through the functions and executes them. That's a real basic explanation, but I hope it makes things a little more clear.
Is there a better way to prevent events applying to the same DOM elements?
Make sure you don't add the events again by writing better code. I don't believe you can dive down into an element and look to see if it has events bound to it. You can however change your jQuery selector to only target newly added elements. If you have to, mark the elements that you have added events to with a class or something. Then you could target your elements by doing $('.init-owl:not(.already-bound)'). There is a better solution to your problem, I can assure you, but we might need more context and code to see a better way to help you.
EDIT:
You can look into jQuery's off() function to remove events. That may help you too.

Fix Hijacked Event Handling of Click-Events

For a few years now I use user-JavaScript to put additional input buttons and clickable span-elements on pages. Usually I manage to make this work, e.g.
span = document.createElement("span");
span.onclick = __oujs.onClickAddPage;
span.appendChild(document.createTextNode("Add page"));
containingDiv.appendChild(span);
Usually __oujs.onClickAddPage() is called when I click on that span-element.
However, yesterday a site made some changes (apparently I have no clue what they were) that causes clicking on my elements to not cause any events. In the example above __oujs.onClickAddPage() is not called any more. The same is true for input-elements of type "button".
As I'm using Opera, DragonFly shows that my span still is the top-most element in that particular area and, therefore, it should handle the click-event. However, I understand that they include jQuery, which might be part of the misery.
Is there a special technique (maybe with a name that Google knows of) they use to able to do such thing? How do I get the control back and have my code called again? Can I remove some object?
I'm sorry for asking in a rather broad style, but I have no clue what I can look for to fix this myself. Please ask if you need to know something.
I would suggest you this steps:
Create the next function:
function stubFn(event){
console.log('event caught', event); // this will log the click event
__oujs.onClickAddPage.call(event.currentTarget, event); // emulate the onclick behavior
}
Use span.addEventListener('click', stubFn) to add the listener to the element in your code.
If it does not work, then you have to reverse-engineer the script and markup.
I'd suggest to check if there is any element with absolute or fixed position overlapping your span. It can prevent the event propagation.
In general, there are no ways to forbid the elements from userscripts to handle events using inlined handlers.
To get this off my open questions I answer this myself rather than waiting for it to be closed:
I'm sorry, it was my fault. I had a stupid mistake in another user-JavaScript file that affected all sites...
I reinstalled my browser and was thinking about reinstalling my OS, but luckily this isn't necessary.

Trouble with"onmouseover" event using native Javascript

I am attempting to add an onmouseout function to the names in the following widget. The onmouseover works fine but the onmouseout fires almost immediately on rollover. Not sure why.
http://jsfiddle.net/A8fmg/
I think it may have something to do "bubbling" and I have been trying to read about the subject but don't quite understand the implications.
Any help is appreciated.
Your mouseover handler is destroying the <a> which the handlers are attached to. Adjust your code so that the handlers are attached to a permanent element, either by attaching to a different element or not destroying the one you are using.

JQuery dropping click events

I'm currently experiencing click events intermittently not firing. Anyone else ever had this problem?
Code is simple:
<ul class="iconButtons ui-widget ui-helper-clearfix">
<li class="ui-state-default ui-corner-all" title="Save">
<span class="btnSave ui-icon ui-icon-disk"></span>
</li>
</ul>
$(document).ready(function() {
$(".btnSave").click(function() {
alert("Sometimes I never get called!");
});
});
Occurs frequently in all browsers. Using live demonstrates the same behaviour.
I would venture to say that there is some other complication going on to prevent what you are doing.
Here are some possibilities:
Unless you give that empty span display:block; then on some browsers it will have a width and height of 0px and be unclickable. Keep in mind just adding width and height to a span won't actually work on inline elements.
You are ajax'ing content in, and not rebinding the click handler. You can check at any time by doing $(".btnSave").data("events") in your firebug or chrome console to see the number of events to that element.
Another event is usurping your event, using the technique in #2 may help reveal this.
Your click handle is being called, but not returning the right result causing to believe it wasn't being called. Have you tried adding an alert('called') to the very top of the click handler?
Are you certain the element exists in the DOM prior to appending the click element to it? You can check by doing an alert($(".btnSave").length) at the line JUST before you bind the click handler.
I would suggest you use an anchor instead of a span for your button it will fire for sure.
Put
$(".btnSave").click(function(event){
event.preventDefault();
alert("Clicked");
});
In IE, you also have to have content inside an anchor for it to work: background image / background color/ text (maybe also with big negative text-indent)
Your code will hook up event handlers to all elements with that class that already exist when the code is called. If you add more later, they won't get the handler because, well, you haven't asked that they do. :-) Options:
You could use live instead, if you add and remove these elements dynamically. live (and the related delegate) use event delegation to watch for events rather than actually attaching the handlers to the elements in question. live uses the document itself. Since click bubbles, document sees all clicks (that aren't cancelled), and so jQuery's document-wide handler can see if the click was on a .btnSave element and fire your handler if so.
You could put your script at the bottom of the page (just before the closing </body> element), so that all of the elements are there when you hook up your handler.
You could use jQuery's ready function to ensure the DOM is ready before you hook up your handlers.
Alternately, as quoted your span is pretty darned hard to click on (what with being completely empty) unless there's some CSS giving it dimensions you haven't shown... ;-)
Update: You've said the span has dimensions, and that the handler is being hooked up fine (you didn't say how you know that). The only thing left is if something is hooking the click event on those elements and cancelling them (e.g., via stopImmediatePropagation, like this), and it happens that they're earlier in the event handler list than your handler is. It seems more likely that there's an issue hooking things up, though.
There may be many different reasons for that, eg.:
the JS code you are referring to is not executed correctly (does not bind the event in the correct moment in time), try executing it when the DOM is ready:
jQuery(function(){
// your code goes here
});
you may be creating this element dynamically (if you bind it first, then create element, then this element will not have the specific event). The solution is to use .delegate() or .live() jQuery functions.
the event may be unbound somewhere in your code. Try searching for usage of .unbind() jQuery's function within JS code (or even HTML).
It turns out the span which the click event was being added to only occupied the central part of the button's graphic. Clicking directly on the glyph always fired the event, but clicking slightly outside (although seemingly still inside the button) would not raise the event.
I hope this helps anyone else using mini JQuery buttons in the same way they are presented on the JQuery UI ThemeRoller page.
I'm running jquery-ui-1.10.3 and I'm having the same intermittent issue with .toggle buttons -- they just aren't very responsive. I think it's inherent in jquery-ui because even on their demo page the toggle button feels less-than-awesome in terms of tactile response. If I click very slowly and deliberately I can usually get the button to toggle on and off but fast clicking is very hit or miss. I've tried all the tips to speed up jquery-ui but none have worked.

which HTML element lost focus?

in javascript, when I receive a focus event, how can I work out which element has lost focus? I'm trying to avoid having to put an onblur event handler on all elements within my web page.
#pbrodka: the target/srcElement property would refer to the element with focus for onfocus events
offhand I can't see a way to get this short of onblur, or if the set of objects you care about all have focus methods you could store a reference to that object instead. It's also possible event bubbling could get you out of jail
this all feels like a bit of a code smell though - perhaps you need to describe the problem in more detail
Difficult this. You cannot use event delegation to find out which control last produced a blur as focus/blur do not bubble up. There have been some attempts to 'fix' this but they are buggy and not resiliant cross browser.
Could I ask you why do you need this information as maybe there is an alternative solution.
Unfortunately, the onblur event doesn't bubble, otherwise you could have handled it at the window level to always know when an element lost focus.
As things are, I do believe it will be hard to do without, as you say, adding an onblur event handler to all elements (a truly nasty solution ;-).
It is possible to delegate the focus and blur events, if you follow PPK's advice, here:
http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
The most simple solution is to write a function that walks all forms and then all elements within the form and installs an onblur handler for each (which will probably call some global function). This handler will get an event and this event will contain the info you seek.
This way, you just have to call this method once in body.onload and it will work no matter how complex your document is.
The only drawback is that you will need to call it if you dynamically add forms to your current document. In this case, you must make sure not to install the handler again (or you will get spurious duplicate events).

Categories