(Polymer) Custom Element lifecycle hook after style and layout - polymer

I need to know where on the page my element is when my element gets initialized. I tried using connectedCallback
connectedCallback(){
console.log(this.$.someDiv.getBoundingClientRect())
}
but it gives me {top: 0, right: 0, bottom: 0, left: 0, width: 0…}, apparently because when connectedCallback is called, layout hasn't happened yet. When I go in with dev tools, $0.$.someDiv.getBoundingClientRect() gives me the correct values (e.g. in this case {top: 154.59375, right: 614, bottom: 634.59375, left: 54, width: 560…})
Is there any lifecycle hook or event or something that I can use to get this information after layout has been calculated? I don't want to have to use SetTimeout and just hope it works...

Related

Custom Loading Cursor

I want to know if there is a way to change the "progress" cursor's loading animation. Like changing the cursor like in this CSS-Trick post.
Two ways to achieve what you want.
The CSS way
If you want to completely customize the cursor, you can use cursor which accept images (in your case, a .gif !)
._show-loader:hover {
cursor: url('http://i117.photobucket.com/albums/o72/redfenderstrat/Debian_Rotate.gif');
}
I like this approach since I prefer keeping JS out of my pure design things as much as possible.
The jQuery way
If you need to add an animation after user's cursor (to make this more natural since people does not have the same cursor), this jQuery alternative will make the image stick to the cursor.
var $showLoader = $('._show-loader');
$showLoader.on('mousemove', function(e) {
var cursorPos = {
left: e.pageX + 20,
top: e.pageY + 20,
}
$("._cursor-onLoad").css({
left: cursorPos.left,
top: cursorPos.top
});
});
$showLoader.on('mouseenter', function() {
$('._cursor-onLoad').css({
display: 'block',
})
});
$showLoader.on('mouseleave', function() {
$('._cursor-onLoad').css({
display: 'none',
})
});
JSFiddle here
I doesn't really like this alternative since it does this 2002-sluggish effect.

Google Maps InfoWindow width is overwritten even when set correctly

