Javascript function call on page both onload and onclick? - javascript

I need help with changing a function that is called once the page loads, and anytime afterwards when the user clicks on a certain div with an ID. So far I have this:
window.onload=function() {
//Do your stuff, JS!
}
Yes, I barely know any JS...
EDIT: I will include my JS function (I didn't make it myself, obviously another nice and smarter person did :P)
function() {
var maxHeight = 0;
//get the column containers
var colsA = document.getElementById("Content").childNodes;
//get the height of the tallest column
for(var i=0; i < colsA.length; i=i+1) {
if(colsA[i].clientHeight > maxHeight) maxHeight = colsA[i].clientHeight;
}
//set all the column containers heights to maxHeight
for(var i=0; i < colsA.length; i=i+1) {
if(colsA[i].nodeType == 1) colsA[i].style.height = maxHeight+'px';
}
}
What it does: I have a div container that houses x number of column divs. These columns vary at height due to content. This function makes all the divs heights the same.
When my page loads, this code runs flawlessly. However afterwards, it doesn't. I have some collapsible divs that house extra information, when a user clicks it will push the height further. This is why I thought of an onclick for that id... unfortunately the id is dynamically generated by php.

You can define a function separately and then bind it to multiple event handlers:
function myHandler(){...}
window.onload = myHandler;
myElement.onclick= myHandler;
...

This should fix it:
function f() {
// do your stuff
}
window.onload = f;
document.getElementById("myButton").onclick = f;

Another way:
window.onload=function() {
//Do your stuff, JS!
}
yourElement.onclick = window.onload;
In the end it does not matter how you do it. Functions are first class objects, so you just need to have a reference to the function.
To learn more about JavaScript, have a look at the MDC JavaScript Guide.

Related

jQuery show() doesn't work after hide()

I'm trying to display div with content after click on image, but when my page is loaded and I try to click then nothing happens. Interesting that if my page is loading with not hidden content and then I'll do hide() and after that show() id console then it works perfectly. What am I doing wrong?
$(document).ready(function() {
$('.content-flowers').hide()
var first = $(".content-flowers").children()[0];
var second = $(".content-flowers").children()[1];
var third = $(".content-flowers").children()[2];
var firstImg = $(".flower-image")[0];
var secondImg = $(".flower-image")[1];
var thirdImg = $(".flower-image")[2];
$(firstImg).click(function(){
$(first).toggle(1000);
})
/*$(".flower-image").click(function () {
$('.content-flowers').show(1000);
});*/
});
Last commented function works also good, but that function loads all three divs with content, I want in order to after click on 1 image the first div with content will display
You've said the commented-out version works other than that it does all three at the same time, but the earlier version does not work.
They do very different things. Your un-commented-out code looks at the children of the .content-flowers elements:
var first = $(".content-flowers").children()[0];
But your commented-out version works on the .content-flowers elements themselves:
$('.content-flowers').show(1000);
I suspect it's the .children() part that's making it fail. I think you want:
var first = $(".content-flowers")[0];
// No .children() here ----------^
...as the minimal change.
That said, though, the whole thing can be dramatically simpler:
$(document).ready(function() {
$('.content-flowers').hide()
// Get the flower images
var images = $(".flower-image");
// When a flower image is clicked...
images.on("click", function() {
// Determine its index relative to the others...
var index = images.index(this);
// And show that content
$(".content-flowers").eq(index).toggle(1000);
});
});
You already applied the jquery function on the variable first. So try first.toggle(1000) instead. Remove the $ sign.

Fade in and out div

My goal: fade in a div with text, after n seconds fade out. Do this again with 4 another divs, without interfere the div before (like showing up when the div before is still on screen) with consistent distances.
Here you can what I want to accomplish: https://www.youtube.com/watch?v=2PsCgs8rVHE (only the first moments).
Probably I am thinking too complicated.
I tried this for some time (hours, eh) now and tried thousand things. Here is my current code:
$('.quote').each(function(divID){
fadeContent(divID);
});
function fadeContent(childID)
{
$('.quote:nth-child('+childID+')').fadeIn(1000).delay(8000*childID).fadeOut(1000);
}
Before that I create the divs from array (works fine)
for(var i = 0; i < quotes.length; i++){
var quote_container = $('<div>').addClass('quote').append(quotes[i]).css('display', 'none');
$('.quotes').append(quote_container);
}
Appreciate your help a lot.
I had to code this: https://jsfiddle.net/dmpk42vd/
Here's an example of how you might go about it with jQuery:
$(".txt1").fadeIn("slow").delay(4000).fadeOut("slow");
$(".txt2").delay(6000).fadeIn("slow").delay(4000).fadeOut("slow");
$(".txt3").delay(12000).fadeIn("slow").delay(4000).fadeOut("slow");
$(".txt4").delay(18000).fadeIn("slow").delay(4000).fadeOut("slow");
$(".txt5").delay(24000).fadeIn("slow").delay(4000).fadeOut("slow");
EDIT: Added more or less delay depending on text length and made the entire thing work with one class. See comments and answers below for OPs.
I also made this a little bit more like Zelda :)
https://jsfiddle.net/dmpk42vd/2/
var delay = 0;
$('.txt').each(function (index) {
$('.txt').eq(index).delay(delay).fadeIn("slow").delay($(this).text().length * 30).fadeOut("slow");
delay += 6000;
});
Here is a slightly more dynamic way, wouldn't require adding additional CSS classes or Jquery
var delay = 0;
$('.quote').each(function (index) {
$('.quote').eq(index).delay(delay).fadeIn("slow").delay(4000).fadeOut("slow");
delay += 6000;
});
https://jsfiddle.net/80w1hnqh/

