Why does changed value not display after breakpoint? Part 2 - javascript

A value in tab header changed through JS value is not persisting on #media breakpoint/accordion screen - although the one in the tabbed content area is persisting.
The js code:
function check_1_input(X, Y) {
var ids=X.split("_"); console.log(' X '+X+' id '+ids[1]);
var PX=document.getElementById(X);
var PY=document.getElementById(Y);
PX.childNodes[0].textContent = "Changed";
PY.childNodes[0].textContent = "Changed";
}
which makes the changes is at the end of the html - not sure why it only works in that location.
The fiddle is
https://jsfiddle.net/PhilB/077dbf37/10/

The problem you're having is that you're using element IDs in your check_1_input function. The responsive tab plugin clones your tab elements on initialization to have both horizontal and vertical tabs with different classes that get hidden or exposed based on the media width, but it keeps the IDs the same. Since your function is looking for elements using getElementById, it will only find the first one.
Ultimately, you end up with two different elements with the same ID, which is bad practice. Using a class as the selector instead of the ID fixes the problem. I used jQuery to select the classes instead of ID's since you have jQuery loaded. You may consider removing the ID's all together in the tab elements, since the responsive tab plugin is always going to clone them and result in an invalid DOM (two elements with the same ID).
See my updated version of your fiddle here.

Related

Javascript for deleting DIV that blurs website

There is a website with the following div:
<div class="x" style="user-select: none; filter: blur(4px);">
under this div there are a lot of other divs. I would like to know if there is any possibility to delete only this DIV with javascript. So only that one gets deleted and all the divs underneath remain.
I want to get rid of this DIV becouse this div blurs an part of the website text. Just changing the blur(4px) wont work the website has some kind of protection what refreshes this part back to original.
the reason i am searching for an possibility in javascript is because i want to automate this in the browser.(Just deleting DIV manually under developer mode works)
so far i got the following:
var div = document.getElementsByClassName('page-content');
div.remove(); //(but this does not work)
getElementsByClassName() returns a collection. Only single objects have remove() method. You have to apply one of the following:
Use brackets to specify an index of the object you want to get:
div[0].remove()
Use item() method passing the index as well:
div.item(0).remove()
Both ways are equivalent.
As an alternative, you may call querySelector() method:
const div = document.querySelector('.page-content')
It returns a single object (according to the passed CSS selector) so you can use:
div.remove()
Edit:
To remove only the covering div, you may use replaceWith() method and pass the child nodes of that div as an argument:
div.replaceWith(...div.childNodes)
If you want to keep only element nodes, use children property:
div.replaceWith(...div.children)

javascript get size of element with hidden parents

