vuejs : how to preload image inside a component - vue.js

I have images inside a component not displayed at launch.
When i show my component, my images are not displayed instantly, but are loaded.
I would like to preload my images on the root app, to be instantly displayed when the component is active.
How would you do that?

components are bind to dom only when they are created. images will be loaded only when dom sent request. you can try something
let image = new Image();
image.src = 'something.png'.
this will trigger a network request. you can use the image variable as props to component

You can also do it with css background images. Simply add this css to your global styles:
html {
background-image: url('url1.jpg'),
url('url2.jpg'),
url('url3.jpg'); // list all images here
background-size: 0;
}
This might be a little bit hacky, but all images get preloaded asynchronously. From here on you can optimize it by going more specific on where to apply the styles e.g. scoped in child components or wherever you want.
If you have a lot of images you could also write a simple webpack plugin which generates this code dynamically.

Related

Change background color of ion-page element only, not descendent elements, in Ionic Vue

I have an Ionic Vue3 app. I'd like to change the background color of the whole page. I'm new to Ionic but I believe the way this has to be done (due to the use of Web Components/Shadow DOM) is to modify the --ion-background-color CSS custom property rather than trying to set the value of the normal CSS property, so this works:
.ion-page {
--ion-background-color: red;
}
...but this doesn't:
.ion-page {
background-color: red;
}
Fine, so I do the former, but the problem now is that all elements within the page (everything inside the <ion-page></ion-page> element which use that same custom property value now inherit the same background color.
Does anyone know how to scope the change of background colour of the ion-page element such that it doesn't cascade through descendent elements? Thanks :)
The solution here was to use local CSS custom property --background rather than the global property --ion-background-color. So the following works:
.ion-page {
--background: red;
}
I didn't previously realise there were different sets of CSS variables for different scopes.

Vue lazyloading gets triggered when adding dynamic class to <main>

I am adding a 'sticky-header' class to my dynamically, but when its sticky i obviously also need to add padding to my so the content doesnt go behind the header.
The problem is that when adding the padding via class-binding(v-bind:class="{'fixed-header': stickyHeader}")on scroll, this reloads all the lazy-loaded images (that are lazy loaded using vue lazy)
This makes all images go from loading to loaded in a split second, but its very noticable.
stickyHeaderis a boolean that gets recalculated on scroll, if the window is scrolled past a certain element (with a eventlistener on scroll: checkHeader())
checkHeader() {
var elementTarget = document.getElementById("notice");
if(window.scrollY > (elementTarget.offsetTop + elementTarget.offsetHeight)){
this.stickyHeader = true;
}
else{
this.stickyHeader = false;
}
}
Anyone know what exactly triggers the images to go back to 'loading' for a split second?
To solve this instead of dynamically binding the class with v-bind i simply add it in the scroll listener method with basic javascript, now it doesnt rerender :) !

Scroll to an element given in the location hash, when said element is loaded asynchronously on page load

I am passing an element ID using the location hash like so:
https://example.com/object/id#sub-object
However, the list of sub-object elements is loaded dynamically from an api after page load.
How can I scroll the viewport to the given element once the async request completes? Given that it's location is not available in the DOM on page load.
I solved this myself, I used jquery for the scroll animation because, easy.
if(window.location.hash && !this.hasScrolled){
var hash = location.hash.substring(1);
$('html, body').animate({scrollTop: this.$refs[hash][0].offsetTop -200} ,800);
this.hasScrolled = true;
}
This had to happen in the updated() hook on the component as this is the point when the element's offset is known. I added a hasScrolled property (initially set to false) so I can make sure it only does the scroll on initial page load.

Prestashop Slider

How to setup a slider at the bottom-right corner in Prestashop like the picture? This slider consists of different picture. When I click an image, relative information will be shown on the right corner.
Simple you need to build a custom module. Please ref to prestashop.com document how you build custom module.
On that module hook the theme file yourmodulefile.tpl at FOOTER
Then make a wrap Div, set a class "footer_slide_wrap"
On your module CSS mark that class as bellow
.footer_slide_wrap{
display :fixed;
bottom : 0;
right :0;
width : 30px;
height:auto;
}
Now your DIV with class footer_slide_wrap will be place on that place.
now insert an UL and put your all button under li in this UL.
You can make the div .footer_slide_wrap mouse over slidable. For that you need to make a default div with class .opener and make the wrap hide.
need to create a javascript function to hide / show the DIV on mouse over.
you need to register a custom hook inside your slider module's php file, eg: "footerslider" then add the hook to your fooeter.tpl file which is located at "themes/yourthemes/footer.tpl" by placing this code {hook h="fooerslider"}
Basically, you should create small module that have hook.
Prestashop has many hooks related with your layout but if they are not suitable for you, you can create your own hook.
If you want to call your custom hook, simply put this code where you want to show.
{hook h="displayYourHookName"}
You need to install your custom hook in your install() function of your custom module.
// use this code in your install() function
$this->registerHook('displayYourHookName');
// your custom hook
public function hookDisplayYourHookName()
{
// code ...
// your html template that you want to show
return $this->display(__FILE__, 'yourTemplate.tpl');
}
if you are using default hook, prestashop will call automatically.
I hope this will help, cheers :)

DojoX Mobile ListItem load HTML via AJAX and then remove from DOM

Let's say in a view I have a DojoX Mobile ListItem that is pulling an HTML view fragment into the DOM via AJAX and then transitioning to that view. Assume this is all working fine.
Now, I go back to the initial view that had that ListItem on it and click some other button that destroys that view node from the DOM. If I now click on that ListItem that previously loaded that view node into the DOM (which has now been removed), it will try to transition to a view that doesn't exist. It doesn't know that it has been removed.
Is there some type of way to tell a ListItem that it needs to fetch the HTML again because what was previously fetched no longer exists? I am not seeing anything about doing this in any documentation anywhere. I don't think a code sample is really necessary here, but I can provide a minimal one if necessary.
I went a different route and left the view exist in the DOM, and simply made a function that clears all sensitive data out of the view.
Okay, in this case, i guess you could hook the onShow function of your ListItem container(or any other onchange event). Create a listener for said handle to evaluate if your item needs reloading. Following is under the assumtion that it is the item.onclick contents showing - and not the label of your item which contains these informations
Or better yet, do all this during initialization so that your ListItem container will be an extended with custom onClick code.
Seems simple but may introduce some quirks, where/when/if you programatically change to this item, however here goes:
function checkItem() {
// figure out if DOM is present and if it should be
if( isLoggedIn() ) {
this.getChildren().forEach(function(listitem) {
if( dojo.query("#ID_TO_LOOK_FOR", listitem.domNode).length == 0 ) {
// this references the listItem, refresh contents.
// Note: this expects the listitem to be stateful, have no testing environment at time being but it should be
listitem.set("url", listitem.url);
}
});
}
}
Preferably, set this in your construct of the container for your ListItems
var listItemParent = new dojox.mobile.RoundRectList({
onShow : checkItem,
...
});
Or create listener
var listItemParent = dijit.byId('itemRegistryId');
// override onClick - calling inheritance chain once done
dojo.connect(listItemParent, "onClick", listItemParent, checkItem);