Append div to body when URL hash # changes - javascript

I'm using curtain.js and would like to keep a DIV (which holds navigation) visible at all times except for when the user is looking at the very first panel, i.e. at the top of the page.
Currently the DIV resides within panel two
I'm thinking perhaps of using the hash change as you scroll through the page to trigger an append to the body. Curtain.js creates an individual URL for each panel and the URL changes each time a panel is brought into view.
I can append the div to the body (below) but I need to work out when to do this but I am unsure how? Could anyone help me out?
$("body").append($('.nav-wrap'));

you can use onhashchange event:
The hashchange event fires when a window's hash changes
$(window).bind('hashchange', function() {
$("body").append($('.nav-wrap'));
})

You can use JQuery to bind the Event
$(window).bind('hashchange', function(){ ... });
And add some workarounds for when it doesn't have the onhashchange event.
jQuery - hashchange event

Ok well instead of using some hacky solution, after much digging around in the plugin's file, I just added:
$("body").append($('.nav-wrap'));
to the setHash function on line 491. Works a treat.

Related

Adding `click` event to child of `iframe` of `iframe` - not woking

I am trying to add a click event to one of the element which is nested inside of a iframe of iframe.
this is a iframe .ssueContentIframe under this, there is another iframe added as #SmartReportTabContent1 so inside of the second iframe element, I am trying to add a click event like this:
Basically, I don't know when both of iframe will be loaded and all elements will available, for future I am adding:
$('.ssueContentIframe').contents().find( '#SmartReportTabContent1' ).find('.ui-grid-selection-row-header-buttons.ui-grid-icon-ok.ui-grid-row-selected').on('click', function(){
alert('Hi');
});
But not working. what is the correct way to wait until both of iframe exist and add the click event to one of the element here?
Thanks in advance!
You need to use "contents" on the second iframe as well. to wait for it to load, you can use the "ready" event on the second iframe.
eg:
$("#SmartReportTabContent1").find("iframe").ready(function (){
// do something once the iframe is loaded
});
Update
refer to this question
Well I edit this, first do a load of the first iframe and check it loaded well, then do the function on click on the element.
$(function(){
$('#foo1').load(function(){
alert("Loaded");
$('#foo1').contents().find('iframe').contents().find('#test').on('click', function(event) {
alert("Working");
});
});
});
I tested it on my computer and worked perfectly, remember addind the library, if you don't add a library it won't work.
Just change the ID i used to your IDs.

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.

Is there a callback function for internal page links

On - window.location.hash - Change?
The above question talks about hash change while this question talks about callback whenever internal link is clicked
I have many links in a page that points to another location in the same page using # links. Whenever, I click one such link, the page scrolls to that location. But I need to adjust the scroll manually after the automatic scroll happens. So would like to know if there is any callback function for such events?
Also the event should fire if the # tag was present in the initial page load (not only when it is clicked with a link) and when the same link is clicked again (hashchange event won't fire in this case)
You can register one by calling this function on the element:
addEventListener('click', function(){/*update your stuff here/*});
in jQuery, it's even easier
$('a').on('click', function(){/*update your stuff here/*}); will update after every link click.
There is no specifica callback that I know of but you could bind a function to the window.onscroll (https://developer.mozilla.org/en-US/docs/DOM/window.onscroll) event. That will detect when the window has been scrolled by the links being clicked and will let you make your adjustments. Then only problem is that it will also fire off when a user scrolls the page normally.
Other than that you would add a class to all your # links that will allow you to detect when one has been clicked. In jQuery:
$("a.HASH-LINK-CLASS").on("click", function (event) { ... });

jQuery after ajax call, events with the same Ids stopped working

Not sure if this is a bug or I am not suppose be doing this.
I have a page with sidebars that loads the main body dynamically.
For page1, I have a callback for an element #id1, which works on initial load.
After the user navigates to page2, the main content will get replaced by contents of page2, which also has an element with #id1, they serve the same purpose. events are initialized there as well.
The problem is that everything on page 2 would work except the event associated with #id1.
If navigating back to page 1, #id1 wouldn't work as well.
After looking at the console, I found that when calling $("#id1") sometimes give me the initial load element (not destroyed?), which is probably the reason.
The ajax load simply uses:
$.get(path, function(data) {$('#main').html(data)});
Any idea what's going on here?
If the old elements are not 'properly destroyed in jquery', what is suppose to be done here.
While it's not clear exactly what you're binding, the solution is to use (depending on your jQuery version) live() or on() to ensure that you bind to elements that aren't in the DOM at execution time.
jQuery 1.7+: on()
$(document).on('click', '.selector', function() { ... });
jQuery <1.7: live()
$('.selector').live('click', function() { ... });
Remember that an ID should only occur once
Because you don't know what elements with ID's may still be living in the DOM after the Ajax call you should stick with classname's instead.
With that you can use jQuery's .live() to bind to elements that have been dynamically loaded.
You have to generate dynamic id for that. When you click the right bar option the id will generated and place the id in the body element "id" tag.So you know that which id is generated for which page. Call a javascript function on "onclick" event and pass that id to this function then call the body element as $("#id"+that generated_id).something;
I think this will help.

could jquery live solve this problem? table links are bound to click, ajax refresh of rows ruins things

I have a table, that I loop through using jquery and modify the href of each link.
IF someone pages through the table, the links are refreshed using ajax (page doesn't reload).
Now all my links are not modified since the table has refreshed.
Paging is done via a drop down list.
Can jquery live help in some way to re-apply the modifications to the urls that I do when the page initially loads up?
$("#someTableID").each(function () {
// modify href of links in each row, append ?user=342 to it.
}
There's a couple ways to approach this. You could go in any of the following directions, but your only limitation is how creative you can be:
First option would be to delegate the paging event to fire a loop as described above. After the content is finished loading, you can loop through the links modifying each individually.
Alternatively, you can store your query string modification as data in the link markup itself:
some link.
Then, you can create a delegate function to wire up your new urls(as they are clicked or any delegated event you choose):
$("body").delegate("a", "click", function(e) {
e.preventDefault();
var $this = $(this);
window.location = $.param.querystring($this.attr("href"), $this.metadata().myData);
});
For option 2, I'm using a couple of plugins, but those are not required for the idea. Plugins used are metadata and bbq. Metadata is built in to the edge version of jQuery and should be included in $.data() as soon as they make the next release(currently 1.4rc1). Custom attributes would also work in this scenario as opposed to metadata.
String appending is also an option, I'm just a fan of the jquery-bbq project as it provides a lot of power in url manipulation.
I've provided a jsFiddle sample here.
No, .live() can't help you. All that .live() and .delegate() do is help handle events from content that changes. It can't automatically fix things for you. The code that performs the ajax reload will have to apply all transformations to whatever is reloaded.
Try this:
$("#someTableID > tr").each(function () {
var $link = $(this).find('a');
$link.attr('href', $link.attr('href') + '?user=342');
}
You aren't actually hooking an event up to each link, you're just modifying the text for each link, correct? Then no, jquery.live() is the incorrect tool; it is a way of monitoring user events on the page. You're just trying to decorate existing text.
What you want is to connect a callback to the ajax handler to do the decorations to the new content of the page after it has been received by the ajax handler.
You may even want to hook the callback in after the new content has been received, but before it has been placed into the page, to make sure there's no possible race condition where the link exists but the extra material hasn't been added.
I suspect you're using load. Look to the jquery.ajax.load() source code, and see how you can replace it with a more robust callback handler using jquery.ajax().

Categories