jQuery event to detect when element position changes - javascript

I would like to know if there is a jQuery event that I can use to determine when a particular DIV's top property has changed.
For instance, I have invisible content above a DIV. When that content becomes visible, the DIV is shifted down. I would like to capture that event and then use the offset() function to get the X/Y coordinates.

The easy answer is that there are no events in the DOM for detecting layout updates.
You have a couple options the way I see it:
Poll, nasty but it may work depending on your update frequency requirements.
Tap into whatever event causes the invisible DIV to change size and do whatever you need to do in that handler
I shall correct myself.
I took a look at the DOM and noticed the DOMAttrModified event and found this JQuery Plug-In that you might be able to leverage to do what you want.
As the article mentions, it works great in IE and Firefox but seems to have problems in WebKit.

I thiiink you should be able to do:
$(document).ready( function (){
$("#mydiv").bind("movestart", function (){ ...remember start position... });
$("#mydiv").bind("moveend", function (){ ...calculate offsets etc... });
});

$("#someId").resize(function () {
// your code
});

Related

How to unbind() .hover() but not .click()?

I'm creating a site using Bootstrap 3, and also using a script that makes the dropdown-menu appear on hover using the .hover() function. I'm trying to prevent this on small devices by using enquire.js. I'm trying to unbind the .hover() event on the element using this code:
$('.dropdown').unbind('mouseenter mouseleave');
This unbinds the .hover of that script but apparently it also removes the .click() event(or whatever bootstrap uses), and now when I hover or click on the element, nothing happens.
So I just want to how I can remove the .hover() on that element, that is originating from that script, but not change anything else.
Would really appreciate any help.
Thanks!
Edit: Here is how I'm calling the handlers for the hover functions:
$('.dropdown').hover(handlerIn, handlerOut);
function handlerIn(){
// mouseenter code
}
function hideMenu() {
// mouseleave code
}
I'm trying to unbind them with this code.
$('.dropdown').unbind('mouseenter', showMenu);
$('.dropdown').unbind('mouseleave', hideMenu);
But its not working.
Please help!
**Edit2: ** Based on the answer of Tieson T.:
function dropdownOnHover(){
if (window.matchMedia("(min-width: 800px)").matches) {
/* the view port is at least 800 pixels wide */
$('.dropdown').hover(handlerIn, handlerOut);
function handlerIn(){
// mouseenter code
}
function hideMenu() {
// mouseleave code
}
}
}
$(window).load(function() {
dropdownOnHover();
});
$(window).resize(function() {
dropdownOnHover();
});
The code that Tieson T. provided worked the best; however, when I resize the window, until I reach the breakpoint from any direction, the effect doesn't change. That is, if the window is loaded above 800px, the hover effect will be there, but if I make the window smaller it still remains. I tried to invoke the functions with window.load and window.resize but it is still the same.
Edit 3: I'm actually trying to create Bootstrap dropdown on hover instead of click. Here is the updated jsFiddle: http://jsfiddle.net/CR2Lw/2/
Please note: In the jsFiddle example, I could use css :hover property and set the dropdow-menu to display:block. But because the way I need to style the dropdown, there needs to be some space between the link and the dropdown (it is a must), and so I have to find a javascript solution. or a very tricky css solution, in which the there is abot 50px space between the link and the dropdown, when when the user has hovered over the link and the dropdown has appeared, the dropdown shouldn't disappear when the user tries to reach it. Hope it makes sense and thanks.
Edit 4 - First possible solution: http://jsfiddle.net/g9JJk/6/
Might be easier to selectively apply the hover, rather than try to remove it later. You can use window.matchMedia and only apply your script if the browser has a screen size that implies a desktop browser (or a largish tablet):
if (window.matchMedia("(min-width: 800px)").matches) {
/* the view port is at least 800 pixels wide */
$('.dropdown').on({
mouseenter: function () {
//stuff to do on mouse enter
},
mouseleave: function () {
//stuff to do on mouse leave
}
});
}
else{
$('.dropdown').off('mouseenter, mouseleave');
}
Since it's not 100% supported, you'd want to add a polyfill for those browsers without native support: https://github.com/paulirish/matchMedia.js/
If you're using Moderizr, that polyfill is included in that library already, so you're good-to-go.
I still don't understand how you intend to "dismiss" the dropdown-menu once it is displayed upon mousing over the dropdown element partly because there's not enough code in your question, but that's sort of irrelevant to this answer.
I think a much easier way to approach the mousenter event handling portion is not by using off()/on() to unbind/bind events at a specific breakpoints, but rather to do just do a simple check when the event is triggered. In other words, something like this:
$('.dropdown').on('mouseenter', function() {
if($('.navbar-toggle').css('display') == 'none') {
$(this).children('.dropdown-menu').show();
};
});
$('.dropdown-menu').on('click', function() {
$(this).hide();
});
Here's a working fiddle: http://jsfiddle.net/jme11/g9JJk/
Basically, in the mouseenter event I'm checking if the menu toggle is displayed, but you can check window.width() at that point instead if you prefer. In my mind, the toggle element's display value is easier to follow and it also ensures that if you change your media query breakpoints for the "collapsed" menu, the code will remain in sync without having to update the hardcoded values (e.g. 768px).
The on click to dismiss the menu doesn't need a check, as it has no detrimental effects that I can see when triggered on the "collapsed" menu dropdown.
I still don't like this from a UX perspective. I would much rather have to click to open a menu than click to close a menu that's being opened on a hover event, but maybe you have some magic plan for some other way of triggering the hide method. Maybe you are planning to register a mousemove event that checks if the mouse is anywhere within the bounds of the .dropdown + 50px + .dropdown-menu or something like that... I would really like to know how you intend to do this (curiosity is sort of killing me). Maybe you can update your code to show the final result.
EDIT: Thanks for posting your solution!

