find object with position top > x using jquery - javascript

what is the best way to find first element in the html document with the class myClass with position top greater than specified

Filter the .myClass elements based on position top, and then get the first element in the collection:
var elem = $('.myClass').filter(function() {
return $(this).position().top > 200;
}).first();
This will get you the first element with a distance from the top inside it's containing element above 200px etc. To get the position relative to the document you could use offset() instead.
If performance is an issue, I guess this is the fastest:
var elems = document.getElementsByClassName('myClass'), elem;
for (var i=0;i<elems.length;i++) {
if (parseInt(elems[i].style.top, 10)>200) {
elem=elems[i];
break;
}
}

Wrong (first answer) :
var $elm = jQuery.each($('.myClass'), function() {
if ($(this).attr('top') > x) return $(this);
});
Ok :
var $elm;
jQuery.each($('.myClass'), function() {
if ($(this).attr('top') > x) {
$elm = $(this);
return false;
}
});
This solution does not parse all .myClass elements, just returns the first one and stops.

Related

How to make the height of a each div equal height with JavaScript?

I am trying to make an object that will determine the highest height of a set of elements and make each element match the height of the largest.
In this object, I am trying to pass a selector to a JQuery method which resides inside of my object method. Unfortunately I am not able to get each item this way and my Each statement does not fire but the object returns 0 items.
Below is an example of my object:
var heightBalance = {
containerName: '',
childElements: '',
alert: function() {
var divs = $(this.childElements);
console.log(divs);
$.each(divs, function(index, value) {
console.log('working');
});
}
}
heightBalance.containerName = '#containers';
heightBalance.childElements = 'div';
heightBalance.alert();
#one {
background-color: green;
width: 50px;
height: 200px;
}
div {
width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="containers">
<div id="one">d</div>
<div id="two"></div>
<div id="three"></div>
<div id="four"></div>
<div id="five"></div>
</div>
You're script is initialized in the head, before the divs are rendered. Move the script to the end of the body, or use jQuery ready function (fiddle):
$(function () {
var heightBalance = {
containerName: '',
childElements: '',
alert: function () {
var divs = $(this.childElements);
console.log(divs);
$.each(divs, function (index, value) {
console.log('working');
});
}
}
heightBalance.containerName = '#containers';
heightBalance.childElements = 'div';
heightBalance.alert();
});
The code in this answer will give you the equal heights you want:
$(function() {
// Get an array of all element heights
var elementHeights = $('.features').map(function() {
return $(this).height();
}).get();
// Math.max takes a variable number of arguments
// `apply` is equivalent to passing each height as an argument
var maxHeight = Math.max.apply(null, elementHeights);
// Set each height to the max height
$('.features').height(maxHeight);
});
As the poster above states, your code is initializing in the head before your elements have loaded. If you looked at the object in the console, you can see that the object was referencing the root of your entire document. For future reference, in fiddle, under "Frameworks and Extensions" switching the second dropdown from "nowrap - in head" to "onload" can achieve the same result as the previous answer.
You're defining 2 variables. I assume the intention is to define a context - heightBalance.containerName
and then search that context for the highest child and modify all children to match that height. heightBalance.childElements.
Your function doesn't make use of heightBalance.containerName. so $(this.childElements) just looks for any div on the page. in the console, you can see that the container is being listed along with the child elements.
You probably want to change it to something more like var divs = $('#containers').find('div') or shortform $('div', '#containers')
alert: function(){
var divs = $('#containers').find('div')
console.log(divs);
$.each(divs, function(index, value){
console.log('working');
});
}
I modified my code a little and got this to work. Thank you for everyone showing me when I need to initialize JQuery to get this functioning.
var heightBalance = {
containerName: '',
childElements: '',
heightArray: [],
calc: function(){
var divs = $(this.containerName + " " + this.childElements);
$.each(divs, function(index, value){
var innHeight = $(value).height(); ;
heightBalance.heightArray.push(innHeight);
});
this.largestHeight(this.heightArray);
},
largestHeight: function(data)
{
var i = data.indexOf(Math.max.apply(Math, data));
$(heightBalance.childElements).height(this.heightArray[i] );
}
}

JavaScript Jquery function that is triggered on event executes all at once instead of right time

I made a function that Is made to be trigered when user scrolls on a element on the page. In this case when user scrolls to an id then it fades in. The problem is that they fade in all at the same time with the first scroll instead of when they reaching the element That is supposed to allow it to fade in! Please help me make my function work.
Thanks a lot
var selected={
//// Storing selectors
items:[],
/// Function that stores items and hides them from the page
selectFunc: function(select) {
//// Store selected element
selected.items.push(select);
/// hide selector from the page
$(select).hide();
}
};
//// Function triggeres on scroll
$(window).scroll(function() {
/// loops trough the selected elements
for(i=0; i<selected.items.length; i++){
var currentItem = selected.items[i];
///// calculates your position and item position
var hT = $(currentItem).offset().top,
hH = $(currentItem).outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop();
////// check if you are in the position
if (wS > (hT+hH-wH)){
$( currentItem ).fadeIn( 2500 );
}
}
});
//// Using my function to select id about and p element in it.
selected.selectFunc("#about p");
selected.selectFunc("#about input");
In your for loop, you are doing an iteration for each element in selected.items. What's in there? Two strings: "#about p", and "#about input".
So for each of these selectors, you show them all. You need to get every element separately.
Another problem is that hiding these elements means they are not taking up the space they should on the page, so you might not be able to scroll down. You can solve that by changing their opacity instead of making them display:none (what .hide() is doing).
Here is your code with some modifications:
var selected = {
//// Storing selectors
items: [],
/// Function that stores items and hides them from the page
selectFunc: function(select) {
//// Store selected element
var items = $(select);
for (var i = 0, l = items.length; i < l; i++) selected.items.push(items[i]);
/// hide selector from the page
items.css('opacity', 0);
}
};
//// Function triggeres on scroll
$(window).scroll(function() {
/// loops trough the selected elements
for (i = 0; i < selected.items.length; i++) {
var currentItem = selected.items[i];
///// calculates your position and item position
var hT = $(currentItem).offset().top,
hH = $(currentItem).outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop();
////// check if you are in the position
if (wS > (hT + hH - wH)) {
$(currentItem).animate({
'opacity': 1
}, 2500);
}
}
});
//// Using my function to select id about and p element in it.
selected.selectFunc("#about p");
selected.selectFunc("#about input");
// Simulating a scroll to show the first elements
$(window).scroll();
JS Fiddle Demo

how to highlight a word given coordinates

I found this code: (result of the script):
HTML
<p>Each word will be wrapped in a span.</p><p>A second paragraph here.</p>Word: <span id="word"></span>
JAVASCRIPT
// wrap words in spans
$('p').each(function() {
var $this = $(this);
$this.html($this.text().replace(/\b(\w+)\b/g, "<span>$1</span>"));
});
// bind to each span
$('p span').hover(
function() { $('#word').text($(this).css('background-color','#ffff66').text()); },
function() { $('#word').text(''); $(this).css('background-color',''); }
);
I would like something similar. What I need to do is to obtain the same result but instead of highlighting the word (span tag) under the cursor I need to highlight a word (span tag) given the coordinates in pixels.
Does anyone know if this is possible and how can I do it? Or is there another way?
Thank you!
Maybe you want to use elementFromPoint(). It's really simple to use, you need to pass the coordinates and this function will return an element under the point.
For your particular case, every word must be in an independent element span, div or whatever.
See the working example: jsfiddle
Maybe you want to make some more robust solution, and add a condition if in the given coordinates there is not an element (elementFromPoint() return its ancestor or the body element or NULL if coordinates are not in visible part)
This is relatively easy once every word token is wrapped in a span. You can use jQuery's .position(), .width() and .height() functions to determine if an element overlaps with a given set of x,y coordinates.
Something as simple as
var x = 100, y = 100;
$("span.token").filter(function () {
var $this = $(this), pos = $this.position();
return y >= pos.top && y <= pos.top + $this.height() &&
x >= pos.left && x <= pos.left + $this.width();
})
finds the element(s) at position 100,100.
However. Your "wrap words in spans" function is wrong and potentially dangerous. It must be rewritten to a more complex, but in exchange safer approach.
I've created a .tokenize() jQuery plugin that walks the DOM tree and works on substitutes all text nodes it finds, wrapping them in a configurable bit of HTML:
$.fn.extend({
// this function recursively tokenizes all text nodes in an element
tokenize: function (wrapIn) {
return this.not(".tokenized").each(function () {
$(this).addClass("tokenized").children().tokenize(wrapIn);
$(this).contents().each(function () {
var node = this,
parent = this.parentNode,
tokens, tokenCount;
// text node: tokenize, dissolve into elements, remove original text node
if (node.nodeType === 3) {
tokens = $(node).text().replace(/\s+/g, " ").split(" ");
tokenCount = tokens.length;
$.each(tokens, function (i, token) {
if (token > "") {
parent.insertBefore($(wrapIn).text(token)[0], node);
}
if (i < tokenCount - 1) {
parent.insertBefore(document.createTextNode(" "), node);
}
});
parent.removeChild(node);
}
});
});
}
});
Usage:
$("p").tokenize("<span class='token'>");
See a live example here: http://jsfiddle.net/u5Lx6e2a/

Javascript - Pull attribute into array/delete items based on attribute

I want to pull into an array the classes of all of the <img> in a particular <div> and then use those classes to delete the first <img> that shares that class in a different <div>.
So far, I have this that calls the original array:
var class = $('.frame div img').each(function() {
return $(this).class;
}).get();
class.forEach(function(entry) {
console.log(entry);
});
The log outputs a list of the <img></img> lines.
After that, I get stuck.
//Iterate through array and delete first <img> in #grid that has the same class, limit one per iteration.
// var img_class = $.each(class, function(key, value) {
// console.log(value);
// return $(this).attr('class');
// });
$('#grid img').each(function(){
if($(this).attr('class') == img_class){
$(this).remove();
}
});
The goals are:
Getting an array of classes into the img_class variable
Delete only the first <img> as it iterates through each class in the array
Thanks!
I am not sure if I understood it right but would something like this be of any help?
var firstIDs = "";
$('.frame div img').each(function() {
firstIDs += $(this).attr('id') + ",";
});
var SplitIDs = firstIDs.split(",");
$('#grid img').each(function(){
for(var i = 0; i < SplitIDs.length; i++) {
if($(this).attr('id') == SplitIDs[i]){
$("#grid img #"+$(this).attr('id')+":first").remove();
}
}
});
I would suggest to use some other attribute than class, eg. 'data-type'.
With the collected attribute values (e.g. 'types' array) do:
var $grid = $('#grid');
// iterate over collected types
types.forEach(function(type)) {
// find within $grid the first <img> with data-type == type and remove it from DOM
$grid.find('img[data-type="' + type + '"]:eq(0)').remove();
}
You could also do all in one rush:
// iterate over source <img> set
$('.frame div img').each(function() {
// get current images type-attrib
var type = $(this).attr('data-type');
// find within $grid the first <img> with data-type == type and remove it from DOM
$grid.find('img[data-type="' + type + '"]:eq(0)').remove();
});
Try
$(function() {
var classes = $.map($(".frame div img"), function(v, k) {
return [$(v).attr("class")];
});
var d = [];
console.log($("#grid img").length);
$.each($("#grid img"), function(k, v) {
if ( classes.hasOwnProperty($(v).attr("class")) ) {
d.push(v); $("body").find($(d.slice(0, 1))).remove();
};
});
console.log($("#grid img").length);
});
jsfiddle http://jsfiddle.net/guest271314/yv95C/

How to find the width of a div using vanilla JavaScript?

How do you find the current width of a <div> in a cross-browser compatible way without using a library like jQuery?
document.getElementById("mydiv").offsetWidth
element.offsetWidth (MDC)
You can use clientWidth or offsetWidth Mozilla developer network reference
It would be like:
document.getElementById("yourDiv").clientWidth; // returns number, like 728
or with borders width :
document.getElementById("yourDiv").offsetWidth; // 728 + borders width
All Answers are right, but i still want to give some other alternatives that may work.
If you are looking for the assigned width (ignoring padding, margin and so on) you could use.
getComputedStyle(element).width; //returns value in px like "727.7px"
getComputedStyle allows you to access all styles of that elements. For example: padding, paddingLeft, margin, border-top-left-radius and so on.
Another option is to use the getBoundingClientRect function. Please note that getBoundingClientRect will return an empty rect if the element's display is 'none'.
var elem = document.getElementById("myDiv");
if(elem) {
var rect = elem.getBoundingClientRect();
console.log(rect.width);
}
You can also search the DOM using ClassName. For example:
document.getElementsByClassName("myDiv")
This will return an array. If there is one particular property you are interested in. For example:
var divWidth = document.getElementsByClassName("myDiv")[0].clientWidth;
divWidth will now be equal to the the width of the first element in your div array.
Actually, you don't have to use document.getElementById("mydiv") .
You can simply use the id of the div, like:
var w = mydiv.clientWidth;
or
var w = mydiv.offsetWidth;
etc.
call below method on div or body tag onclick="show(event);"
function show(event) {
var x = event.clientX;
var y = event.clientY;
var ele = document.getElementById("tt");
var width = ele.offsetWidth;
var height = ele.offsetHeight;
var half=(width/2);
if(x>half)
{
// alert('right click');
gallery.next();
}
else
{
// alert('left click');
gallery.prev();
}
}
The correct way of getting computed style is waiting till page is rendered. It can be done in the following manner. Pay attention to timeout on getting auto values.
function getStyleInfo() {
setTimeout(function() {
const style = window.getComputedStyle(document.getElementById('__root__'));
if (style.height == 'auto') {
getStyleInfo();
}
// IF we got here we can do actual business logic staff
console.log(style.height, style.width);
}, 100);
};
window.onload=function() { getStyleInfo(); };
If you use just
window.onload=function() {
var computedStyle = window.getComputedStyle(document.getElementById('__root__'));
}
you can get auto values for width and height because browsers does not render till full load is performed.

Categories