I just started on Polymer and there are things I hope can get clarification on. For example, in this documentation: https://elements.polymer-project.org/elements/paper-header-panel. In the last card about Events, there is a script that when content-scroll is triggered. However, I have no idea where to put that script and why double curly brace {{}} is used. If there is a documentation on this it would be great! Thanks.
These are the places that I have tried to put that script:
<!-- Uncaught SyntaxError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'undefined'. The type name is invalid. -->
<script>
(function() {
Polymer ({
navigationbarScrollHandler: function(event) {
var scroller = event.detail.target;
console.log(scroller.scrollTop);
}
});
})();
</script>
<!-- Uncaught SyntaxError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'undefined'. The type name is invalid. -->
<script>
Polymer ({
navigationbarScrollHandler: function(event) {
var scroller = event.detail.target;
console.log(scroller.scrollTop);
}
});
</script>
<!-- Uncaught NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'paper-header-panel'. A type with that name is already registered. -->
<script>
Polymer ({
is: "paper-header-panel",
navigationbarScrollHandler: function(event) {
var scroller = event.detail.target;
console.log(scroller.scrollTop);
}
});
</script>
<!-- Uncaught SyntaxError: Unexpected token ( -->
<script>
navigationbarScrollHandler: function(event) {
var scroller = event.detail.target;
console.log(scroller.scrollTop);
}
</script>
<!-- console doesn't log anything -->
<script>
Polymer ({
is: "custom-element",
navigationbarScrollHandler: function(event) {
var scroller = event.detail.target;
console.log(scroller.scrollTop);
}
});
</script>
You will also need to add is and properties properties to your Polymer() function as well as an id to your <dom-module> that matches the value of your Polymer() is property. Something like the following.
Code:
<dom-module id="my-example-element">
<style>
...
</style>
<template>
...
</template>
</dom-module>
<script>
(function() {
Polymer ({
is: 'my-example-element',
properties: {
// See and follow examples
},
navigationbarScrollHandler: function(event) {
var scroller = event.detail.target;
console.log(scroller.scrollTop);
}
});
})();
</script>
Answers:
Double curly braces {{}} is Polymer's data-binding syntax.
The scrollHandler you ask about goes inside your Polymer() function in your <script> section at the very bottom of your custom element but outside your <dom-module>. Here is an example (real world) of the structure your code should follow. (Or see above code for a made-up theoretical example.)
Suggestions:
The best tutorial you can get on all of this is to download the Polymer Seed Element. Then look it over and read all the comments (which serves as de facto documentation). It will get you up and running quickly and provide the context you need. It has all the sample code and explanatory documentation you need to make sense of the question you asked.
You should also download the Polymer Starter Kit. If you haven't done so already. Again, follow the code and it will answer most of the questions you have asked here plus others you don't even know to ask yet.
Related
in a SPA, using options API, how (where) to define a function that will be called from an html href?
In the following codepen for demo, everything works fine.
CODEPEN
However, on my Single Page:
<template>
<div v-html="my_div" />
</template>
<script>
/* function MyFunction() {
alert();
}; */
const MyFunction = () => {
alert();
};
/* Just for explanation, because the data comes from the database
export default {
data() {
return {
my_div:'link call function ',
}
}
*/
}
</script>
call the function return the error:
Uncaught ReferenceError: MyFunction is not defined
Apparently, the function is defined after the call
Any idea how to solve this?
Not sure what you're trying to do here but don't evaluate some random string coming from nowhere into a weird format. It will not work, will be clunky, non-debuggable.
If your codebase is legacy and has a lot of debt, refacto it or use jQuery or whatever to hack it even further.
I'm trying enter code here in to execute an imported module from a HTML page. I get to see that it's partially getting executed. I need help. My code files are test.html, main.js and say.js. These files are produced below in the same order.
test.html:
<html>
<head>
<script type="module" src="./main.js"></script>
</head>
<body onload="sayHi('Manish')">
</body>
</html>
main.js:
import { sayHi } from './say.js';
sayHi('MK');
say.js:
export function sayHi(user) {
alert('Hello, { $user }');}
This code partially executes
Then after this partial execution, it gives an error
Uncaught ReferenceError: sayHi is not defined
at onload (test.html:7)
The picture of the error is as shown below:
This is the error that says sayHi function is not recognized. Why?
What am I doing wrong here?
One of the great things about modules is that top level declarations, etc., in them don't create globals. One of the bad things about onxyz-attribute-style event handlers is that the functions you call with them have to be globals. Your sayHi isn't a global, so onload="sayHi('Manish')" fails because it doesn't have access to sayHi.
Which is a good thing.
Instead, just call the function from main.js:
import { sayHi } from './say.js';
sayHi('MK');
sayHi('Manish');
Because module scripts are automatically deferred until the end of HTML processing, you know that won't happen until all the HTML is loaded. This is covered by a great graphic in this section of the spec, duplicated here:
If you want to wait longer, until the load event (which doesn't fire until all images and such are loaded), use a modern event handler to do that:
import { sayHi } from './say.js';
sayHi('MK');
window.addEventListener("load", () => {
sayHi('Manish');
});
If you need information from the element you hooked the event on, use a traditional function and access the element as this, or accept the event parameter and use event.currentTarget (you can also use event.target for the element that the event targets, which could be within the element you hooked the event on). So for instance, suppose you have:
<button type="button" data-name="Manish" id="btn-say-hi">
you could have:
import { sayHi } from './say.js';
document.getElementById("btn-say-hi").addEventListener("click", function() {
sayHi(this.getAttribute("data-name"));
});
Also note that as Vikas Saini pointed out your say.js is using a string literal instead of a template literal (and although he/she didn't mention it, also has the wrong syntax for a substitution), so you'll actually see the text Hello { $user } instead of seeing Hello MK or Hello Manish. Either use a template literal with the correct form of substitution (${user}, not { $user }):
export function sayHi(user) {
alert(`Hello, ${user}`);
}
or simple string concatenation:
export function sayHi(user) {
alert("Hello, " + user);
}
Classic case of String interpolation
Use
export function sayHi(user) { alert(`Hello, ${user}`);}
Notice ` in place of ' or "
Reference https://campushippo.com/lessons/how-to-do-string-interpolation-with-javascript-7854ef9d
For the Error, bind the window to load
window.addEventListener("load", () => {
sayHi('testing');
});
Basically my objective was to pass some parameter from the HTML script to the main.js file. I have got the required after both of you have given me hints, especially Vikas Saini. The suggestion of adding an event listener in the main.js file helped a lot. Thanks much. I'm posting the corrected and the latest code files for the benefit of ES6 beginners like me.
The test.html file contents
<html>
<head>
<script type="module" src="./main.js"></script>
</head>
<body>
<input type="text" id="btn-say-hi"label="fill here" placeholder="Fill in here and click"/>
</body>
</html>
The main.js file contents
import { sayHi } from './say.js';
document.getElementById("btn-say-hi").addEventListener("click", function() {
sayHi(this.value);
});
The say.js file contents
export function sayHi(user) { alert(`Hello, ${user}`); }
Kindly note: All these files are in the same directory/folder. I could change the text item value and could get the required execution based on my inputs.
Thanks much to T.J. Crowder and a special thanks to Vikas Saini for the code snippet pertaining to adding the event listener. That was a golden suggestion.
Thanks much guys.
Regards
Manish.
I am trying to write some userscripts in JavaScript to be used with browser extensions.
In a website, I tried overriding a function defined in an external javascript, with Object.defineProperty. but it seems that this breaks the external script, because other codes in the external scripts (that are essential to the original website) seems to be not executing as well.
<html>
<head>
<!-- injected script, injected via Userscript -->
<script>
Object.defineProperty(window, 'originalFunction', { get: function() { return overridingFunction; } });
</script>
<!-- injection end -->
</head>
<body>
<script src="/external-javascript.js">
<script> originalFunction(); </script>
<script> anotherEssentialFunction(); </script>
</body>
</html>
and http://domain/external-javascript.js looks like this"
...
function originalFunction() {
some codes here;
}
...
function anotherEssentialFunction() {
....
}
and this was preventing anotherEssentialFunction from running. In the console, I see TypeError: can't redefine non-configurable property originalFunction and ReferenceError: anotherEssentialFunction is not defined
Is this expected in this situation, or there should be other problem causing it that is not described here? How can I safely override original function without causing such an error?
Object.defineProperty takes the name of a function as a parameter, so you'd have to do this instead:
Object.defineProperty(window, 'originalFunction', {
get: function() {
return overridingFunction;
}
});
Or if that's all the getter does, simply:
window.originalFunction = overridingFunction;
But if the other functions need to call the original function, you can't really override it without breaking the functions that rely on its behavior. If you're just trying to execute custom code in addition to the original code, you can do this:
var origFn = window.originalFunction;
window.originalFunction = function () {
customFunction();
origFn.apply(this, [].slice.call(arguments));
};
Update:
Based on your comment, it sounds like you're wanting to not only override the original function but also prevent the external script from redefining that function. You can maybe add a no-op setter to avoid the external script from getting an error when trying to define it:
Object.defineProperty(window, 'originalFunction', {
get: function() {
return overridingFunction;
},
set: function(ignored) { }
});
I have this HTML:
<template is="auto-binding" id="container-binding-template">
<core-scaffold id="scaffold" onscroll={{containerScrolled}}>
<div id="container">
The auto-binding template and <core-scaffold> are part of Polymer.
This is the JavaScript:
var template = document.querySelector('#container-binding-template');
template.containerScrolled = function() {
// regardless of the code here, the error will occur (event if it's empty)
};
When I run this code I get the following error (in Chrome DevTools):
Uncaught SyntaxError: Unexpected token ( VMxxxx:2
When I open the VMxxxx file (e.g. VM1362) I see this code:
(function() {with (this[2]) {with (this[1]) {with (this[0]) {return function(event) {function () {
// This line contains the same code as in containerScrolled(). This is where the error is pointing to.
}
};}}}})
What's causing this error? How can I fix it?
Any help would be appreciated.
Update #1: JSFiddle
The event attribute should be on-scroll. What you have there is the native inline event handlers, which expect the input to be the body of a function.
For some reason my javascript code is messed up. When run through firebug, I get the error proceedToSecond not defined, but it is defined!
JavaScript:
<script type = "text/javascript">
function proceedToSecond () {
document.getElementById("div1").style.visibility="hidden";
document.getElementById("div2").style.visibility="visible";
}
function reset_Form() {
document.personalInfo.reset();
}
function showList() {
alert("hey");
if (document.getElementsById("favSports").style.visibility=="hidden") {
document.getElementsById("favSports").style.visibility="visible");
}
}
//function showList2() {
//}
</script>
HTML:
<body>
<!--various code -->
<input type="button" onClick="proceedToSecond()" value="Proceed to second form"/>
</body>
The actual problem is with your
showList function.
There is an extra ')' after 'visible'.
Remove that and it will work fine.
function showList()
{
if (document.getElementById("favSports").style.visibility == "hidden")
{
// document.getElementById("favSports").style.visibility = "visible");
// your code
document.getElementById("favSports").style.visibility = "visible";
// corrected code
}
}
There are a couple of things to check:
In FireBug, see if there are any loading errors that would indicate that your script is badly formatted and the functions do not get registered.
You can also try typing "proceedToSecond" into the FireBug console to see if the function gets defined
One thing you may try is removing the space around the #type attribute to the script tag: it should be <script type="text/javascript"> instead of <script type = "text/javascript">
I just went through the same problem. And found out once you have a syntax or any type of error in you javascript, the whole file don't get loaded so you cannot use any of the other functions at all.
important: in this kind of error you should look for simple mistakes in most cases
besides syntax error, I should say once I had same problem and it was because of bad name I have chosen for function. I have never searched for the reason but I remember that I copied another function and change it to use. I add "1" after the name to changed the function name and I got this error.