javascript: detect when the appearance of the document has changed

Is there a way to detect when the appearance of the document has changed? For example:
$(document).on('change??', function () {
console.log('My aspect has changed');
});
// changes the appearance of a particular div
$('#my-div').css({width: 320, height: 240});
Also, is there a kind of 'render' event? This event would be fired every time the browser redraws the page. For example:
$(document).on('render', function () {
console.log('The page has been redrawn');
});
Don't know of any event like that, but if you are in control of all the changes you can easily cause your own events.
Here is a simple JQuery based example to illustrate the idea.
$( "#test" ).on( "mysitechanged", function( event, param1, param2 ) {
alert( 'changed' );
});
$( "#test").trigger( "mysitechanged", [ "Custom", "Event" ] );
http://api.jquery.com/trigger/
Here is info on how to do it in pure JavaScript
How to trigger event in JavaScript?
Since i think you're trying to detect whether the aspect has changed or not, this is what you're looking for.
window.onresize = function(){
// your code goes here;
}
Here is a good example of how the window.resize event is handled: http://jsfiddle.net/CoryDanielson/LAF4G/
I am on the lookout for that too. Apparently not. However it should be possible to implement one.
As far as I know, for the document to change appearance, one of the following is true:
The DOM has changed
The viewport changed (resize, orientation change, media changed, etc.)
You can detect changes to the DOM using MutationObserver, and detect viewport changes using native JavaScript events (onresize, etc.).
I am not sure whether this is necessary or useful (events should cover all realistic cases), but window.matchMedia(media).addListener() will also notify you about media changes to the viewport.
A DOM or viewport change does not necessarily imply a change of appearance, so then you should do some measurements on the page to verify whether anything changed.
More realistically and pragmatically, assuming that you build the page or app, you should be able to predict what would cause a change of appearance (ex: new content loaded through ajax, the user typed something in or clicked a button, new message received, page resized, etc.) and watch for these actions instead.

Using jQuery delegate (on) with a check box causes huge delay in response - why?

Hi I have a dynamically create table which acts as a pick list using check boxes. I Want these check boxes to be mutually exclusive. So upon checking a box I need to clear any other checked boxes.
$(document).on("keydown", "#list_Instructors input.allocate",function(event){
alert("hit");
$("#list_Instructors input.allocate").removeAttr('checked');
$(event.target).attr('checked', 'checked');
});
This sort of works but there is a huge delay between clicking and anything happening which is no good. I have tried all sorts of combinations with no success.
Is there is simple explanation as to why this is creating a delay.
Your problem is you bind on method for whole DOM which is really BAD.
So always try to bind that to the closest div (closest parent element) which your controls are exist.
And second thing is always cache your selectors for better performance.Like below
var dataTable=$('#dataTable');
dataTable.on("click", function(event){
alert($(this).text());
});
About Event performance from Jquery API says like below.
Attaching many delegated event handlers near the top of the document
tree can degrade performance. Each time the event occurs, jQuery must
compare all selectors of all attached events of that type to every
element in the path from the event target up to the top of the
document. For best performance, attach delegated events at a document
location as close as possible to the target elements. Avoid excessive
use of document or document.body for delegated events on large
documents.
What you might be seeing is that until the alert box is dismissed, the code afterwards is not executed. The alert command is a blocking one.
Perhaps you can use console.log() for debugging purposes of this feature. This will not block your code and it will be executed on the keydown event.
You need to use $(this) instead of going through another lookup. Also as stated above try to bind to the closest parent element if possible, for example a container div. With that said this should speed you up a bit:
$(document).on('keydown', '#list_Instructors input.allocate', function (event) {
//alert("hit");
console.log('hit');
$(this).removeAttr('checked');
$(event.target).attr('checked', 'checked');
});
But you should try to replace document with a container div or another parent element

