I have some JavaScript code and a button which already has an event/action assigned to it, and I want to add a second event to the button. Currently the relevant bit of code looks like this:
events: {onclick: "showTab('"+n+"')"},
How do I amend this code so that it also increases the 'width' property of a div with class='panel', by a fixed amount e.g. 50px?
EDIT:
I understand. Problem is I don't know how to change id, only classname. The div is constructed in JavaScript using buildDomModel as follows:
this.buildDomModel(this.elements["page_panels"],
{ tag: "div", className: "tab_panel",
id: "tab_panel",
childs: [...]}
)
But the id doesn't get changed to 'tab_panel'. HOWEVER, classname does get changed to 'tab_panel' which is why i tried to use getelementbyclass. So the div has no id and I don't know how to create one using the buildDomModel but I can give unique class. I have put the code in original post too.
This:
events: {onclick: "showTab('"+n+"'); $('div.panel').width('50px');"},
Or you might want to add below line to showTab function.
$('div.panel').width('50px');
Update:
Or you can do with vanilla javascript:
function setWidth()
{
// since you are using a class panel, means more than one div, using loop
var divs = document.getElementsByTagName('div');
for(var i = 0; i < divs.length; i++)
{
// check if this div has panel class
if (divs[i].getAttribute('class') === 'panel')
{
// set the width now
divs[i].setAttribute('width', '50px');
}
}
}
Or if you want to apply the width to just one specific div, give that div an id and use this function instead:
function setWidth()
{
var div = document.getElementById('div_id');
div.setAttribute('width', '50px');
}
And later use it like this:
events: {onclick: "showTab('"+n+"'); setWidth();"},
Or you might want to add below line to showTab function.
setWidth();
Update 2:
Ok modify the function like this:
function setWidth()
{
var divs = document.getElementsByTagName('div');
for(var i = 0; i < divs.length; i++)
{
// check if this div has panel class
if (divs[i].getAttribute('class') === 'tab_panel')
{
// get previous width
var prevWidth = getComputedWidth(divs[i]);
// set the width now
divs[i].setAttribute('width', (prevWidth + 50));
}
}
}
function getComputedWidth(theElt){
if(is_ie){
tmphght = document.getElementById(theElt).offsetWidth;
}
else{
docObj = document.getElementById(theElt);
var tmphght1 = document.defaultView.getComputedStyle(docObj, "").getPropertyValue("width");
tmphght = tmphght1.split('px');
tmphght = tmphght[0];
}
return tmphght;
}
Note that with jQuery it should be this code in all:
function setWidth(){
jQuery('.tab_panel').each(function(){
jQuery(this).attr('style', 'width:' + (jQuery(this).width() + 50));
});
}
instead of the function you can use this line of JQuery code:
$('div.tab_panel').attr('style',"width:100px");
any way if you dont want it to be JQuery then this function should work :
function setWidth() {
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
// check if this div has panel class
if (divs[i].getAttribute('class') === 'tab_panel') {
// set the style now
divs[i].setAttribute('style', 'width:100px');
}
}
}
putting width attribute to div wouldnt work, you need to set its style,
so i expect any of the code i provided to work.
oh no the one i sent early just set width to a new value
this one should fix your problem :
var x = $('div.tab_panel')[0].style.width.replace("px", "");
x = x + 50;
$('div.tab_panel').attr('style', "width:" + x + "px");
ok here is a non JQuery Version :
function setWidth() {
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
if (divs[i].getAttribute('class') === 'tab_panel') {
var x = divs[i].style.width.replace("px", "");
x = x + 50;
divs[i].setAttribute('style', 'width:' + x + 'px');
}
}
ok here it is :
JQuery:
function Button1_onclick() {
var x = $('div.tab_panel')[0].clientWidth;
x = x + 50;
$('div.tab_panel').attr('style', "width:" + x + "px");
}
non JQuert:
function setWidth() {
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
if (divs[i].getAttribute('class') === 'tab_panel') {
var x = divs[i].offsetWidth;
x = x + 50;
divs[i].setAttribute('style', 'width:' + x + 'px');
}
}
}
this should work
Related
I want to check the height of an element every time the site changes, because of a viewport resize or a click event.
At the moment I'm using the following code:
jQuery(function ($) {
var height = document.getElementById("head").offsetHeight;
var x = document.getElementsByClassName("dropdown-menu");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.top = height + 'px';
}
});
It's possible that the height of "head" changes. So I need to check the actual height if there are any changes at the site/viewport.
Is there a way to do so?
You can check on window resize
$( window ).resize(function() {
//check element height
});
You can use onresize event listener of javascript
var header= document.getElementById("head")
header.addEventListener('onresize', function(){
// do your code here
});
var element = document.getElementById("head"),
height;
function eventHandler () {
height = element.offsetHeight;
console.log(height);
// rest of your code
}
window.addEventListener('resize', eventHandler)
element.addEventListener('click', eventHandler)
You can bind two different event listeners and pass the same function as a callback if you want to share code logic and reduce redundancy.
My solution:
$( window ).ready(function() {
var height = document.getElementById("head").offsetHeight;
var x = document.getElementsByClassName("dropdown-menu");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.top = height + 'px';
}
});
$( window ).click(function() {
setTimeout(function() {
var height = document.getElementById("head").offsetHeight;
var x = document.getElementsByClassName("dropdown-menu");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.top = height + 'px';
}
}, 500);
});
$( window ).resize(function() {
var height = document.getElementById("head").offsetHeight;
var x = document.getElementsByClassName("dropdown-menu");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.top = height + 'px';
}
});
The timeout is for the correct height after the click and an animation.
I have a hex colour value stored on each section and when a section reaches the top of the screen (-180px for the header) I want to assign a css property to the header element in order to change the text colour as you scroll through the sections. I am not getting any errors and I am having trouble debugging this issue.
http://www.amypreston.co.uk/
$(window).load(function() {
var $header = $("header");
var numberOfSections = $("section").length;
var sectionOffsets = [];
var sectionColour = $("section").eq(i).data("colour");
for(var i = 0; i < numberOfSections; i++) {
sectionOffsets.push($("section").eq(i).offset().top);
}
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
for(var i = 0; i < numberOfSections; i++) {
if(scrollTop > sectionOffsets[i] - 180) {
$header.css('color', 'sectionColour');
}
}
});
});
I dont know if it happened by accident, but the line
var sectionColour = $("section").eq(i).data("colour");
is out of place. it uses a variable i which is only defined in the window scroll handler.
notice that you need to retrieve the section color each time the scroll handler runs, and not only on window load. you need to place this line from above in the loop inside the scroll handler.
Plus, as stated on the comments, you need to use the sectionColour as a variable, and not as a string like you do now. the single quote marks must be removed, so 'sectionColour' turns into sectionColour.
here is your fixed code:
$(window).load(function() {
var $header = $("header");
var numberOfSections = $("section").length;
var sectionOffsets = [];
for(var i = 0; i < numberOfSections; i++) {
sectionOffsets.push($("section").eq(i).offset().top);
}
$(window).scroll(function() {
var scrollTop = $(this).scrollTop();
for(var i = 0; i < numberOfSections; i++) {
if(scrollTop > sectionOffsets[i] - 180) {
var sectionColour = $("section").eq(i).data("colour");
$header.css('color', sectionColour);
}
}
});
});
On a side note, you could shorten your code into this:
$(window).scroll(function () {
$("section").each(function () {
if ($(window).scrollTop() > $(this).offset().top - 180) {
$("header").css('color', $(this).data("colour"));
}
});
}).scroll();
As I'm trying to create a grid of images for my background, I need to be able to add the background-image attribute to the css of the body via jQuery, but it isn't working. The following code returns the correct value, but all I see in the end is a blank page.
<body>
<script>
$('body').css('background-image', function() {
var position = 0,
image = '';
for(var x=1; x<=4; x++) {
// 4 rows
for(var y=1; y<=8; y++) {
// 8 columns
position++;
image += 'url(img/bg/' + position + '.jpg)';
if(x<=4 && y<8) { image += ','; }
}
}
console.log(image);
return image;
});
</script>
As you can see, I'm doing the script work after the body tag is created, so my understanding is that I don't need $(function(){}) to make things happen.
Can anyone see what's keeping this from working?
Your if condition is wrong, so you're leaving out the , after every 8 URLs.
$(function() {
$('body').css('background-image', function() {
var position = 0,
image = '';
for (var x = 1; x <= 4; x++) {
// 4 rows
for (var y = 1; y <= 8; y++) {
// 8 columns
position++;
image += 'url(img/bg/' + position + '.jpg)';
if (x < 4 || y < 8) {
image += ',';
}
}
}
console.log(image);
return image;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
The way I prefer to do things like this is to push the elements onto an array, then construct the string using array.join(',').
I'm trying to write a function to vertically center elements if they have a class called "vcenter(#)". For example, vcenter1 vcenter2. It's supposed to take the element's parent's innerheight and subtract the element's innerheight then divide by 2. The value then is applied to the css as the margin-top. It doesn't work though. Please help!
$(document).ready(function(){
for (i=1; i<3; i++){
var childID = $(".vcenter" + i);
var parent = childID.parent().innerHeight();
var child = childID.innerHeight();
var marginTop = (parent - child)/2 + 'px';
$(childID).css({"margin-top", marginTop})
}
});
How about this...
http://jsfiddle.net/mVn9S/
$(document).ready(function () {
$('.vcenter').each(function () {
var parent = $(this).parent().innerHeight();
var child = $(this).innerHeight();
$(this).css({
'margin-top': ((parent - child) / 2) + 'px'
});
});
});
Have you considered using CSS3 Flexbox with a polyfill for old versions of IE? Might be less work.
Change your code to look like this:
$(document).ready(function(){
for (i=1; i<3; i++){
var childElement = $(".vcenter" + i);
var parent = childElement.parent().innerHeight();
var child = childElement.innerHeight();
var marginTop = (parent - child) / 2;
childElement.css({"margin-top": marginTop});
}
});
Notice use of ; at the end of lines - it's a good habit even in JS.
I don't know how your HTML looks but probably this could be easily generalized for all elements with .vcenter class:
$(document).ready(function(){
$('.vcenter').each(function() {
var childElement = $(this);
var parent = childElement.parent().innerHeight();
var child = childElement.innerHeight();
var marginTop = (parent - child) / 2;
childElement.css({"margin-top": marginTop});
});
});
I have a little bit of Javascript that almost works correctly. Here's the code:
function toggle(curlink) {
curlink.style.backgroundColor = curlink.style.backgroundColor == "yellow" ? "transparent" : "yellow";
var maindiv = document.getElementById("grid");
var links = maindiv.getElementsByTagName("a");
var list = "";
for (var i = 0; i < links.length; ++i) {
var link = links[i];
if (link.style.backgroundColor == "yellow") {
list += ("," + parseInt(link.style.left, 10) + "-" + parseInt(link.style.top, 10));
}
}
document.theForm.theList.value = list.substring(1);
return false;
};
window.onload = function() {
var links = document.getElementById("grid").getElementsByTagName("a");
for (var i = 0; i < links.length; ++i) {
links[i].onclick = function() { return toggle(this); }
}
};
The issue is with line #9; it only works when I specify values for the top and left style property of every link in the array. How do I get the top and left style property values (or X and Y coordinates) of each link in the array with Javascript when those values aren't given?
Also, what would the code above look like in jquery? Not that it's needed - I just want to reduce the code a little and dabble in the jquery framework (I'm a Javascript newbie).
Thanks in advance,
Dude-Dastic
link.offsetLeft and link.offsetTop. More about finding position here. They'll be positions relative to the offsetParent, but the link shows a way to get position relative to the document.
offsetParent will evaluate to the body if the parent elements are positioned statically or there's no table in the parent hierarchy. If you want a position other than body then update the parent of the links to have a non-static position, perhaps relative
I'm not familiar with JQuery so I can't help there
The jQuery might look something like this. Untested.
$(function(){
// Get all <a> descendents of #grid
var $anchors = $('#grid a');
// Bind a click handler to the anchors.
$anchors.click(function(){
var $clickedAnchor = $(this);
var coordinates = [];
// Set the background color of the anchor.
$clickedAnchor.css('background-color', $clickedAnchor.css('background-color') == 'yellow' ? 'transparent' : 'yellow');
// Loop through each anchor.
$anchors.each(function(){
var $anchor = $(this);
if ($anchor.css('background-color') == 'yellow') {
var offset = $anchor.offset();
coordinates.push(offset.left + '-' + offset.top);
// Or maybe..
// var parentOffset = $('#grid').offset();
// coordinates.push((offset.left - parentOffset.left) + '-' + (offset.top - parentOffset.top));
}
});
$('#theList').val(coordinates.join(','));
return false;
});
});