I'm using Google Maps API and I have some troubles about InfoWindow.
Here is a summary :
I'm loading the InfoWindow's content when user clicks on a marker
The content is a partial view, loaded thanks to an Ajax call
In the .done callback, I call an asynchronous method which will insert data into the InfoWindow content. I need to do this because I want the InfoWindow main content to be displayed immediately, whereas this "bonus" information could be displayed after some tenths of seconds.
This perfectly works ; but I have a white strip on the right of my InfoWindow I can't remove (see the picture below)
However, the content I load is included in a <div> with a fixed width :
<div id="div-main-infoWindow">
<!-- All my content -->
</div>
And in my CSS, I wrote :
#div-main-infoWindow {
width:342px !important;
}
The loading of the InfoWindow, with more details, looks like this :
$.ajax({
url : "/my-url",
async : false,
contentType : "application/json; charset=utf-8",
dataType : "json",
type : "POST",
data : JSON.stringify(myModel)
}).done(function(response) {
MarkerContent = response.Content; //The HTML content to display
MyAsyncMethod().then(function(response) {
//do some formatting with response
return result; //result is just a small HTML string
}).done(function(result1, result2) {
//do some formatting with result1 and result2
$("#myNode").html(/*formatted result*/);
})
//info is a global variable defined as new google.maps.InfoWindow()
info.setOptions({
content: MarkerContent,
maxWidth: 342 //To be sure
});
info.open(map, marker);
});
});
The content is perfectly OK, the problem is all about this white strip.
Looking at my browser console (I reproduced it in ALL browsers), I can see this :
As you can see there, my <div> containing all my data loaded from my ajax call is OK with the good size (green rectangle, corresponding to the greyed zone in the screenshot), BUT the above divs (from Google API itself, into the red rectangles) have a bigger size, from which the problem is.
The only way I found is running this jQuery script modifying the InfoWindow internal structure :
$(".gm-style-iw").next().remove();
$(".gm-style-iw").prev().children().last().width(342);
$(".gm-style-iw").prev().children(":nth-child(2)").width(342);
$(".gm-style-iw").width(342);
$(".gm-style-iw").children().first().css("overflow", "hidden");
$(".gm-style-iw").children().first().children().first().css("overflow", "hidden");
$(".gm-style-iw").parent().width(342);
Note : gm-style-iw is the class name given by Google of the div containing all the content of the InfoWindow, the one hovered on the above screenshot. I also add this rule in my CSS :
.gm-style-iw {
width: 342px !important; //also tried with 100% !important, not better
}
It works in the console, however, it has no effect when written in the code itself, in the .done callback, or in the domready Google Maps' event...
However, in this late case, if I encapsulate the above jQuery script in a setTimeout(), it works !! I commented the asynchronous method, so it's not this one which is guilty, but it seems domready is executed whereas 100% of the InfoWindow is not still displayed - which is contrary to the doc.
I also tried to move my info.setOptions outside the .done callback and put it at after it, no effect.
So, how can I display a "normal" InfoWindow without this white strip on the right ?
I don't want to implement InfoBubble or other custom InfoWindow library. It's a personal project and I want to understand why and where the problem is. And of course, find a solution.
Thank you for your help !
It's a little bit more complex than you think.
Just some things:
did you notice that there is a close-button? Even when you remove the button the space will be there, because the API calculates the size of the other nodes based on this space
the tip must be in the center
there are additional containers for rounded borders and shadows
the size of the infoWindow will be calculated so that it fits into the viewport
the content must be scrollable when needed
the position of the infowindow must be set(therefore it's required to calculate the exact height of the infowindow)
Basically: all these things require to calculate exact sizes and positions, most of the nodes in the infowindow are absolute positioned, it's rather a technique like it will be used in DTP than you would use it in a HTML-document.
Additionally: the InfoWindows will be modified very often to fix bugs, a solution which works today may be broken tomorrow.
However, an approach which currently works for me:
set the maxWidth of the infowindow to the desired width - 51 (would be 291 in this case)
It's not possible to apply !important-rules via $.css , so it must be done via a stylesheet directly. To be able to access all the elements set a new class for the root-node of the infowindow(note that there may be infoWindows which you can't control, e.g. for POI's):
google.maps.event.addListener(infowindow,'domready',function(){
$('#div-main-infoWindow')//the root of the content
.closest('.gm-style-iw')
.parent().addClass('custom-iw');
});
the CSS:
.custom-iw .gm-style-iw {
top:15px !important;
left:0 !important;
border-radius:2px;
}
.custom-iw>div:first-child>div:nth-child(2) {
display:none;
}
/** the shadow **/
.custom-iw>div:first-child>div:last-child {
left:0 !important;
top:0px;
box-shadow: rgba(0, 0, 0, 0.6) 0px 1px 6px;
z-index:-1 !important;
}
.custom-iw .gm-style-iw,
.custom-iw .gm-style-iw>div,
.custom-iw .gm-style-iw>div>div {
width:100% !important;
max-width:100% !important;
}
/** set here the width **/
.custom-iw,
.custom-iw>div:first-child>div:last-child {
width:342px !important;
}
/** set here the desired background-color **/
#div-main-infoWindow,
.custom-iw>div:first-child>div:nth-child(n-1)>div>div,
.custom-iw>div>div:last-child,
.custom-iw .gm-style-iw,
.custom-iw .gm-style-iw>div,
.custom-iw .gm-style-iw>div>div {
background-color:orange !important;
}
/** close-button(note that there may be a scrollbar) **/
.custom-iw>div:last-child {
top:1px !important;
right:0 !important;
}
/** padding of the content **/
#div-main-infoWindow {
padding:6px;
}
Demo(as I said, may be broken tomorrow): http://jsfiddle.net/doktormolle/k57qojq7/
Bit late to the party here, but after searching for ages to achieve the same thing as the OP a thought occurred to me. The width seemed to be getting set by the parent element of .gm-style-iw so I just set the parent elements width to auto using jQuery and hey presto! So here is my code in the hope it may help someone in the future.
JS
$('.gm-style-iw').parent().css('width', 'auto');
CSS
.gm-style-iw {
width: auto !important;
top: 0 !important;
left: 0 !important;
}