Swipe event that work with live()?

I have elements on a page that are loaded dynamically, but I also need to be able to swipe on these divs.
I searched for jQuery swipe events, and found touchSwipe. This is nice because it's cross browser, but it does not allow me to use .on() or .live(), so the dynamic elements aren't accounted for.
Here's an example of what I mean, http://jsfiddle.net/wUkZq/
The only way I could get swiping to work on the dynamic elements was to attach the swipe event to the parent. Problem is, I don't want the parent to be swipeable. In the example, if you create a few elements with the a link, then try and swipe within .content, it will return the text of all elements, which is not what I'm wanting, as swiping should not be allowed in the parent.
Is there a better way to do this, or a better plugin? Ideally, I'd like to not use a plugin, but pure JS, but I can't find a good example of calculating when the person is actually swiping instead of some other event (i.e. scrolling).
How about simply assigning each swipeable element a specific class, then checking for that class in the swipe event handler? It's quite a common trick for such cases, I suppose. For example:
swipeLeft: function(event, direction, distance, duration, fingerCount) {
var $target = $(event.target);
if (! $target.hasClass('sw')) {
return false;
}
alert($target.text());
}
Here's a JS Fiddle illustrating the concept.

Javascript Custom Resize Event [duplicate]

This question already has answers here:
How to detect DIV's dimension changed?
(28 answers)
Closed 7 years ago.
I have a very simple question, or at least it seems that way.
I have a DIV element which will be resized at one moment. I want to be able to capture the resizing moment.
Something like this:
function myFunction(){
alert('The DIV was resized');
}
divElement.addEventListener("resize", myFunction, false);
Does anyone know the answer?
Thanks
As of December 2011, there's no built-in event to detect when a div resizes, just when a window resizes.
Check out this related question: Detecting when a div's height changes using jQuery, and this plugin from the solution to that question: http://benalman.com/projects/jquery-resize-plugin/
With jQuery resize event, you can now bind resize event handlers to
elements other than window, for super-awesome-resizing-greatness!
Why is a plugin needed for the resize event?
Long ago, the powers-that-be decided that the resize event would only
fire on the browser’s window object. Unfortunately, that means that if
you want to know when another element has resized, you need to
manually test its width and height, periodically, for changes. While
this plugin doesn’t do anything fancy internally to obviate that
approach, the interface it provides for binding the event is exactly
the same as what’s already there for window.
For all elements, an internal polling loop is started which
periodically checks for element size changes and triggers the event
when appropriate. The polling loop runs only once the event is
actually bound somewhere, and is stopped when all resize events are
unbound.
Sample Code
// You know this one already, right?
$(window).resize(function(e){
// do something when the window resizes
});
// Well, try this on for size!
$("#unicorns").resize(function(e){
// do something when #unicorns element resizes
});
// And of course, you can still use .bind with namespaces!
$("span.rainbows").bind( "resize.rainbows", function(e){
// do something when any span.rainbows element resizes
});
You can try this plugin - http://benalman.com/code/projects/jquery-resize/examples/resize/
There are various examples. Try resizing your window and see how elements inside container elements adjusted.
Example with js fiddle
In that resize() event is bound to an elements having class "test" and also to the window object and in resize callback of window object $('.test').resize() is called.
e.g.
$('#test_div').bind('resize', function(){
console.log('resized');
});
$(window).resize(function(){
$('#test_div').resize();
});
See this
My first thought is to use a custom event system. You can find a pure javascript one here ( http://www.nczonline.net/blog/2010/03/09/custom-events-in-javascript/ )
After including his code, you can do something like this:
function myFunction(){
alert('The DIV was resized');
}
div_elm = document.getElmentById('div-to-resize');
EventTarget.call(div_elm);
div_elm.addListener("resize", myFunction);
Then later, just add one line to wherever you are resizing the div.
div_elm.width += 100 //or however you are resizing your div
div_elm.fire("resize");
I think that should work for you.
EDIT:
If you are not the one coding the resizing, then my first thought is something like this:
var resizeScannerInterval_id = (function(div) {
var width = div.offsetWidth;
var height = div.offsetHeight;
var interval_id = setInterval(function() {
if( div.offsetWidth != width || div.offsetHeight != height )
width = div.offsetWidth;
height = div.offsetHeight;
div.fire();
}
},250);
})(document.getElementById('div-id'))
There is a very efficient method to determine if a element's size has been changed.
http://marcj.github.io/css-element-queries/
This library has a class ResizeSensor which can be used for resize detection. It uses a event-based approach, so it's damn fast and doesn't waste CPU time.
Please do not use the jQuery onresize plugin as it uses setTimeout() loop to check for changes. THIS IS INCREDIBLY SLOW AND NOT ACCURATE.

Categories

Resources