I have two forms that have to use the same IDs, etc. however, one is specifically for mobile viewing and the other for everything else. I am using media queries and display: none to show/hide each, but of course they are both technically still coded ON the page, which means neither of them work. So instead I am trying to think of a way to totally remove the element based on screen size. It has to be actually removed and not simply hidden.
I'm stuck and I need to get the site migrated by tonight. Any suggestions would be most appreciated!!!
Use the jQuery solution here to add a 'resize' event listener to window:
jQuery on window resize
In your event handler check the screen size (Get the size of the screen, current web page and browser window)
Use jQuery remove() to remove the element http://api.jquery.com/remove/
then append() to add the new one: http://api.jquery.com/append/
(only remove and add elements when changing from one size range to the other, not on every window resize)
Related
I am wondering if there are any HTML5 events associated with whether or not an element has been viewed or "scrolled into view" by the user.
An example could be a longer page with elements at the bottom, which has yet to be scrolled into the users view...
I have seen jQuery solutions to this problem, however I am only interested in figuring out if weather or not this is achievable purely though the use of HTML5 events and JavaScript.
It should be noted that I have already had a look at the "onfocus" event, which (from it's official description) seems to only be applicable if the user selects or "clicks" somewhere on or within the element itself.
In plain JavaScript you can use the event "scroll" along with getBoundingClientRect().bottom <= window.innerHeight to determine if an html element has come into view.
document.addEventListener("scroll", inView);
function inView() {
if (document.getElementById("viewElement").getBoundingClientRect().bottom <= window.innerHeight) {
console.log("in view");
// uncomment below if you only want it to notify once
// document.removeEventListener("scroll", inView);
}
}
The console prints "in view" when the element comes into view.
<div id="viewElement">Hello there!</div>
There are no built-in events that tell you when an entire DOM element has become viewable/visible on the page due to scrolling or window resizing.
The only way to do this is to keep track of resize and scroll events (which can each cause more or less of your page to be visible) and then use the scroll position and window height and DOM element positions to calculate if your entire DOM element is visible.
Some relevant pieces of code you can either consider using or look into how they work (these tend to be jQuery-based because they are harder to share if not based on a common DOM library):
Lazy Load Plugin for jQuery
Element "in view" Event jQuery Plugin
Check if Element is Visible After Scrolling - plain JS
I had to do something similar to this when I built http://f1circle.com.
When the bottom banner becomes visible, I have to show a spotlight to the user asking him to login.
The code that achieves it using angularjs can be viewed at https://github.com/rajegannathan/angularUtilities/blob/master/directives/eagerload.js
Though it is an angularjs directive, the main logic is in plain javascript. Basically I check if the the last feed's bottom edge is visible and then trigger the spotlight.
I can explain more if required.
As already mentioned, there is no "event" but someone already wrote a method to "detect if a DOM Element is Truly Visible" (the title). It doesn't require JQuery. You might want to check for the value on several events like the document load, scroll or window resize.
I need to navigate to the element 'divElem1', on click of a button. Is it possible?
If we enter this link in browser, http://myUrl#divElem1, browser will navigate to the page and to the DIV element 'divElem1'. The same behavior has to be obtained through javascript.
The hash change will not work in my application, as there are other events will be fired on hash change.
So, the following will not work.
document.button.onclick = function () {
location.hash = "#divElem1";
};
document.getElementById("divElem1").focus() is also not working since the element is a div
You can use scrollIntoView for that:
document.getElementById("divElem1").scrollIntoView()
This doesn't give fine grain control over where exactly the target element will end up but it WILL be moved into the view-port. Even more, if the element is inside a scrollable container, both the container and the element inside it will be moved into a position so they are visible in the view-port.
If you want "plain" Javascript, use scrollIntoView(). But it really jumps to that position, see this question and answer.
Using jQuery, it can be done jumpy or with some easing, as explained here.
Easing is recommended to provide a better user experience and to let visitors see and understand what is happening.
I have a blog that consists of consecutive entries, ie. divs. I have a separate background image for each entry. I want to change background image when a specific div gets visible in the client window. I couldn't figure out how to trigger it.
I think this is not about :visible or .show, all divs are alredy visible. However the page is long due to consecutive entries and I just want to change background image when the page is scrolled and a div get in sight.
Note: A javascript solution would be better by the way, if exists... rather than jQuery
I think you need to bind a function to the windows scroll event and validate the div's when the event is fired.
$j(document).bind("scroll", function() {
//check here
});
I found where someone is offering a plugin for this sort of thing too: http://remysharp.com/2009/01/26/element-in-view-event-plugin/
--edit--
here is a similar question and answer:
Check if element is visible after scrolling
I have two elements (think of two buttons side by side). I dynamically toggle the class "focusd" to change the highlighted effect. However, there's a quirk it doesn't always get redrawn and/or inserted in the DOM. For example, if in chrome I do console.log, I see the class changes (I'm using removeClass/addClass in jquery). But if I go to the Elements tab in the inspector, it shows the classes from before (and in fact, I'm not seeing the redrawing reflecting the toggling of the classes.)
I tried setting the parent div to display none then back to block but that didn't work. It's a "one off" modale screen, so efficiency doesn't matter so I've resorted to this hack where I essentially copy the parent's innerhtml, remove and reinsert the element. Horrible!
// Not sure why I need this hack. But if I don't, the buttons don't seem to get redrawn
var htm = jQuery(".rdata_container").html(); // copy the innerhtml
jQuery(".rdata_container").empty(); // empty and then append back
jQuery(".rdata_container").append(htm);
This seems like a specific quirk that someone must have ran into (I hope). If so, I'd love to know why my changes aren't reflected.
EDIT
Code posted here:
http://jsfiddle.net/roblevintennis/JCZnf/
you can use setTimeout when you are doing the other operation on the element, so for example:
$elm.addClass('hide')
setTimeout(function(){
$elm.removeCalss('hide')
},0);
Or you could force a repaint like so:
$elm.addClass('hide')
$elm.scrollTop; // forces a repaint (might be expensive for large amount of items)
$elm.removeCalss('hide');
These tricks will force the browser to re-draw the change, because there are two things happening here and the browser logic just combines them into one, which isn't the desired behavior.
Not directly an answer to your question, but you can use jQuery's toggleClass function to simplify your code.
Here's an updated version that uses toggleClass() and jQuery 1.6 and AFAICT works fine.
http://jsfiddle.net/JCZnf/7/
I'm developing a web application that shows some controls and descriptions dynamically (I don't want to use jQuery or other libraries).
At this moment i make appear and disappear controls using:
element.setAttribute("style", "display : inline");
and
element.setAttribute("style", "display : none");
but i'm thinking about using:
element.appendChild(childRef);
and
element.removeChild(childRef);
So, which one is the best solution in terms of system speed and elegance of the code?
Or is there a better way to go about this?
element.appendChild(childRef); and element.removeChild(childRef); both make the browser to manipulate the DOM tree while changing CSS just changes one of the attributes.
So, changing CSS is faster.
Dev Opera says
When an element has its display style set to none, it will not need to repaint, even if its contents are changed, since it is not being displayed. This can be used as an advantage. If several changes need to be made to an element or its contents, and it is not possible to combine these changes into a single repaint, the element can be set to display:none, the changes can be made, then the element can be set back to its normal display.
This will trigger two extra reflows, once when the element is hidden, and once when it is made to appear again, but the overall effect can be much faster
Another relevant article explains about reflow and repaint
Definitely go on using display properties.
They are much faster than removing/appending children, but most important they work very well in every browsers.
I know appendChild/removeChild are supposed to be well supported in IE, but sometimes on my IE7 a still get things moving around after a new element is appended (this is only my personal experience).
Regarding the way you change the display properties I would simply do a more easy and cross-browser (setAttribute is not well supported by IE6/7 an also IE8 when in IE7 mode):
element.style.display = 'none'; //for hiding an element
element.style.display = ''; //for showing that element again using its default way of displaying
Showing an element by using display = 'inline' is wrong because the element might have by default a display block way of showing like DIV tags and you are changing its way of showing to inline wich is not correct and might lead to elements in your page moving out from the places you expect them to be.
I doubt there's much in it one way or the other, and even if there is, I bet it varies by implementation (IE vs. Chrome vs. Firefox vs. ...). Both will cause reflow events in the tree.
Showing and hiding is simple and straightforward. Adding and removing can have its uses, but for the most part is probably overkill. For one thing, you have to keep a reference to it so you can add it back later, and you have to remember where you need to add it back.
But (and this is a bit off-topic) your mechanism for showing and hiding has some issues:
With your example code, things can only be inline, not inline-block or block, which would be somewhat...limiting.
Your code also completely replaces the style information on the element (and may not work on IE; see David's comment on your question), so all other styles directly applied to the element will get blown away; consider using the style property of the element instead: childRef.style.display = 'none"; and childRef.style.display = "inline"; (or block, or...). That way, you don't bludgeon any other styles on the element.
Completely removing a child from the tree (while keeping a reference to it so you can put it back later) definitely has its uses, though. For instance, when it's not in the tree, it won't be found when you're walking the tree with selectors for doing this, that, and the other; which may be helpful.
A small aside: if you happen to be dealing with user editable elements in IE (i.e. inside a document with designMode "on" or inside an element with contenteditable true), setting the CSS display property to none won't have any effect, and you'll need to remove the elements from the DOM to hide them.
The first approach is better i think which just hides and displayes but does not remove from the DOM and add again.
I would think that performance is better just updating the style.
The answer will depend on what you are using the elements for. If it is very dynamic whether they should be shown or not, it might be a solution to add/remove from DOM, but if there are a static set of elements, it might be easier to set the style. Setting the style, you also have more control of the position in the document. Adding/removing from DOM, you need to be sure it is added at the right place.
Note:
Instead of element.setAttribute("style", "display:none"); you can use element.style.display= "none"; If you use the first approach, you will remove any other style settings on the element.
I think editing the style of an element will be faster, but which is better hide the element or remove it from dom, this depends on your needs, if you need to just hide the element or remove it.
May be you don't need the user see the element but you need to do some js logic on it, so hide here will be the best.