Say I have a web page index.html. Suppose the client goes to index.html#section2. This should take the client to the section of the page with a block-level element having a name attribute of section2.
How do I detect this inline link in javascript? Specifically, if the user goes to index.html#section2, I want to run a certain function in javascript.
I am open to using jQuery as well. Thank you!
Use jQuery with this jQuery plugin
http://benalman.com/projects/jquery-hashchange-plugin/
Then you can do:
$(window).bind( 'hashchange', function( event ) {
if(window.location.hash === "#section2"){
// What you want to do
}
})
Or if you dont want to use jQuery just use onclick events.
JS:
function changed(){
setTimeout(function(){
if(window.location.hash === "#section2"){
// What you want to do
}
})
}
window.onload = changed; // In case user starts on #section2
Do a switch on the window.location.hash property.
switch(window.location.hash) {
case '#section1':
foo();
case '#section2':
bar();
}
Note - The hash property is supported in all major browsers.
Edit -
#IvanCastellanos is right about the new hashchange event and the lack of support in down-level browsers. If the OP needs to handle this situation then the overhead of the plugin may be necessary - as pointed out in his answer...
Related
Can someone explain to me what i am doing wrong in this code?
http://jsfiddle.net/14njfqef/
var isLoggedIn = function(state){
if(state == true) {
$("#content-container").show();
$("#account2").show();
$("#account").hide();
}
else(state == false){
$("#content-container").hide();
$("#account2").hide();
$("#account").show();
}
}
onload=function() {
isLoggedIn(false);
}
On load i want the divs to hide but then when i click the button i want the divs to show?
Is the boolean function set out in the correct way?
Piece below tries to re-arrange piece at OP. onload not appear clearly defined , not addressed , though could be attached to an event , i.e.g., window.onload = onload . Wrapped blocks in jquery .ready() event . Removed js onclick markup from html , included at script element , or loaded from file at jquery .on("click") event . Added strict comparison operator === (an added =) to if / else if statements. Changed input type to button. Added if to else portion of composition (see link posted at comments by Felix Kling).
Try
$(function() {
var isLoggedIn = function(state){
if(state === true) {
$("#content-container").show();
$("#account2").show();
$("#account").hide();
}
else if(state === false){
$("#content-container").hide();
$("#account2").hide();
$("#account").show();
}
};
isLoggedIn(false);
$("input[type=button]").click(function() {
isLoggedIn(true)
})
});
jsfiddle http://jsfiddle.net/guest271314/14njfqef/3/
changed your html to
<input type="submit" value="Boolean" id="toggle"/>
rewrote your js as
// JQuery run at start effectivly
$(document).ready(function() {
function isLoggedIn(state) {
if(state == true) {
$("#content-container").show();
$("#account2").show();
$("#account").hide();
}
else {
$("#content-container").hide();
$("#account2").hide();
$("#account").show();
}
}
// JQuery attaching a click event using an anonymous function
// and hard coding your isLoggedIn to true, passing variables is a bit more complicated.
$('#toggle').click(function() {isLoggedIn(true)});
isLoggedIn(false);
})
Well there's a few things I am not sure if you are aware of so I feel there's some responsibility on my end to make sure they are mentioned. They are a number of syntactical errors in your post that are stopping this from working so instead of addressing them I feel its necessary to update your view on what JQuery you are using as well as your selector choice.
First I would add a class structure to all of the div's to target them all at once so you can save on some lines of code. In production it's always better to have less code for all of your visitors to download because even a little bit of code can get out of control after enough hits on a webpage. Having to serve it kills speed and so does having to process three separate jquery selections as opposed to one.
I would change the HTML to...
<body>
<div id='content-container' class='boxes'>
Content Container
</div>
<div id='account' class='boxes'>
account
</div>
<div id='account2' class='boxes'>
account2
</div>
<input id="validateButton" type="submit" value="Boolean">
</body>
This way you can simply target all divs with $(".boxes"); ... I wouldn't recommend getting into the habbit of using $("div");
Next I would change the JQuery to being more JQuery friendly code. Its not always useful to use an onload event from pure Javascript to handle JQuery driven functions in correct time to the loading of DOM objects. Therefore you should use $( document ).ready( handler ) to handle this load event properly just in case it causes you problems down the road. The more common shorthand of this ready event is a simple $(function() { }); wrapper.
The rest of the code can be re-arranged to this....
var isLoggedIn = false; //<--Instantiate to false, make global to window level scope
//Load event Corrected For JQuery
$(function() {
$(".boxes").hide(); //<--Hide on load
//Add A Proper Updated Click Event To Button
$("#validateButton").click(function() {
isLoggedIn = true; //<--Should include real functionality not hand coded to true
checkLoginAndRespond(); //<--Validate Login Status
});
});
function checkLoginAndRespond() {
//If Logged, Show
if(isLoggedIn) {
$(".boxes").show();
//Else Don't
} else { $(".boxes").hide(); }
} //end function
Lastly, the version. New versions of JQuery have not been released for some time and seem to not be in the making so its a safe bet to use their most recent versions as it has thousands of pages of help for its syntax and it's very stable. I would recommend anything in the 2.0 or higher series JQuery.
I am assuming you have JQuery library loaded. Try
if (state) {
$("#content-container").show();
$("#account2").show();
$("#account").hide();
}
else{
$("#content-container").hide();
$("#account2").hide();
$("#account").show();
}
to solve your problem.
I'd like to execute a Javascript function myFunc(myParam) automatically when a HTML link is opened, how can I achieve this without breaking compatibility with current browsers?
Notes:
Function name is static whereas parameter is passed dynamically for each link.
I've seen similar questions on SO but personally I would prefer not to use any JS library (if possible), but just my own code
You can use a link like <A href="mypage.html#myParam">, then add this code to this page:
<BODY onLoad="pageLoaded();">
....
function pageLoaded() {
var hash = window.location.hash;
if (hash != "") {
myFunc(hash);
}
}
You can do this very nicely with JQuery. I can't give you an extensive answer (on my mobile phone), but this should be enough to give it a go: How do I run a jQuery function when any link (a) on my site is clicked
Several problems:
1) I am trying to make this script run more efficiently.
2) When the user clicks either pop out button it opens a windows and hides the element. (Currently I am using .detach() to remove the embedded video player because in Firefox .toggle() just hides the player but keeps the audio playing. Is there a better way to do this?
3) In theory by clicking the button again or closing the window manually it should un hide or .toggle() the element but does not for the video player due to detach().
4) If a user pops out the window manually closes it and then pops it out again to only close it once more the element does not .toggle() back.
See it in action here, http://www.mst3k.tv/.
$(document).ready(function() {
$('#lights').click(function(){$('#darkness').fadeToggle(500);});
$("#lights").toggle(function(){$("#lights").attr('id','lightsoff');},function(){$("#lightsoff").attr('id','lights');});
/**VIDEO**/
var videoWin;
$('#video-toggle').click(function(){
$('#video').fadeToggle(500);
$('#video').detach();
});
$('#video-toggle').click(function(){
if (videoWin && !videoWin.closed) {
videoWin.close();
return false;
}
videoWin = window.open(
$(this).attr('rel'),
'videoWin',
'width=600,height=480,toolbar=0,top=0,left=0,menubar=0,location=0,status=0,scrollbars=0,resizable=1');
return false;
}
);
var watchVideo = setInterval(function() {
if (videoWin.closed) {clearTimeout(watchVideo);$('#video').show(500)}
return false;
}, 1);
/**CHAT**/
var chatWin;
$('#chat-toggle').click(function(){
$('#chat').fadeToggle(500);
/*$('#chat').detach();*/
});
$('#chat-toggle').click(function(){
if (chatWin && !chatWin.closed) {
chatWin.close();
return false;
}
chatWin = window.open(
$(this).attr('rel'),
'chatWin',
'width=320,height=480,toolbar=0,top=0,left=601,menubar=0,location=0,status=0,scrollbars=0,resizable=1');
return false;
}
);
var watchChat = setInterval(function() {
if (chatWin.closed) {clearTimeout(watchChat);$('#chat').show(500)}
return false;
}, 1);
/*$("a.btn").fitText(1.2, { minFontSize: "6px", maxFontSize: "14px" });*/
});
It would be better if you created a jQuery plugin for your code so you can re-use it and avoid DRY. Here are a couple of options:
Plugin 1: jQuery popupWindow
Plugin 2: jQuery winPop
Also note that the closed property is not part of any W3C specification, however it might be supported across Browsers.
You could also write a JS function that could be reused. According to the w3cschools website the window.closed property is supported in most major browsers and you can check for it prior to triggering the event.
instead of
if(videoWin && !videoWin.closed)
you could use
if (typeof videoWin!='undefined'){ /* it has been created */}
elseif(typeof videoWin='undefined') { /*it's okay to open the new window*/}
Make sure you're not creating the variable if you're using this as a check though until the window open event has been fired. Since you're creating the var a couple of lines above your function declaration it will always return as defined.
You'll need to specify a target object in your function to have it throw multiple windows correctly... meaning you can't declare one var for multiple windows. Maybe a class would be better.
Something I thought was odd earlier but forgot to mention before FB posted my response prematurely was that you're adding your href in the rel attribute and specifying the href as a js:void(0) which is also non-standard. The rel attribute is for specifying the relationship between the link and the page... (eg. rel=nofollow). That might also be why it's not firing and misfiring some of the time as well, and the differences between browser response.
I am writing a script that needs to detect elements added to a Web page, for example events rendered in a calendar (div tags). I don't care about elements that are removed. There should be at most 20-30 such elements on the page.
My idea - short and easy code - is to use a specific class ("myName") to brand elements already in the page. At regular intervals I would poll the page:
// Get all divs in the calendar:
var allDivsCount=myCalendar.querySelectorAll("div").length;
// Get already branded divs
var oldDivsCount=myCalendar.querySelectorAll("div.myName").length;
if (allDivsCount > oldDivsCount) {
// brand the new divs and do stuff
}
Is this a good practice, or is there a better way to do it? Are there libraries that already have such logic implemented?
I am trying to avoid DOMNodeInserted as some browsers don't support it and it is deprecated (due to performance issues, from what I've read).
I know that you're against DOMNodeInserted but I'll added it anyways for options (in case you're not supporting older version of IE).
I blogged about this a while back but it seems like the same solution still applies today (but like I said, depending on the browsers you currently support).
Example:
$(document.body).on('DOMNodeInserted', function (e) {
if (e.currentTarget.toString() === 'HTMLBodyElement') {
console.log(e);
}
});
This triggers any changes within the body not just the body itself.
$('#context').append($('<div />')); // triggers the event above
If you can intercept a DOM change (an AJAX call for instance) and create a global callback function, that would be ideal instead of the setInterval option.
var globalCallback = function() {
/** Do something when the DOM changes */
};
/** Global AJAX event to watch for all AJAX complete within the body */
$('body').ajaxComplete(globalCallback);
This is just one example (AJAX callbacks) of course.
Which is preferable, assuming we don't care about people who don't have JavaScript enabled?
Or
Is there any difference?
Or there any other ways I'm missing besides attaching an event to the anchor element with a JavaScript library?
The nice thing about onclick is you can have the link gracefully handle browsers with javascript disabled.
For example, the photo link below will work whether or not javascript is enabled in the browser:
foobar
it's better to use the onclick because that's the way the things should be.
The javascript: was somekind of hackish way to simulate the onclick.
Also I advice you to do some non intrusive Javascript as much as possible, it make the code more easy to read and more maintainable!
href="#" has a number of bad side effects such as showing # in the browser footer as the destination URL, and if the user has javascript disabled it will add a # at the end of their URL when they click the link.
The best method IMHO is to attach the handler to the link in your code, and not in the HTML.
var e = document.getElementById("#myLink");
e.onclick = executeSomething;
This is essentially the pattern you'd want to follow:
Write your HTML markup
Attach event handlers from JavaScript
This is one way:
<a id="link1" href="#">Something</a>
<script type="text/javascript">
// get a reference to the A element
var link1 = document.getElementById("link1");
// attach event
link1.onclick = function(e) { return myHandler(e); };
// your handler
function myHandler(e) {
// do whatever
// prevent execution of the a href
return false;
}
</script>
Others have mentioned jQuery, which is much more robust and cross-browser compatible.
Best practice would be to completely separate your javascript from your mark up. Here's an example using jQuery.
<script type="text/javascript">
$(function() {
$('a#someLink').click( function() {
doSomething();
return false;
});
});
</script>
...
some text
Yes I would agree to use onclick and leave the href completely out of the anchor tag... Don't know which you prefer to do but I like to keep the 'return false' statement inside by function as well.
The main difference is that:
The browser assume by default the href attribute is a string (target url)
The browser knows that in a onclick attribute this is some javascript
That's why some guys specify to the browser "hey, interpret javascript when you read the href attribute for this hyperlink" by doing ...
To answer the question, that's the difference!
OTOH what's the best practice when using javascript events is another story, but most of the points have been made by others here!
Thanks