How to use intro.js with Polymer 2? - javascript

I want to use intro.js for first-time user experience in my Polymer 2 application. Below is the code how I'm trying to use but it's not working out for me.
<base href="https://polygit.org/polymer+v2.0.0/shadycss+webcomponents+1.0.0/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
<script src="intro.js/minified/intro.min.js"></script>
<link rel="import" type="css" href="intro.js/minified/introjs.min.css">
<dom-module id="my-app">
<template>
<style>
</style>
<p class="line1" data-intro='Hello step one!' data-step="1">Line 1</p>
<p class="line2" data-intro='Hello step two!' data-step="2">Line 2</p>
<p class="line3" data-intro='Hello step three!' data-step="3">Line 3</p>
<p class="line4" data-intro='Hello step four!' data-step="4">Line 4</p>
</template>
</dom-module>
connectedCallback(){
super.connectedCallback();
introJs().start();
}
Here's the Codepen for the same. Since, intro.js is not a polymer web component so, I'm not able to figure out how to use it with Polymer 2.

It won't work as you have it right now
Asides
If you are importing external styles into a polymer element, you need to use style-modules Read here , henceforth, preferably.
The link rel=import type=css is deprecated, but If you still want to use them, they should be placed inside your dom-module for polymer to shim it.
intro.js , can not be scoped to your polymer element. JS is scoped via IIFE's and you might have to code a wrapper to do that yourself for any external scripts
That is if you strictly want everything scoped.
Regarding Your question
The problem is, that intro.js, can not access DOM inside your element.
Hence, it can not reach any of your P tags
One solution, is to move / distribute them to an outer scope like the document itself, by using slots
<dom-module id="my-app">
<template>
<!-- uncomment this, if you have a style module pointing to intro'scss only-->
<!--<style include="intro-css"></style>-->
<slot>
</slot>
</template>
</dom-module>
Now, all you need to do is, place all your DOM inside the tags <my-app></my-app>
Only then will intro.js work on them. plunker

Related

How do you activate alpinejs?

I'm trying to add AlpineJS to a very simple html page that I'm working on and the package is being executed (from cdn) but it doesn't seem to get activated correctly. Even on this small snippet of HTML, it doesn't work:
<html>
<head>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.x.x/dist/alpine.min.js" defer></script>
</head>
<body>
<h1 x-show="false">hide me</h1> <!-- doesn't work-->
</body>
<script type="text/javascript">
console.log($el); //undefined
</script>
</html>
This is also loaded into a codepen where the problem can be observed: https://codepen.io/dwarburt/pen/gOgZyeR
I'm sure I've just missed a step, but what could it be? AlpineJS is executing its initialization routines, you can tell from the debugger.
To initialise an AlpineJs component you'll need an x-data attribute on the parent container:
<div x-data="{
isShowing: false
}">
<h1 x-show="isShowing">I am hidden</h1>
</div>
This contains an object with properties and functions you can use within the component instance.
It's definitely worth reading through the docs in the repo here: https://github.com/alpinejs/alpine#use
I have adjusted your example in order to achieve the result you require, along with an additional example so you can see how multiple object properties can exist and used within your Alpine.js components.
x-data does not need to be initiated on the body tag, however nested components will retrieve the object property from the closest x-data property match.
You can access from child nodes of nested x-data objects the properties.
Careful of your property naming conventions if you don't wish to overwrite proceeding object properties.
I would also suggest reading Build a Drop Down along with Toggle Element
Reading these points will be helpful in understanding the below example in further detail.
<html>
<head>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.x.x/dist/alpine.min.js" defer></script>
</head>
<body x-data="{show: false, button: 'Toggle'}">
<button #click="show = ! show" x-text="button"></button>
<span x-show="show">
<h1 #click.outside="show = false">hide me</h1> <!-- doesn't work-->
</span>
</body>
</html>

Is there a Wordpress method or PlugIn to call JS function from <body> tag?