Adding a class while looping to an array

I have a list composed by some divs, all of them have a info link with the class .lnkInfo. When clicked it should trigger a function that adds the class show to another div (like some sort of PopUp) so it is visible and when clicked again it should hide it.
I am quite certain this must be a very basic thing and most likely I will get some scoffs...but hey! Once I have this down that's one thing less I will ever have to ask again. Anyway I am starting to leave the safety of html and css to start learning JS, PHP and the like and I came to a bit of a problem.
When testing it before it was working, that was until I added another div, it only worked with the first one, reading a bit and with some suggestion I realized it must be something related to a array, the problem is that I am not quite certain of the syntax for accomplishing what I am visualizing.
Any help would be deeply appreciated.
This is my JS code and below I will attack a Fiddle of how the html looks just in case.
var infoLab = document.getElementsByClassName('lnkInfo'),
closeInfo = document.getElementById('btnCerrar');
infoLab.addEventListener('click', function () {
for (var i = 0 ; i < infoLab.length; i++) {
var links = infoLab[i];
displayPopUp('popUpCorrecto1', 'infoLab[i]');
};
});
function displayPopUp(pIdDiv, infoLab[i]){
var display = document.getElementById(pIdDiv),
for (var i = 0 ; i < infoLab.length; i++) {
infoLab[i]
newClass ='';
newClass = display.className.replace('hide','');
display.className = newClass + ' show';
};
}
JSFiddle.
Thanks a lot in advance and sorry for any facepalms!
EDIT:
This a jQuery function (in another file) that I need to call using the link because it fetches the data that will be inside the div, thus why I wanted to just add a hide/show.
$(".lnkInfo").click(function() {
var id = $('#txtId').val();
var request = $.ajax({
url: "includes/functionsLabs.php",
type: "post",
data: {
'call': 'displayInfoLabs',
'pId':id},
dataType: 'html',
success: function(response){
$('#info').html(response);
}
});
});
EDIT 2:
To a future reader of this question,
If you managed to find this answer throughout space and time, know that this is how the solution ended being, may it help you in your quest to stop being a noob.
SOLUTION
Here is a rudimentary working example of how to make a popup appear after clicking on a specific element given your current code. Note that I added an id to your link element.
// Select the element.
var infoLink1 = document.getElementById('infoLink1');
// Add an event listener to that element.
infoLink1.addEventListener('click', function () {
displayPopUp('popUpCorrecto1');
});
// Display a the popup by removing it's default "hide"
// class and adding a "show" class.
function displayPopUp(pIdDiv) {
var display = document.getElementById(pIdDiv);
var newClass = display.className.replace('hide', '');
display.className = newClass + ' show';
}
Fiddle.
There are various ways to generalize this to work for all links/popups. You could add a data-link-number=1, data-link-number=2, etc to each link element (more on data-). Select an element containing all of your links. Bind to that element an event listener that, when clicked, detects the link element that was clicked (see event delegation / "bubbling"). You can determine which link was clicked based on the value of your data-link-number attribute. Then show the appropriate popup.
You may also want to use jQuery for this. Changing an element's class by setting it's className property makes for brittle DOM code. There is an addClass and a removeClass method available. jQuery's events also work cross-browser; element.addEventListener() will not work in IE8 which still has a significant market share.

Windows 8 Grid Template JS App, CSS manipulations dont show on all selected items in groupedItems view