I need to determine the height of a DOM element using javascript - specifically, in my case, a div containing some text. Due to the way that HTML works, I can only reliably do this if the element is visible. The general purpose solution is to show the element, get it's height, and then hide it - simple enough in the single element case.
However, in the general case, the element in question may be a child of other elements that are hidden, thus preventing the above solution from working - calling jQuery's show() function on the element in question doesn't actually cause it to be shown due to the hidden parent, so you still can't get the height.
How can I make an element visible long enough to get its height, taking into account any parent elements that need to be made visible to make it work?
Use case: I'm trying to write some code that I can apply to any table element, that creates some other elements whose height should match the height of the table header. I want to keep the code generic enough that it will work regardless of where in the DOM the table is located, or if it is currently visible. An alternate solution would be to have some javascript that simply adjusts the size of the created elements when the size of the table header changes (such as when it is shown), but conceptually that seems less efficient. Still, if it is easier, I will accept that as an answer.
Edit: To give an example, while keeping in mind I am going for a general solution that is not tied to this specific HTML layout, consider the following HTML:
<div style="display:none; line-height:22px; font-size:18px;">
...Some random text or other content...
<div id="desired_size">
I want to find the height of this div when visible
</div>
...Possibly some more content/other stuff...
</div>
The goal is to get the height of that inner div, but I can't do that because it isn't displayed - it is hidden due to the parent div being hidden. If all I know about the HTML is the desired_size div, how would I go about making it visible enough to get the height? Granted, this example is trivial, but I'm trying to generalize it.
Edit 2: One suggestion was to clone the element and move it to somewhere that is visible. This works, but with a caveat: any inherited CSS properties that would affect the size are lost.
Edit 3: I'm trying to write a block of code that I can re-use in a variety of web pages, not just coding to a specific layout. As such, I can't make any assumptions about or changes to the parent HTML. The example above shows one case where this can cause difficulties.
Edit 4: As has been pointed out, it would be trivial to change the HTML such that the visual appearance is the same, but the issue doesn't exist. However, I am trying to find a solution that works with the HTML as written, regardless of how the HTML is written.
demo - http://jsbin.com/tosusanowu/edit?html,js,output
Assuming you know that desired_size div has always a parent that is hidden.
$(function(){
var desired_size = getDesiredSize('#desired_size');
});
function getDesiredSize(el) {
var $el = $(el), $parent = $el.parent(), desired_size = 0;
$parent.attr('style', 'opacity:0;position:absolute');
desired_size = $el.height();
$parent.attr('style', 'display:none');
return desired_size;
}
<div style="display:none;">
...Some random text or other content...
<div id="desired_size">
I want to find the height of this div when visible
</div>
...Possibly some more content/other stuff...
</div>
The following javascript/jQuery function should work in the general case where the HTML structure is unknown, as requested:
function getHeight(objectID){
var object=$('#'+objectID);
var nextObject=object;
var changedObjects=[];
var counter=0; //to prevent infinite looping
while(!object.is(':visible') && counter<100){
counter+=1;
var curObject=nextObject; //store a reference for use in loop
nextObject=curObject.parent();
var curStyle=curObject.css('display') //see if current object is hidden
if(curStyle!='none')
continue; //don't mess with non-hidden objects
//see if the display style is inline, or from a CSS file
var inlineStyles=curObject.attr("style");
if(typeof(inlineStyles)!=='undefined'){
inlineStyles.split(";").forEach(function(element){
var style = element.split(":");
if ($.trim(style[0]) === 'display') {
//Record the fact that the display properly is an inline style
curObject.data('floatinghead_inline_style',true);
return false; //break out of the forEach loop
}
});
}
curObject.show(); //if object is hidden, show it for now
visitedObjects.push(curObject); //save a reference so we can put it back later
}
var height=object.height(); //this should work properly, since object should now be visible
visitedObjects.forEach(function(item){
if(item.data('floatinghead_inline_style')===true)
item.hide();
else
item.css('display','');
})
}
The above code makes no assumptions about the HTML structure, particularly the depth of the object in question from the hidden parent element. Also, unlike the "clone item to a different, visible, location in the DOM" option, it should properly take into account any inherited attributes that affect the height.

Set CSS Left property of UL using Javascript

So i'm trying to make my schools navigation bar a little bit more mobile friendly.
If you navigate to
www.jpc.wa.edu.au
on a mobile device, and click on the menu item "Resources" - A drop down menu opens up with two options. Mousing over these with a desktop computer gives you another menu to the right of the first. This works fine on a large screen. However, anything that has a resolution lower than roughly 1460px, such as most tablets, phones, or even laptops, the new menu gets cut off and you have to pan the window left to view it. I would like to avoid this problem completely by simply positioning the second submenu to the left of the first submenu on smaller screens.
Determining screen size I can do.
if(window.innerWidth<1460)
Works perfectly fine. The problem i'm having is that I can't seem to access the second submenus left property to modify the menus position from my javascript
In my CSS, I set it by using the following selector
#horizonMenu
But when I try to use this selector in Javascript using
document.querySelector("#horizonMenu").style.left
But that doesn't seem to return any values.
What am I doing wrong guys? Or should I just take a whole different strategy to fixing this problem?
Edit: I've now changed horizonMenu to a class. Alas, my problem seems to persist :(
The problem is that you have multiple elements with the ID horizonMenu. You should only have a single element with a given ID. When you query #horizonMenu, it is returning the Community -> Pastoral Care menu, which does not have a left value. You should use classes instead, as you can have multiple elements share a class, or change the id to something unique so you can access what you intend to access.
Take a look at the following links
Change an element's class with JavaScript and http://www.kirupa.com/html5/setting_css_styles_using_javascript.htm
Also please check the position attribute for the elements, see below example:
https://jsfiddle.net/masoodalam78/e3erq6j4/
var elementObj = document.querySelector("#menu");
elementObj.style.backgroundColor = "blue";
elementObj.left = "200px";
style property is the representation of the style attribute. Since you are setting the CSS property in your CSS file, the left property returns an empty string. Also properties of the style object do not show the computed values. For getting the computed value you should use window.getComputedStyle() function.
window.getComputedStyle(document.querySelector("#horizonMenu"), null)
.getPropertyValue('left')
For setting the property value you can code:
document.querySelector("#horizonMenu").style.left = '...';
Note that you can consider using CSS media queries instead of using JavaScript.
Okay. so it may have been a combination of a few things.
I followed JBzd's advice to change the menu to a class.
I also stopped using querySelector() and instead am using querySelectorAll() - storing what's returned as a variable and accessing the correct menus by using varaible[1] and variable[2]
I am now able to access the left property of the menu by using
variable[x].style.left = '162px'
Thanks for all the help everyone :)