Adding footer for printing web pages and setting margins without media print

How can set bottom margin for web page without using class when document print.
for some reason i can not create document head. i cant use code something like this because i have no access to head of document.
#media print {
p.note {
bottom: 0; position: fixed;
}
}
If you can't, or, for some reason, don't want to use css #media, you can always use some jquery:
window.onafterprint = function() {
$("p.note").css("position","fixed");
$("p.note").css("bottom","0");
}; // IE5+
window.matchMedia('print').addListener(function(change) {
if !(change.matches) {
$("p.note").css("position","fixed");
$("p.note").css("bottom","0");
}
}); // Chrome 9+, Safari 5.1+
Here you can find some more info: http://tjvantoll.com/2012/06/15/detecting-print-requests-with-javascript/
And also there nearly exists a plugin: https://code.google.com/p/jmediatype/

Onload set divs opacity to 50%

Okay, so I have a site running Joomla and it is using the mootools 1.11 framework. I've fudged together a working version of this using examples from the mootools 1.2 framework but cannot get the two to co-exist even with the compatibility layer, without breaking other modules in the Joomla site.
Question
I have a couple of divs with a class of ".box_panel" and I have it so that they on mouseover they go from 50% opacity and back to 100% opacity on mouseleave. The problem I'm having is what is the code to set them to 50% onload?
In mootools 1.2 I used:
<body onload="$$('div.box_panel').fade(0.5);">
The code I'm using for the mouseover/mouseleave effects is:
window.addEvent('domready',function() {
//first, apply a class to each of your menu element
//$$('.links') puts every element wearing the .links class into an array
//$$('.links').each is to browse the array an apply a function to... each of them
$$('.box_panel').each(function(el, i) {
//there comes exactly your former fx statement except for
var ExampleFx = new Fx.Style(el, 'opacity', { //the fact i apply the effect on el
wait: false, //and wait: false which make the effect not waiting (very useful on the mouseout or mouseleave function...
opacity: 0.5,
duration: 500,
transition: Fx.Transitions.Quart.easeInOut
});
//and there i apply (always on el) the effect on mouseenter (similar in this case but often better than mouseover)
//and mouseleave (same for mouseenter but concerning mouesout)
el.addEvent('mouseleave', function() { ExampleFx.start(1, 0.5); });
el.addEvent('mouseenter', function() { ExampleFx.start(0.5, 1); });
});
});
Can you not just add ExampleFx.start(1, 0.5); before the last brackets (after the $$('.box_panel')... statement)?
Simple:
$$('.box_panel').effect('opacity', 0.5);
// run this right after your window.addEvent('domready', function() {
Edit: I were a bit wrong here. Mladen Mihajlovic answered completly correct. Also, here are some links for you:
MooTools 1.11 Documentation
MooTools 1.11 Demos

css and image sprites

I got a quick question about sprites in css:
Will I send two HTTP Request if I include the same image twice in a css file? For example if I want to load two different buttons from the same icon set image:
.btn-1 {
background:url('img/icons.png') 0 0;
}
.btn-2 {
background:url('img/icons.png') 0 -60px;
}
or is there another way to only include the image once?
The browser will cache the image so the 2nd time its fetched from cache.
But what you want to do in a situation like this is to let CSS do its job.
If those buttons are <a> for example.
a {
background: url('img/icons.png');
}
.btn-1 {
background-position:0 0;
}
.btn-2 {
background-position: 0 -60px;
}
Besides that what Ólafur said, you could also rewrite your CSS that the URI reference will only occur once:
.btn-1,
.btn-2 {
background:url('img/icons.png') 0 0;
}
.btn-2 {
background-position: 0 -60px;
}
Yes but the client should receive a HTTP 304
304 Not Modified
If the client has performed a conditional GET request and access is allowed, but the document has not been modified, the server SHOULD respond with this status code. The 304 response MUST NOT contain a message-body, and thus is always terminated by the first empty line after the header fields.
So the image will not be send twice but used from cache instead.
HTTP/1.1: Status Code Definitions