I'm using the Win8 Grid View Template to display infos from a news site. In the lower menu bar i have implemented a function wich shuts off the titles, so that only the pictures are still visible.
This function is in a "global.js" file which is included in the "default.html" so it's available everywhere and it looks like this:
//function to turn titles off and on
function titleToggle() {
var titles = document.getElementsByClassName("item-overlay");
for (var i = 0; i < titles.length; i++) {
if (Global.titlesAreOn) {
titles[i].style.display = "none";
}
else {
titles[i].style.display = "";
}
}
Global.titlesAreOn = !Global.titlesAreOn;
};
So when i call this function from the menu bar it works for the first items, but when i scroll the end of the groupedItems view (hubview) the titles are still there. When i then scroll back to the beginning the titles are there again too.
I'm also calling the titleToggle function from the ready() function of the "groupedItems.js" to check whether or not to display the titles depending on a global variable. When i do that (whenever i come back to the hubpage) it works all the way, just as expected.
ui.Pages.define("/pages/groupedItems/groupedItems.html", {
navigateToGroup: function (key) {
nav.navigate("/pages/groupDetail/groupDetail.html", { groupKey: key });
},
ready: function (element, options) {
appbar.winControl.disabled = false;
appbar.winControl.hideCommands(["fontSizeBt"]);
appbar.winControl.showCommands(["titleToggle"]);
if (Global.titlesAreOn == false) {
Global.titlesAreOn = true;
Global.titleToggle();
}
I made a short video to show the problem, because its kinda hard to explain --> http://youtu.be/h4FpQf1fRBY I hope you get the idea?
Why does it work when i call it from the ready() function?
Does anyone have an idea? Is it some kind of automatic item caching in order to have better performance? And how could this be solved?
Greets and thanks!
First, here is why this might be happening - WinJS is using single page navigation for the app experience. This means that when you navigate to a new page, actually you don't. Instead the content is removed from the page and the new content is loaded in the same page. It is possible that at the moment you press the button not all elements have been loaded in the DOM and therefore they cannot be manipulated by your function. This is why when you call it from the ready() function it works - all contents are loaded in the DOM. It is generally better to do things in the ready() function.
About the behavior when you slide back left and the items are again reloaded with titles - for some reason the listView items are reloading. Maybe you are using live data from the news site and they are refreshing with the listView control's template again. I cannot know, but it doesn't matter. Hiding the elements is not the best approach I think. It is better to have two templates - one with a title element and one without. The button click handler should get the listView controls(they have to be loaded) and change their templates.
ready: function (element, options) {
var button = document.getElementById('btn');
button.addEventListener("click", btnClickHandler);
}
And the handler:
function btnClickHandler(e) {
var listView = document.getElementById("listView").winControl;
var template2 = document.getElementById("template2");
listView.itemTemplate = template2;
};

Trying to get a list of all the TR rows in Javascript

Sorry for any ignorance I have - my Javascript is not great.
Anyway, I have this in my header:
<script type="text/javascript">
var tableRows = document.getElementbyId("inventorytable").childNodes;
alert(tableRows)
</script>
As far as I know, it should grab the children of the table with the id of "inventorytable", correct?
Trying to eventually move down the tree of the DOM to the children of the children of the table (i.e. the TDs) and adding strings dependent on where in the table they're located. But for right now just trying to select the table's children and alerting them out.
I've added this code, still no alert:
<head>
<script type="text/javascript">
window.onload = function inventorytable() {
var tableRows = document.getElementbyId("inventorytable").rows;
alert(tableRows.length);
};
</script>
</head>
Try:
var tableRows = document.getElementbyId("inventorytable").rows;
alert(tableRows.length);
See https://developer.mozilla.org/en/DOM/table.rows
You should do either of two things:
put this code before closing </body> tag
wrap this with a function and attach that function as event handler to DOMReady or window load event.
The reason for this is that when your code is executed (when it's being read from within a script tag in the head) the DOM (the tree of HTML elements) is not yet read.
The second option could look like this:
window.onload = function () {
//your code here
var tableRows = document.getElementbyId("inventorytable").childNodes;
alert(tableRows);
};
DOMReady event is not supported cross-browserly, so there is a library that you can use to attach logic to that event – http://code.google.com/p/domready/
I suggest you read the explanation here: http://api.jquery.com/ready/, and if you are going to use jQuery, then you'd do it like this:
$(document).ready( function () {
// your code here…
// instead of writing `document.getElementbyId("inventorytable").childNodes;`
// you could do
var tableRows = $('#inventorytable').find('tr');
alert( tableRows );
});
Simple, use getElementsByTagName:
var tableRows = document.getElementById("inventorytable").getElementsByTagName("tbody")[0].getElementsByTagName("tr");
Note that tbody is require to work on IE browsers. Then loop these elements and alert them
for (var i = 0; i < tableRows.length; i++) {
window.alert(tableRows[i].tagName); // Or whatever...
}
This is a cross-browser technique, may work everywhere :)

Categories