I have two JS functions I want to call, in a wordpress site, from an external .js file. When writing the functions, I called one from the HTML document's tag, but didn't think of how to actually apply this in WordPress.
I see several PlugIns for altering headers/footers, but am just wondering if there's an option for the . Below is a sample which shows JS being called from my tag.
<html>
<head>
<title>SO Question</title>
</head>
<body onload="destroyEarth()">
<h1>Article title</h1><br>
<p>Article text</p><br>
<script async src="extFile.js"></script>
<p>
<a href="#"" onclick="dscntFuniture();" id="FSP" name="FSP">
<img src="https://i.imgur.com/4LtRreH.png" id="RRU" name="RCU"/>
</a>
</p>
<p>....more article text</p>
</body>
</html>
I'd like to be able to call destroyEarth() and dscntFuniture(), from extFile.js, in a WP site. Ideally there'd be a Plugin or alternative way of writing the code so that I can implement this.
Edit:
<script async src="extFile.js">
$(document).onload(destroyEarth);
</script>
jQuery onload does it for you:
$(document).onload(destroyEarth);
There should not be a practical difference between document and body onload event. Both will be triggered when content is loaded.
UPDATED:
add the following code in either header or footer of your website. It does not depend on any library, thanks #Shilly:
<script>
document.addEventListener('DOMContentLoaded', destroyEarth );
</script>
If it does not work, look into developers console for js errors and post them here

Access Shadow DOM polymer elements with meteor

How do I access the paper-button with id='signin' outside of the Polymer constructor. I need to access it from Template.{template-name}.rendered method. Is there a way to use selector for paper-button?
<!-- Code -->
<dom-module id="app-bar">
<template>
<link rel="import" href="bower_components/iron-media-query/iron-media-query.html">
<iron-media-query query="min-width: 1008px" query-matches="{{largeScreen}}">
</iron-media-query>
<template is="dom-if" if="{{largeScreen}}">
<span class="separator">
<link rel="import" href="bower_components/paper-button/paper-button.html">
<paper-button id="signin" on-click="login" raised>Sign in</paper-button>
</span>
</template>
<template is="dom-if" if="{{!largeScreen}}">
<span class="title"></span>
</template>
</template>
<script>
Polymer({
is: "app-bar",
login: function() {
FlowRouter.go('/login');
}
});
</script>
</dom-module>
<!-- In the landing-page.html -->
<landing-page>
<link rel="import" href="app-bar.html">
<app-bar></app-bar>
</landing-page>
The easy, less prone way to breakage... (with shadowRoot you will potentially break in Polyfil'd browsers) get a reference to your 'app-bar' element and from there use the $ property id shortcut. If you cannot find the element via [landing-page].querySelector('app-bar') then try Polymer.dom(landing-page-element.root).querySelector('app-bar'). ($ shortcut only works for elements given an ID in that particular elements template, so for your app-bar this will work with signin. It would not work if the elements/ids were generated by a dom-repeat though.
document.querySelector('landing-page').querySelector('app-bar').$.signin;

Pass DOM nodes to Polymer as attributes

Ok, so I'm defining a polymer object like this:
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="my-element" attributes="content">
<template>
<div class="someclass">
{{content}}
</div>
</template>
<script>
Polymer({});
</script>
</polymer-element>
Which works fine if I instantiate it as:
<my-element content="test"></my-element>
However, I'd like to be able to pass HTML inside the element. If I do this:
<my-element content="<div>test</div>"></my-element>
The HTML is not added to the DOM, but displayed as text. Is it possible to pass HTML inside a polymer element? Or am I doing something completely wrong here?
Thanks for any help!
Here's some hackish code I made that may answer your question.
http://jsbin.com/hedutu/edit?html,output
Basically, I created an observer for an attribute that accepts DOMs in string format and then inserted that dom into a local dom node.

How to attach an HTML element or a DocumentFragment to the DOM?

I’ve got an HTML fragment like <p>Hello, World!</p> and want to attach it to the container HTML page that includes
<script src="lib/kotlin.js"></script>
<script src="my-app.js"></script>
There are two package that came to my mind:
kotlin.js.dom.html.window.document.*
kotlin.browser.document.*
Which should I use and how do I access the document’s root? I’ve already tried document.getElementById("container") whereby container is the id of a DIV. But this returns null. I also tried document.appendChild(node)...
Also which of the above packages should I prefer?
I just figured out that the JS output of the compiled app needs to be below the element that is referenced inside the app.
I’ve created a demo case that illustrates this:
<!DOCTYPE html>
<meta charset="utf-8"/>
<script src="lib/kotlin.js"></script>
<p>Look inside the JavaScript Console of your browser…</p>
<div id="container"></div>
<script>
console.log("Native JavaScript");
</script>
<!-- This script tag was misplaced. It needs to be placed after all elements you want to access in your DOM -->
<script src="kotlin-javascript-hello-world.js"></script>

Categories

Resources