More efficient way script the heights of DIVs - javascript

Im using this script to find the height of a DIV. I am using it on more than one DIV.
Is there a more efficient way to write this code?
$(document).ready(function() {
$(".block00").height($(".subheader").height());
$(".block01").height($(".subheader").height());
$(".block02").height($(".subheader").height());
});

No need to list each one separately or make a loop as you can just list multiple items in the selector and it will return all of them.
$(document).ready(function() {
$(".block00, .block01, .block02").height($(".subheader").height());
});
or a little more efficiently:
$(document).ready(function() {
var h = $(".subheader").height();
$(".block00, .block01, .block02").height(h);
});
or, if you control the HTML source, add a common class on all the blockXX objects so you can do this:
$(document).ready(function() {
var h = $(".subheader").height();
$(".blockCommon").height(h);
});
Remember, you can have more than one class per object. Using a common class among several objects is precisely for the situation where you want to treat a number of objects the same way.

$(document).ready(function() {
var h=$(".subheader").height();
for(var i=0;i<3;i++)$(".block0"+i)height(h.height());
});
might work

Related

Detect if a div with id including number is clicked

My html code has X elements, with their ids in this form:
viewer_mX
Here, X is a number from 1 to m (m can be different each time).
I want to use javascript to get the number X of the respective element when somebody clicks one of these elements.
I realise I should probably use a class (.viewer) and and id (#x) containing the number. However, I am using a library to generate the html elements and I am stuck with this protocol and will have to make the best of it.
This is the javascript I have so far:
$(document).ready(function () {
$("#viewer>...").click(function () {
x = ...
var number = x;
});
});
What's missing in this code (indicated by 3 dots) is that viewer is not the full ID, but could be post-pended with something. I want to store whatever is after the clicked div in number, but I can't figure out which function to use for that.
Try this,
$("[id^='viewer_']").click(function () {
var number = this.id.match(/\d+$/)[0];
});
Why not use class to identify elements and then data-attribute for storing your id (data-id for example) and then get value of this data-attribute?
Otherwise I would personally use something like this
$(this).attr('id').substr("viewer_m".length);
Either split or a reg exp
var id = this.id.split("_m")[1]
or
var id = this.id.match(/\d+$/)[0];
or better yet, use a data attribute
<div data-mid="123">
and reference it
$("[data-mid]").on("click", function () {
var id = $(this).data("mid");
});
A better approach to this, as #Wax Cage mentioned, is to use classes and data attributes for better organizing. Example:
<div class="viewer" data-viewer-id="1">...</div>
$('.viewer').on('click', function() {
var viewerId = $(this).data('viewerId');
// ...
});

How to combine multiple scripts into one?

I've got five of the same scripts that just use five different variables. #video0 to #video4. I'm just not quite sure on how to combine them all so I don't have redundant code. I've been trying to make them all variables
var video= [
$('#video0'),
$('#video1'),
$('#video2'),
$('#video3'),
$('#video4')
];
http://jsfiddle.net/cwfybnzr/
Use each() with the array
var videos = [
$('#video0'),
$('#video1'),
$('#video2'),
$('#video3'),
$('#video4')
];
$(function() {
$.each(videos, function(){
var iframe = $(this)[0];
...
});
});
Isn't it better to create class for those elements? Then it will be possible to iterate through them using simple jQuery syntax: $('.video'). Plus it would not require changing any JavaScript code when new videos will be added.
You can add a class element like videoCSS to all the elements and then loop through them like
$('.videoCSS').each(function(){
var player = $(this);
// your code here
});
This way you can future proof you js code as you can add as many new player/iframes to the HTML with videoCSS class and your js code will still be the same.
Also, I found that in your code you are doing like
var iframe = $('#video0')[0];
var player = $(iframe);
Which means that first you are getting a jquery object using $('#video0'), then you are trying to get a DOM element out of it like $('#video0')[0] and then again you are converting it to a jquery object using $(iframe).
I think there is no need of this much extra processing, you can simply use
var player = $('#video0');
or using my updated code like
var player = $(this);
UPDATED FIDDLE

How to create a string and use a function that's named after it?

Sorry for bad wording in the question but it's hard to explain for me. I'm using several bxsliders on a page and some are placed in hidden divs. Unfortunately images are not shown in the slider after making the parent div visible unless the slider is reloaded (See here: bxSlider within show/hide divs). So let's say I initiate the sliders at the beginning with:
var slider_0=$("#slider_0 .bxslider").bxSlider({
//bxslider options here
});
var slider_4=$("#slider_4 .bxslider").bxSlider({
//bxslider options here
});
var slider_7=$("#slider_7 .bxslider").bxSlider({
//bxslider options here
});
The sliders are not consecutively numbered but there is a navigation and if I click the 7th element it leads to slider_7. So I could get the index of the clicked item with:
$(this).index();
When I call slider_7.reloadSlider(); it would work but I don't know which slider the user clicks and which number it has. So would it be possible to call that with a created string like this:
slider_name='slider_'+$(this).index();
slider_name.reloadSlider();
works not of course. Is there a way to do it?
I would create a dictionary with strings as keys and functions as values. Then, you could have O(1) lookup of the functions you're targeting.
In general, you can do it like so:
// set up your dictionary
var dictionary = {};
// add your functions
dictionary['methodName'] = function() {};
// call the functions
dictionary['methodName']();
So, for your example, you could do:
dictionary['slider_7'] = slider_7.reloadSlider;
dictionary['slider_'+$(this).index()]();
You could trigger it with
window["slider_" + $(this).index()].reloadSlider()
Although, I'm not sure whether your approach is the best. I think I'd go with arrays or with object (as a key-value pairs)
Try this:
slider_name='slider_'+$(this).index();
$("#" + slider_name + " .bx_slider").reloadSlider();
Found a working solution:
eval("slider_" + $(this).index()).reloadSlider();
Its not entirely clear here what you want/are trying to do. What it seems like you want to do is get a programmatic handle on a specific slider when a user clicks a specific part of your page. You do not accomplish this by eval()ing a string...that's what event handlers are for. So create a click event handler and in that event handler
$('#idOfWhatTheUserClicksOn').click(function(event) {
var slider = document.getElementById('#idOfRelatedSlider');
$(slider).bxSlider();
//if you need the current value of the slider you can get that too
var value = slider.value;
});
You could achieve the same with fewer LOC by using a class instead of id's with different handlers, but the concept is the same.
var slider_cache = [
$("#slider_0 .bxslider").bxSlider(),
$("#slider_1 .bxslider").bxSlider(),
$("#slider_2 .bxslider").bxSlider()
];
...
slider_cache[$(this).index()].reloadSlider();

Performing the same operation on multiple selectors, elegantly?

On the project I'm working on, I've been writing a little JavaScript object. One of its behaviors involve removing any children in a series of classes, as such:
function Foo () {
var $a = $('.a'),
$b = $('.b'),
// ...etc...
$n = $('.n');
$a.remove();
$b.remove();
// ...etc again...
$n.remove();
}
While there are some ways to revise this to be more easily maintainable (putting the selectors into a single array springs instantly to mind), I'm wondering if there's any elegant way to perform the .remove() operation on a series of selectors, as such:
function FooPrime() {
var selectors = [
'.a',
'.b',
// ...
'.n'
];
// Perform remove on all given selectors?
$(selectors).remove();
}
Thus, Question: What are some ways I could perform a single jQuery operation on a number of selectors?
EDIT: here is a JSFiddle to show a cut-down version of the problem context.
You can separate the selectors with commas:
$(selectors.join(',')).remove();
The comma has that purpose in straight ordinary CSS selector syntax.
Thanks for showing your DOM, you should avoid making big lists of classes to select when you can add multiple classes to elements and create a specific class for the elements you want to target... or target via association to other elements. This would be a more clean and efficient way to do it.
By association
Basically for the selector I just have this:
$("#test-callout").find("div").not(".callout-main").remove();
Fiddle
This assumes that you do not have any other div's besides .callout-main and the target div in test-callout. If you do you can modify the selector chain a bit to compensate.
By adding another class
Your arrow creation code was like this:
function calculateArrow() {
var arrowClass;
if(pub.isLeft) {
arrowClass = 'callout-arrow-left';
} else {
arrowClass = 'callout-arrow-right';
}
pub.$callout.append('<div class="' + arrowClass + '"></div>');
}
Modify it to be like this:
function calculateArrow() {
$arrow = $("<div>")
.addClass("callout-arrow")
.addClass(pub.isLeft ? "callout-arrow-left" : "callout-arrow-right");
pub.$callout.append($arrow);
}
Then your selector can be simply:
$("#test-callout").find(".callout-arrow").remove();
Fiddle
If you are interested in a complete refactor - I reduced your CalloutObject from 53 to 17 lines and it still works the same.
Fiddle

Check if objects within a variable are also contained in another variable (jQuery)

I hope the title somewhat sums up what I am trying to achieve.
Let's say I have two variables:
var one = $('div.foo, div.faa, div.fee, span, a, .all-sorts-of-objects'),
two = $('div.fii, div.foo, span, .all-sorts-of-objects-two');
And now, I want to check if objects contained within two are also contained within one. In other words, if there are any objects within both variables.
I need this so that I can set-up a non-overriding hover function (i.e. because I'm adding inline color-styles, I need to target my objects wisely). This is the logic I came up with: (note the if(one == two) which is essentially my question).
one.hover(function() {
if(one == two) { // if there is one or more objects in both variables..
$(this).css('color', 'red');
} else {
$(this).css('color', 'blue');
}
}, function() {
// ...
});
I hope I have been clear enough. If not, please let me know and I will do my best to explain this better.
Thank you very much!
Here is a quick and dirty way to do it:
var one = $('div.foo, div.faa, div.fee, span, a, .all-sorts-of-objects').addClass('one');
var two = $('div.fii, div.foo, span, .all-sorts-of-objects-two').addClass('two');
one.hover(function() {
if(one.hasClass('two')) {
$(this.css('color', 'red');
}
});
In my book the cleanest way (apart from refactoring to avoid these duplicate selectors if possible) would be to use the merge and unique jQuery utilities, something like:
var $merged = $.merge(one, two);
var $unique = $.unique($merged.get());
The $unique now has the unique, or, if you like, distinct elements.

Categories

Resources