Add a resize event handler only once - javascript

I have a widget that insert a div element in the DOM;
that div needs some js that handles the resize event;
the problem is:
the widget can be added multiple times on the same page, but I don't wanto to add many identical resize event handlers on the page (one, acting on the specific widget's class will be enough for all the widget instances);
the page that will embeed the widget can have its own resize event handler, that should not be deleted;
do you have any suggestion about how to implement this?

Honestly, I didn't get most of workflow explained as you didn't provide any html and js but I hope the following works for you:
var resized = 0; // works as a flag
$( window ).on('resize', function () {
if ( resized++ >= 1 ) return;
// do something here..
console.log('resized once'); // console.log as an example!
});
Good luck.

Related

JQuery doesn't work after a minute or two

My JQuery works well to allow the logo to pop up the mobile navigation but it doesn't work after a few minutes. It no longer changes the display of the UL when the logo is clicked Here is my code:
$(document).ready(function() {
checkSize();
});
function checkSize(){
if ($("ul, #left img:nth-of-type(2)").css("display") == "none" ) {
$("#click").on('click',function() {
$("ul, #left img:nth-of-type(2)").toggleClass("show-items");
});
}
}
Thank you.
From jQuery docs:
Code included inside $( document ).ready() will only run once the page
Document Object Model (DOM) is ready for JavaScript code to execute.
Your jQuery works, only you have specified to run it once.
UPDATE:
To run your script every time the window changes size use .resize()
The resize event is sent to the window element when the size of the
browser window changes:
// run once the document is lodaded
$(document).ready(checkSize);
// run on resize
$( window ).resize(checkSize);
Did you mean onclick event didn't working?
How many times you call checkSize() function?
May be you call it couple of times - so you bind couple onclick events.
And may be you call $("ul, #left img:nth-of-type(2)").toggleClass("show-items"); twice - so it toggle class twice. And it's looks like as "no effect".
Use debugger; in the first line of the onclick event and look in the developer tool how many times this event will be raised.
Also you can add $("#click").off('click'); before binding this event.

removing dynamic javascript tag does not remove attached events

i'm creating an application where a user can make a html layout and attach javascript to it.
Now i'm trying to make it so when they click a button, they go to a preview mode where they can see it in action.. so when they click i add the javascript tag ( with their javascript) in the head of the iframe.. this all works fine!
But the problem is when they leave the preview mode, i remove the javascript tag, however when i have code like this:
$('#button').click(function()
{
alert("ok");
});
it still alerts ok when i click the html button (when not in previewmode!), which shouldn't happen!
It seems that when removing the javascript tag, the listeners aren't removed.. Or am i doing it wrong?
Now my question: is there a way to make it so these added eventlisterens are removed when i remove the script tag?
AND YES: i know you can remove eventhandlers with .off(), but since i already have event handlers attached, these will be removed also, and i don't want this!
So two options i can think off:
- rebuild the whole iframe
- store the eventhandlers that were added by the user and when leaving the preview mode, removing them.
Thanks in advance
Each time you "evaluate" JavaScript, it becomes part of the browser's "image", and whether the source is present on the page no longer matters. You need to manually unbind the event, or replace the html segment to which the event was bound.
To remove events from an html element, you can use:
element.parentNode.innerHTML = element.parentNode.innerHTML
This rebuilds the DOM tree using the same HTML.
you need to unbind event.
You can do it by using jquery unbind() or off()
like this:
$("#button").unbind("click");
or
$("#button").off("click");
Demo: http://jsfiddle.net/a6NJk/664/
jquery Doc: http://api.jquery.com/off/
Another good answer: Best way to remove an event handler in jQuery?
Set the event:
var $button = $('#button');
$button.on("click", function() {
alert("ok");
});
Take off the event:
$button.off("click");
You can take off that specific function too
var $button = $('#button');
var eventFunction = function() {
alert("ok");
});
// Set event up
$button.on("click", eventFunction);
// Take event off
$button.off("click", eventFunction);
If you want to remove all events from an element you can use
$("#yourSelector").off()
Because it's not jQuery in general but also vanilla javascript, it would be too much work to keep track of javascript changes, so rebuilding the iframe would be the best option here.

How do I unbind events properly when using allowSamePageTransition in jQuery Mobile?

I'm using the jQuery Mobile option allowSamePageTransition, which enables me to go from
page A > page A > page A ...
I need this to allow browsing through a catalogue of items. My problem is, the items need some form of interaction and I used to attach the interaction binding to document, because it is set before the elements affected are generated.
However, reloading the same page over and over again will re-bind my event handlers every time I reload.
My first idea was to use .off when the page is being hidden, but reloading a page #foo, will trigger pagehide on the same page being shown, so all bindings set on
$(document).on("pagebeforeshow.foo_events", "#foo", function(e) {
// bind when shown
});
will be unbound again by the previous #foo being hidden
$(document).on("pagehide", "#foo", function (e) {
$(this).off(".foo_events");
// removes bindings on #foo being hidden AND shown
});
The only solution I have come up with is plastering the document with classes, which I don't like doing:
priv.setBindings = function (param) {
var doc = $(document);
doc
.filter(function() { return $(this).is(".e_gallery") !== true; })
.on("pagebeforeshow.gallery", param.pageId, function (e) {
doc.addClass(".e_gallery");
// run stuff
});
};
But I'm no fan of attaching classes to the dom.
Question:
Is there a way to prevent multiple event bindings set on $(document) when going to the same page over and over again WITHOUT toggling classes?
Solution 1
Best solution would be to use pageinit to bind events. If you take a look at an official documentation you will find out that pageinit will trigger ONLY once, just like document ready, so there's no way events will be bound again. This is best solution because you don't have processing overhead like when removing events with off method.
Working jsFiddle example: http://jsfiddle.net/Gajotres/AAFH8/
Of course this will fail in case multiple HTML solution is used.
Solution 2
Remove event before you bind it:
$(document).on('pagebeforeshow', '#index', function(){
$(document).off('click', '#test-button').on('click', '#test-button',function(e) {
alert('Button click');
});
});
Working jsFiddle example: http://jsfiddle.net/Gajotres/K8YmG/
Solution 3
Use a jQuery Filter selector, like this:
$('#carousel div:Event(!click)').each(function(){
//If click is not bind to #carousel div do something
});
Because event filter is not a part of official jQuery framework it can be found here: http://www.codenothing.com/archives/2009/event-filter/
This is probably best solution because event is going to be bound ONLY once.
Solution 4
Probably an easiest of them all.
$(document).on('pagebeforeshow', '#index', function(){
$(document).on('click', '#test-button',function(e) {
if(e.handled !== true) // This will prevent event triggering more then once
{
alert('Clicked');
e.handled = true;
}
});
});
Working jsFiddle example: http://jsfiddle.net/Gajotres/Yerv9/
This is a 180 percent different solution then solution 3, in this case event is going to be bound numerous times but it will be allowed to execute only once.
More info
If you want to find more about this problem take a look at this article, working examples are included.

