I'm trying to figure out if it's possible to calculate the area of a HTML element on a website? In pixels, as a percentage or whatever.
My first thoughts have been to make the assumption that the element is 100% in width and height, and then try to retrieve the size through a mapping between the HTML and CSS.
So if there's a width/height attribute in the referenced CSS-file I could possibly say that
the body element is covered by a column that takes 25% of the area (everything is based on your screen resolution of course - and I'm still trying to figure out how I'd be able to do this programmatically).
Or whether I should render the website and do my calculations based on an image with the most common screen resolution at the time).
Are there any more possible solutions?
(Currently I'm trying to solve this in Perl, but I suppose any language that's got a library for this purpose would be appreciated to know about!)
EDIT: I need to retrieve the visual area for every single element on a page.
For example; if there are elements on top of the <body> element, that covers it visually, I want to exclude that area from the <body>'s and so on. A simple raytracing to find the visible area for every element on a page.
EDIT: Let's say we exclude JavaScript - any other approaches possible?
Personally, I would use jQuery - even if you don't use a library, your best bet will be a JavaScript solution.
var $elt = $('#some-element-id'),
height = $elt.height(),
width = $elt.width(),
area = height * width; // contains the area in px^2
http://api.jquery.com/height and http://api.jquery.com/width
This is such a simple problem I don't think JQuery is necessary if you are not already using it.
Try running this:
<div id="myParent">
What's up?
<div id="myDiv">Hello there!</div>
</div>
With
var myDiv = document.getElementById("myDiv");
alert(myDiv.offsetHeight);
alert(myDiv.offsetWidth);
var myParent = myDiv.parentNode;
alert(myParent.offsetHeight);
alert(myParent.offsetWidth);
Divide resulting widths to get % of space the element takes in it's parent, or simply use the absolute pixel values.
I would recommend using jQuery to do it if possible.
alert('Size: ' + $('li').size());
http://api.jquery.com/size/
Would it be feasible to use javascript? If so you can get the width/height with something like this:
document.getElementById(YourElementsId).style.height;
document.getElementById(YourElementsId).style.width;
However this does depening on how the elements are sytled in the first place. Another option would be
document.getElementById(YourElementsId).clientHeight;
document.getElementById(YourElementsId).clientWidth;
Related
I am using MigraDoc to generate a PDF. I want to align some content to the bottom of the last page. This is boilerplate disclaimer information that my company always includes in these types of documents. The goal is to keep the content altogether and always have it appear just above the footer on the last page. If there isn't room on the last page of actual content to keep it together, there should be a page break and the boilerplate content will be on a page by itself.
I would like to do this without measuring the height of the content.
I get the impression that I can use TextFrame to assist with this in some way, but I can't find any documentation on it. The questions and examples I've found online refer to being able to "absolutely position" the TextFrame, but none of the examples seem to do that, exactly.
As a starting point, I am trying to position a paragraph of text in the way I described on an otherwise blank page. Here's my latest experiment:
static void AddBoilerPlate(Section section) {
var sectionWidth = PdfSharp.PageSizeConverter.ToSize(PageSize.Letter).Width - section.Document.DefaultPageSetup.LeftMargin.Point -
section.Document.DefaultPageSetup.RightMargin.Point;
section.AddPageBreak();
var frame = section.AddTextFrame();
frame.RelativeVertical = RelativeVertical.Page;
frame.Width = sectionWidth;
frame.Top = ShapePosition.Bottom;
frame.AddParagraph(DisclaimerText);
}
The text starts just above the footer (the blue line in this screenshot) and then runs over the footer:
Once I get a paragraph of text aligned, then I think I will be able to use a table with one column and one row instead, and then put all of my content in there.
Update: here is a screenshot showing my goal (faked using a page break and SpaceBefore):
Update: here are some related articles that don't quite get me where I'm trying to go:
Centering a table on a page using a TextFrame: http://forum.pdfsharp.net/viewtopic.php?p=753#p753
Seems to answer the same question, but doesn't provide information about how to absolutely position the TextFrame: http://forum.pdfsharp.com/viewtopic.php?f=2&t=587
Keeping table together on a page ("in one piece"). This will be useful once I figure out the issue with aligning relative to the bottom of the page: Keep table in one piece MigraDoc / PDFsharp
Update: Note that adding a height to the TextFrame does make the text align the way I need it to. It's not ideal, because I would rather not hard-code the height. But it does produce the desired effect:
static void AddBoilerPlate(Section section) {
var sectionWidth = PdfSharp.PageSizeConverter.ToSize(PageSize.Letter).Width - section.Document.DefaultPageSetup.LeftMargin.Point -
section.Document.DefaultPageSetup.RightMargin.Point;
section.AddPageBreak();
var frame = section.AddTextFrame();
frame.RelativeVertical = RelativeVertical.Page;
**frame.Height = new Unit(75, UnitType.Millimeter);**
frame.Width = sectionWidth;
frame.Top = ShapePosition.Bottom;
frame.AddParagraph(DisclaimerText);
}
Update: Note, though, that setting the TextFrame height doesn't resolve the ultimate issue. Content added before the boilerplate should push the boilerplate to the next page if there isn't enough space for it, and that's not happening.
Update: After trying it out myself (I've had the same Problem), add an invisible element with the Height you want to have just before the bottom element. In case the invisible Element doesn't fit it will seem that the page break occurred because of the bottom element.
Works like a charm.
(tip I added a border to both elements for testing so I was able to make sure the layout was proper)
Basically, what I'm trying to do is get an image to represent a page (for quick browsing in a XAML GridView).
I have the pages URL (and it's HTML content), but now I'm not completely sure how to proceed. I could just use the Favicon, but I don't think that would scale well up to the 200x200 box I'm using to display it. The other option (as far as I can think of) is to look through the HTML source and pick out the largest image.
Is there an easier/simpler way to do that in C# other than just using Regexs to find the height/width of all the image tags and then comparing them?
Thanks!
There is no way to know for sure from the HTML source what size the images are. An img tag doesn't require the height and width parameters. If they're not specified, then the image is displayed in its actual size. If all the img tags on the page have their height and width specified, you could pick the one that has the largest values. But those are the display sizes. The actual sizes might be quite different.
The only way to be 100% sure is to download each image and get its size.
By the way, if you're parsing HTML, you probably shouldn't be doing it with regular expressions. I know it seems simple enough, but you're almost certain to get things wrong and not handle some common cases. You'll save yourself a lot of time and frustration by using something like the Html Agility Pack.
you can try
imageObject.ActualWidth
imageObject.ActualHeight
properties
I am trying to get position of html elements in a .net's webbrowser control and failing,
i need the exact position of the element relative to the whole document or the webbrowser control to be able to send a mouse click using SendMessage() P/Invoke ..
I have tried the solution from here but it didn't work:
getting absolute position of HTML element in webbrowser control with C#
I am guessing that is because the page relies on very complex ajax and css.
the function "WebBrowser1.Document.GetElementFromPoint()" works just fine in getting the accurate html element, i just need the opposite of it.
other wise, should i just keep on searching using "GetElementFromPoint()" until getting the correct element ???
Thanks.
As I am unable to comment on your question, I'll go for making an "answer", even though it won't be much of one...
What's wrong with clicking the element via JavaScript / InvokeMethod?
You could also modify the CSS for the element, making it cover the
whole of the viewport, allowing you to click anywhere within the web
browser control's viewport.
If you were to post reasons why the solution from your link was unable to work, then it would be easier possible to give you a solution to the problem.
You may get the same exact behaviour by simply doing something like this:
public void ClickHtmlElement(WebBrowser o, string htmlElementId)
{
const string mask = #"javascript:void(document.getElementById('{0}').click())";
string url = string.Format(mask, htmlElementId);
o.Navigate(url);
}
I have this exact same issue. Invoke, .domelement.click(), .click etc... doesn't work, sendmessage does work, but that requires the exact X,Y position.
The only solution I have at the moment is horrible. Basically using GetElementFromPoint(), but instead of going point by point, you can use a step of the width and height of your element.
So if your element is 500 pixels high and 500 pixels wide, then you can search point 0,500,1000,1500 etc.
I've found some jQuery code that shows how complex it actually is to get the correct X,Y position:
https://github.com/jquery/jquery/blob/master/src/offset.js
I can't believe there isn't an easier way :-(
I generate a HTML-Page from C#. In the HTML-Page there are a lot of elements. All of them have a absolute position.
One of these elements is a table. This table represents a object that keeps a double[]. Every double value is a new cell in a new row.
I iterate over double[] and create my table:
for (int i = 0; i < dbl.Length; i++)
{
htmlTextWriter.RenderBeginTag(HtmlTextWriterTag.Tr);
htmlTextWriter.RenderBeginTag(HtmlTextWriterTag.Td);
htmlTextWriter.Write(dbl[i]);
htmlTextWriter.RenderEndTag(); // td
htmlTextWriter.RenderEndTag(); // tr
}
If the table has so much elements, that it cross an element that is below this table, I have to be responsive to this issue.
This means, I need to know how many pixels this table is long.
Of course I do know how many cells I generate and I also know BorderSize, Padding, Margin, etc.
But there are two problems. First although I know FontSize, FontFamily, FontWeight, I do not know how to include these information into a mathematical calculation.
Second I think in every browser the actual size is also different. I created a dummy table and recognized, that in one screen height I already have one cell difference between Opera and Firefox.
So I think in C# I am only able to approximate the actual height?!
The next idea I have is to include a JavaScript into my HTML. I've no experience with JavaScript, but my approach would be to find my tables and read out size. Then iterate over all elements and find all overlappings.
My questions are:
Are my consideration true or do I miss some aspects?
Are my approaches the right way (in C# I only will get an
approximated result?!, JavaScript I do not know if it is really
possible what I want to do)
Are there other possibilities I do not see right now?
Hint: Other script languages than JavaSript are not applicable for my solution. JavaScript I only use if really necessary.
I think javascript is the answer, not c#.
http://api.jquery.com/height/
You cannot calculate the height in C#. Please use javascript to do this.
What is the easiest/best way to set the maximum width of a web page. For example assume I don't want to let the user to expand the width beyond 400px. HTML code, CSS, C#?
I am using Visual Studio 2008 C# environment.
Thanks
Bruce
If you want to limit the browser width, well you can't do that :P
Alternatively, if you want to limit a certain element's width, such as a div with an ID of #container, then you would use CSS:
#container {
max-width:400px;
}
Wrap the content of the page is some sort of container (a <div>) is usually suitable. Apply the max-width property to it.
Simply make a fixed width CSS layout set at 400px.
Trying to prevent the browser window to be greater than 400px is horrible idea, and will fail in more ways than it will work (mobile, etc).