How to remove an element from opener window viewsource using javascript - javascript

Step 1
I've two screens one is parent and the other one is child.
On click of a button in the parent window the child popup will open.
Step 2
On click of a button in child i'm displaying the html(viewsource) of parent window in a textbox(.net) and holding in a hidden variable hdnSource too.
Step 3
I've 4 checkboxes in the child window.
If the checkbox is not checked, then that part of html should be removed.
eg: cbxPersonal, cbxProfessional
if cbxProfessional is unchecked I should remove divProfessional from html which is in hdnSource and display in the textbox
Can anyone help me to do the 3rd part of coding.
Since the html is in the variable, I'm not able to find the div with document.getElementById

Trying to futz about hacking bits out of HTML strings is going to be annoying and buggy. Instead, do the removal on the DOM Nodes, before you've turned them into an HTML string.
To avoid actually removing the real divs from the parent page's visible DOM, clone the nodes before operating on them. eg.
var copy= opener.document.body.cloneNode(true);
if (!document.getElementById('cbxPersonal').checked) {
var div= copy.getElementById('divPersonal');
div.parentNode.removeChild(div);
}
var html= copy.innerHTML;

Related

Why does the elements inside my div container disappear?

I have a question about browser behavior when handling the elements inside of a div container. I have an Iframe that I use to make requests to the server to run PHP files, while the parent page remains dynamic. Requests made by the parent page to the child frame determines what eventually happens to certain elements on the parent page when the server returns the results to the child frame. I've tested everything, and it all works fine, except for one noticeable glitch. If someone happens to call a function on the main page that tries to read an element inside of a div container while the child frame is making a change to any element inside the same div container, the program gives a null error. When I check the elements of the div container with the debugger, all of the elements (14 in total) inside that specific div container are gone. I'm sure I can solve the problem by querying a random element first to see if it exists, and if not, put a call back function a second later once the child frame finishes with the parent page. But I'm curious as to why all elements inside that specific div container are gone at that exact moment in the first place, since the child frame only manipulates 5 of the elements inside that div, and the parent request is looking for a completely different element that is not being manipulated by the child frame. Am I correct to assume that making changes to an element inside of a div container forces a rewrite of all the elements inside that div? All other div container elements in the body of the document remain intact, just the one div that's being changed. This is not the exact code (too much to post) but an example.
// Parent
document.getElementById("heading").innerHTML = "Where did you go?";
// Child Frame
parent.document.getElementById("pic").src = "anotherpic.jpg";
<div id ="something">
<P id = "heading">blah blah blah</p>
<img id = "pic" src = "picture.jpg">
<p id = "picname">Picture Name</p>
</div>
If the Child runs first, and the Parent tries to read an element while the child is still making changes to an element inside the div, all elements disappear when I look for them in the debugger. Any insights into this behavior are appreciated. Thanks. (Hopefully, this was not a stupid question. lol)
Please mind there is no such thing as "at the same time" here. Both, the innerHTML and getElementById work synchronously.
Even if you used the innerHTML improperly (which I know isn't the case) eg. overriding the parent component - there's no "in-between state" that you'd be able to access with the functions, to notice that there are no elements for a "moment". So I'd look elsewhere to find a reason behind it.
eg. the Iframe content modifies the parent twice every time, first of which makes it empty.
Have you tried using:
target.addEventListener(type, listener [, options]);
Instead of:
getElementById
?
Looks like something is getting overwritten.

Where could `appendTo()` be usable with an `htmlString`?

The API docs for appendTo list the method being able to select an HTML string for a target.
However, there seems to be no use to this since the set still includes the original elements, and the HTML string seems not to have been added anywhere in the DOM nor do I see a circumstance where it could be available.
var b = button.appendTo('<div>').appendTo('body');
b is a button, and yet it is not wrapped in a div or anything.
You can see this at http://jsfiddle.net/0dgLe5sj/
Where would it be useful to append to a HTML string (which doesn't yet exist on the page)?
appendTo() returns the item being appended.
So your code is:
var btn = button.appendTo('<div>');
btn.appendTo('body');
As you can see, you move it inside a div, then immediately move it inside the body. So you when you look at it at the end, it's inside the body.
Perhaps you meant:
var b = button.appendTo($('<div>').appendTo('body'));
which will append a div to the body and then append the btn to that div.
Updated fiddle: http://jsfiddle.net/0dgLe5sj/8/
or, if you wanted to add to the div first:
var b = button.appendTo("<div>");
b.parent().appendTo("body")
but if you combine it into a single line, you can't get the button back into the variable using .appendTo as you're adding the div to the body so you're going to get the div or the body back.
To address the 'where would this be useful part':
Being able to create detached DOM elements is extremely useful for parsing HTML strings and can also be used to 'batch' up some changes without forcing page redraws between.
Moving one button to a detached div and the back to the body doesn't have a lot of point, but it proves the principles.

Why does changed value not display after breakpoint? Part 2

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.

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.

Attach event to document other than 1 div

I have created an inspector type feature that will give you a divs ID when you click anything on the page. I have used:
document.attachEvent('click', inspectorOnClick);
I've now decided to add another feature, I now need this event attached to everything in the document other than one div is that possible?
EDIT:
I thought one of the links in the comments solved my problem, but there is a bit more to it than I thought.
Let me explain, when the document loads.
document.attachEvent('click', inspectorOnClick);
Is attached, once an element is clicked I dynamically create an overlay div in the position of the cursor. I want to take the event off of this dynamically created div. I have tried:
//prepend dynamicly created div to body
document.body.insertBefore(overlayDiv, document.body.childNodes[0];
var getOverlay = document.getElementsByClassName('bsOverlay');
getOverlay.attachEvent("click", function(){ return false; }
I have also tried a different last line which is
getOverlay.detachEvent("click", inspectorCancel)

Categories

Resources