Fire Ajax Rest call only for elements in viewport

i've got the following problem.
We're using a template which generates a list of divs, all with the same classes etc.
Each div contains a hidden input field containing the ID of the target site it links to.
Now my job is to use this ID to generate ajax rest calls for each of the divs to receive the amount of comments on the target site.
My current solution is a simple jQuery each, iterating through all divs and firing a rest call for each div containing the individual target ID and then appending the number of comments on the target page.
However, there might be a huge amount of divs on the page, so the customer only wants the rest calls of the currently viewable divs fired while scrolling down the page.
Is there any way to do this?
IMPORTANT INFORMATION: i have to use jQuery 1.7 and it has to work in IE8! -.-
kind regards
Additional info:
All divs that are rendered by the template are visible, so i can't check for :visible. I need a way to check if they are in the viewport. I tried some inview-plugins etc., but they need a specific ID they are tied to, and then check if the element with this ID comes into view. However, all my elements have the same class and no ID at all as they are rendered by the same template.
You can try with $('.element').is(":visible")
http://jsfiddle.net/4mu18z2y/1/
I haven't tested it in IE8 though.
You have to get the window position and the offset top of each element...
$(document).ready(function(){
var windowSize = $(window).height();
console.log("Window size: " + windowSize);
$(".test").each(function(){
var top = $(this).offset().top; // element top position
if(top < windowSize){
console.log($(this));
// your ajax call
}
});
});
Finddle: http://jsfiddle.net/m2wnbp2c/

KnockoutJS / jQuery UI Sortable Conflict

I'm attempting to use KnockoutJS and jQuery UI Sortable together. I know this has been done before (particularly, knockout-sortable), but my use case has some pretty specific behavior and I'm hoping to avoid trying to make the switch.
Anyway, the problem is pretty straightforward - after moving a DOM element with jQuery UI Sortable, Knockout behaves strangely when removing the observableArray element bound to that DOM element. It will fail to remove the moved element, and if the element that fell into the moved element's place is removed, it will remove both that and the originally moved element. Hard to put into words, but demonstrated by this fiddle.
The problem seems actually take place in the following block in knockout-2.1.0.js:
function fixUpVirtualElements(contiguousNodeArray) {
// Ensures that contiguousNodeArray really *is* an array of contiguous siblings, even if some of the interior
// ones have changed since your array was first built (e.g., because your array contains virtual elements, and
// their virtual children changed when binding was applied to them).
// This is needed so that we can reliably remove or update the nodes corresponding to a given array item
if (contiguousNodeArray.length > 2) {
// Build up the actual new contiguous node set
var current = contiguousNodeArray[0], last = contiguousNodeArray[contiguousNodeArray.length - 1], newContiguousSet = [current];
while (current !== last) {
current = current.nextSibling;
if (!current) // Won't happen, except if the developer has manually removed some DOM elements (then we're in an undefined scenario)
return;
newContiguousSet.push(current);
}
// ... then mutate the input array to match this.
// (The following line replaces the contents of contiguousNodeArray with newContiguousSet)
Array.prototype.splice.apply(contiguousNodeArray, [0, contiguousNodeArray.length].concat(newContiguousSet));
}
}
This call is adding the moved DOM element to the list of elements to be removed when the shifted element is removed.
So an open call to any jQuery UI / Knockoutjs geniuses - is there a way to resolve this conflict, or do I need to do something entirely different to make these tools play nicely together?
I think the "best" solution is to remove the element from DOM and change its position in KO. You can do this in the stop event of the sortable. http://jsfiddle.net/vgrTY/4/
I went ahead and changed your array-contents text to a computed as well so it'll properly display.

Categories

Resources