How to add event handlers in jQuery to code which is rendered after the jQuery itself

EDIT: The Issue has been solved, as it turns out, the Select2 library had a custom command for this typa thing:
$("#element").on("change", function (e) { ... }
// Defined as "change"
I'm using a dropdown menu library called Select2 3.2. In short, the code takes a bunch of select and option tags, and generates a cool drop down search list.
However, after the site is rendered; when I click 'view source', all my select and option tags are still there, but when I right click the fancy new generated menus themselves and select "inspect element" (using google chrome), the html is TOTALLY different.
I think that this is causing the problem, all this new code is rendered from the custom library's JS, and after my jQuery event commands.
Specifically, here is my command:
$(document.body).on('click', '.select2-result-label', function() {
var name = $(this).text();
var post_to = '/myurl/';
$.post(post_to, { dat: dat},
function(response) {
...
}, 'json'
)
I believe the on() method takes care of this kinda stuff but apparently not, any help would be appreciated!
RELEVANT EDIT:
Here is a blurb from another Stack Overflow post:
The view page source page shows you the exact text that
was returned by the server.
Inspect element actually shows you the fully rendered DOM tree.
Knowing that, maybe solving this will be easier.
Here is a JS Fiddle related:
http://jsfiddle.net/JpvDt/47/
Try to make the alert "worked" appear when you click on an "x" in the multi bar.
Right now my code has it to register the class which contains the x's.
$(document.body).on("click", ".select2-search-choice-close", alert("worked"));
Scenario 1:
Your problem is may be 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.
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.
Scenario 2:
Call your on event like below (with off event).
$(#yourElement).off('click').on('click', '.select2-result-label', function() {
var name = $(this).text();
var post_to = '/myurl/';
$.post(post_to, { dat: dat},
function(response) {
...
}, 'json'
)
I hope this will help to you.
As it turns out, the Select2 library had a custom command for future changes to the toolbar.
Read more here: http://ivaynberg.github.com/select2/#programmatic
It's vital to note that many standardized jQuery calls won't work with Select2, you must use their custom set-up.
$("#element").on("change", function (e) { ... }
// Defined as "change"
Just replace $(document.body) by $(document)

Catching the Click on DOM/HTML/BODY event on the iPad

I'm using jQuery to detect a click on the DOM - or let's every click.
$(document).click(function(){
alert("Click :-)");
});
This works pretty good in every browser except Safari for iPad/iPhone. I've also tried to apply the event on the html or body element - no way. How to detect a common click on the iPad/iPhone?
Best regards,
Jim
As I found on http://www.danwellman.co.uk/fixing-jquery-click-events-for-the-ipad/ you may test the user agent and use touchstart or click depending on the platform
var ua = navigator.userAgent,
event = (ua.match(/iPad/i)) ? "touchstart" : "click";
$(document).on(event, function (ev) {
...
});
These answers got me started on the right direction (first google for "jquery document.on ipad"), so thanks for that, but borrowing from this answer I simplified it to something like this:
$(document).on("click touchstart", function (ev) {
...
});
This would obviously produce undesired results if a platform (like Android or Windows Phone or something) supported both click and touchstart in the event bubble, so if anyone knows that let me know (and I'll fix my code and delete this answer! :)
You may use the touchstart event instead.
I have used this:
jQuery(document).on('touchstart',function(event){
//your code here
});
-also instead of "document" you can bind to any DOM object.
and this(from another forum answer):
var body = document.getElementsByTagName('body')[0];
if ("ontouchstart" in window) {
body.ontouchstart = function(){
//your code here
};
};
-again, you don't have to use 'body' you can assign a variable to an object by class this way:
var dd = document.getElementsByClassName('infoAction')[0];
$('html').click(function(){
alert("Click :-)");
});
This works for me, I tested it now.
Even works with no content on page, wherever you click on the page.
You can attach the click listener to the main wrapper element (say div that encloses all the components in your page).
<body><div onclick="void(0)">
... your page tags ...
</div></body>
There is a minor difference with others browsers behaviour: the document object will reveive click events only for tags located inside the "... your page tags ..." section.
In other words, suppose your html and body tags have a yellow background color, and their child tags have a red background color.
The document object will receive clicks on the red areas only. This is usually not a serious drawback.
Tested on an iPhone 3 only

Categories