I have a div (#diagram) larger than the actual visible area in my browser. #diagram contains up to 1500 "boxes" (other div elements) and I would like to know which of these 1500 boxes are actually really visible to the user so that I can populate them using ajax when they come into view. I actually do have some working code but that goes through all elements triggered by the onscroll() event. This works so so in Chrome but of course my client HAS to use the evil browser IE8 where the looping of all elements upon scrolling completely forces my application on its knees.
Is there some sort of event that is fired when an element comes into view or any other option to detect "true" visibility?
Environment: jQuery/jQueryUI (latest), Internet Explorer 8
Thanks in advance :-)
./cj
What if you go through all your boxes just once when they have been rendered and group them into "pages" - collections of references to DOM divs that are visible between [y1, y2] vertical coordinates of your parent div. You'll have <total height of parent div> / <visible height of parent div> pages.
You preload content of the 1st page, and then on each scroll event you'd check if content for the next page of boxes should be loaded.
Refer -
Element ‘in view’ Event Plugin
When the window is scrolled, the event checks the position of the elements against the viewport height and the scrollTop position.
And
Lazy Load Plugin
Lazy Load is a jQuery plugin written in JavaScript. It delays loading of images in long web pages. Images outside of viewport (visible part of web page) wont be loaded before user scrolls to them
Related
I recently posted a question on SO where I observed a different element height and width being returned by Chrome Inspector tool vs. Selenium WebDriver when calling element.getSize().getWidth() and element.getSize().getHeight(). With Chrome Inspector I get dimensions of w = 979, h = 1961. With Selenium I get dimensions of 979 and 1461 respectively.
Code I'm using to retrieve element:
String URL = "https://www.amazon.com/dp/B07G9RZD14";
driver.navigate().to(URL);
String XPath = ".//*[#id='aplus']/div";
WebElement element = driver.findElement(By.xpath(XPath));
I've repeated this experiment several times and each time I got the same result. Some have suggested that I was changing the size of the browser however this is not the case. I always performed my test in maximized mode from start to finish.
I did experiment further and it turn out that if I inspect the element with Chrome Inspector immediately after the page loads (without scrolling down to element so it is put into view) the dimensions returned matches the dimensions returned by Selenium (1461). It is only after I scroll element into view that the element height "grows" to 1961.
When I inspect the HTML in the above URL I see a script executing an "expander" function.
I have three question.
1) How does this function work? (Looks like it's using Javascript)
2) Is it possible to get the real dimensions of the said element (1961) without scrolling element into view? Or it would be required to scroll into view element with this kind of function attached?
3) If it is required to scroll such elements into view, is it possible for us to know which elements have this function and need to be scrolled into view or I would have to scroll all elements into view as a precaution?
Thanks
Amazon product pages are quite complex, and include a lot of lazy-loaded images and other elements. It's likely that your element is growing in size because new content is being rendered lazily as you scroll down the page.
To answer your question, you will certainly need to scroll down the entire page and allow all elements to finish rendering if you want completely accurate dimensions.
I'm using the jQuery UI framework to create a draggable panel. It works fine, but when I drag it over top of an embedded iframe on the page it becomes buggy and stops moving. I thought it could just be the plugin, but it happens with all of my dynamically created elements that move overtop of the iframe.
Does anyone know what is going wrong or how to fix this?
You've to kind of hide the iframe when you drag/resize the panel. This can be done by placing a hidden transparent div right over the iframe (of the same size), and showing it up only when the drag/resize event is triggered. So keep on toggling as soon as the drag/resize start and stop events are triggered.
I am trying to link to a page at an anchor point, i.e.:
About
<div id="content">…</div>
The normal browser behavior is to render the page, then jump to the anchor/ID. Is there a way to position the page at the anchor position before the page renders?
I've tried using
$(document).scrollTop( $('#content').offset().top );
thinking it might move to position quick enough to prevent a flash of the full page load but it doesn't work until DOM ready, so it's not quick enough.
I can cobble together a work-around by selectively hiding elements, moving to position, then showing them, but I'm wondering if there's an approach I'm not aware of.
I don't think there is any other direct way of doing it. You can only guarantee faster link to a particular div making the div available as soon as possible in the DOM.
You can do this by loading the required div to be linked statically while loading the contents of other div dynamically. Again while doing this you have to make sure that the page is always scrolled to this div, by executing the code
$(document).scrollTop( $('#content').offset().top );
periodically, as when the other contents of the page are getting loaded dynamically page size may tend to increase and we would want to keep the scroll position always on the content div.
What I'm trying to achieve is basically have a code that will morph (move around the page) based on the part of the window which is currently viewed.
Scenario:
actual page height : 2000px
actual screen height( pc, laptop whatever ) : 800px
1 image of 600px
3 div's or virtual boxes ( just to prove what I want to do )
Workflow
When you open the page, you'd see the first part of the page with the image loaded in the first div.
What I want and need to achieve is when scrolling the page, and the focus would be on the second div (or the image simply gets out of focus - you can't see it no more),
the image would move (disappear from the first box) and appear in the second one, which is currently visible.
The idea might seem pretty easy but I'm not JavaScript savvy.
Ideally, the answer should include a way to load a JavaScript instead of that image.
The way you use the word focus can be misleading, as focus is a JS event that happens after an element is clicked. You need to get familiar with the jQuery scroll event and scrollTop. Here is similar Thread here in StackOverflow that you may want to read Jquery / Javascript find first visible element after scroll
Here is my current situation:
I have a web page containing a couple scrollable divs. Each of those divs contains a number of objects. I am using YUI to display popup menus of actions that can be performed on each object. Each object has its own menu associated with it that is constructed and displayed dynamically. The popup menus can be large and can overlap the bounds of the scrollable div.
From what I believe are issues with focus (the menus must be accessible), when I hover the mouse over an action that lies on top of an edge of the scrollable div, the div automatically scrolls, moving the content but leaving the menu stationary. Trying to move the menu dynamically when this happens is not something I want to do as I believe it would provide a poor user experience.
So I need to prevent this focused menu from scrolling the div. My idea for providing the best user interface is to prevent these inner divs from scrolling when a menu is open. This leaves the menu positioned in the optimal location to show the user which item is being acted upon. If the user wants to scroll the box, they can click to close the menu and then scroll normally.
How can I do this? I need a solution that works across the major browsers.
My first thought was to listen to the onscroll event for that particular element. Unfortunately, there does not seem to be an easy way from there to just prevent the scrolling from happening. For one, my JavaScript event code appears to execute after the actual scrolling has occurred.
Then, I thought that since my code is being run after the object has scrolled, I could just reset obj.scrollTop and obj.scrollLeft. Sure enough, this appears to work, though I am worried that on slow browsers the user will see the content inside the div "jump around". Also, it would be really nice if the amount the element scrolls is part of the event object. Is it stuck in there somewhere? I'm looking for an alternative to having to store the scrollTop and scrollLeft variables for this element and then using them while the scrolling is temporarily disabled.
What is the best way to solve this entire problem?
I agree with Anthony regarding the presentation of the functionality you're trying to disallow. If you're going to disable scrolling, then you should make that part of the page visually disabled or removed.
To that end, you can position a semi-transparent div on top of the scrollable div in question, which would capture the mouse events and visually show that the scrollable div is inactive for now. It would be hard to make cross-browser compatible and wouldn't be perfect, but then again very few client-side tricks like this are.
The simple answer is no you can't do this. Its doubly no if you want a cross-browser solution.
Providing the user with the clear affordance that something can be scrolled then denying them that is just plain poor UI design.
Ok so after your edit it turns out you are not actually trying to prevent the user from scrolling.
The main answer remains true though. It sounds as though the focus is going to rectangle (probably an anchor?) that is not fully in view and causes a scroll. Is there a reason this rectangle must get the focus? For accessibility?
What if you didn't have overflow: scroll and instead you used overflow: hidden and provided scroll up/down buttons that allowed the user to scroll when necessary? These buttons could of course be disabled easily.
Though it may not be the answer you are looking for, if you are to set the display value of the div to 'none' while the page loads (from the server) and then have an event wired to the page load (either pageLoad in ajax.net or attach it to the onload event via javascript) that will make the div display set to 'block' .. that would ensure that slower browsers wouldn't see the div 'jumping around' (could even put a 'loading' image in the div to show users it's doing something and not just invisible)
sorry i couldn't provide a more complex/fluent solution.
I found a way to work around this issue. By removing the menu element from the scrollable div and then appending it directly to document.body, the browsers all stop trying to scroll the div to reveal the focused element (even though the element is already completely visible).
Thanks to all for your time and your answers!