I'm working on a JavaScript script that aims to add some events on a couple of buttons in the barcode interface in Odoo V15.
When I'm trying to add an event on a button in the standard navbar at the top of the page (the navbar that allows, for example, to go back to the applications list) I can't locate the button with jQuery. I select the button through its class, but the returned object remains empty.I'm simply doing something like :
console.log($('.buttonClass'));
I guess that is because my script executes before the button generation.
I tried to place my script at the last position of the assets in the manifest, but it still not working.
How could I execute JavaScript code only when my page is fully loaded, so I can be sure that all of my elements exist?
Thank you,
Regards,
Try to use the DOMContentLoaded event for all your script.
More here: https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event
Example:
addEventListener('DOMContentLoaded', (event) => {
// your code
console.log($('.buttonClass'));
});
How about using $(document).ready()?
Example:
$(document).ready(function() {
console.log($('.buttonClass'));
});
See more about ready on jQuery API Documentation.
Related
I'm having trouble getting my JS to run after all my content has loaded. Right now on the site Im working on: http://hsvgridproject.com, the grid will not load the first time a user visit the site and needs a hard refresh before it will work. I believe I need to use a window.onload function of some sort but as I am still learning Java I'm not sure how to implement it into my project without breaking the code.
The script for the grid on homepage has a window tag surrounding it already (credit Codrops):
(function(window) {
Please let me know if you need more info. Thank you!
It's probably not working because you're executing your script before the DOM is fully loaded.
To ensure it's executed after the DOM is fully loaded, either move the script tag which executes your code right before the closing tag of the body element or use DOMContentLoaded event like this:
document.addEventListener("DOMContentLoaded", function(event) {
// execute your code
});
I am very new to HTML and the complete web world wrt development. I am trying to create a chrome extension and have decided upon showing the extension UI to the user by injecting a content script when the browser action is clicked. I have created an HTML page for the UI to be shown and now I need to load this HTML page as a small widget somewhere on the right top of the current page (to appear like a popup). From the different things looked up on the internet, I have decided to use shadow DOM but have no clue how to do all this. Can someone help me with a sample code to help me go ahead with this? I am not able to write a javascript that would be used as the content script to do the above mentioned job.
Edit 1: After some more reading, I found out out that we need to create the element hierarchy using javascript and cannot directly make use of any created HTML page. Is that correct? And if we have to make use of javascript, should make use of calls to document.createElement and add element? or document.write?
Just compiling reference from the responses I've got in this thread:
My Background.js:
function hello() {
chrome.tabs.executeScript(null, { file: "injectedScripts/jquery-2.1.3.min.js" }, function () {
chrome.tabs.executeScript(null, { file: "injectedScripts/a.js" });
});
}
// Supposed to Called when the user clicks on the browser action icon.
chrome.browserAction.onClicked.addListener(hello);
Injected Script a.js:
$.get(chrome.extension.getURL("popup.html"), function (data) {
//$(data).appendTo('body');
// Or if you're using jQuery 1.8+:
$($.parseHTML(data)).appendTo('body');
});
Also added popup.html and a.js paths to web_accessible_resources in manifest.json
For Chrome extension content scripts you'll only be able to inject JavaScript/CSS. You won't be able to have you're own HTML popup page like when using browserAction.
With JavaScript you'll need to dynamically create elements and insert them into the DOM. You're on the right track. You can use document.createElement or a library like jQuery to help with DOM manipulation as you get more familiar with web dev.
I am running the following jQuery that affects elements on a page view.
$(document).ready(function($){
$(".views-field-field-video").click(function() {
$(this).parent().find("a.cboxElement").click();
});
});
The code works perfectly, but only on the first page. When I use the pager at the bottom and navigate to any other page, the script does not work. Then, when I navigate back to the first page, the script also fails.
If I reload the page however, it brings me back to the first page and the script works again.
I am linking a .js file, and link in between the <head> </head> tags using <script type="text/javascript" src="http://source_to_file"></script> It is loading, I can see in the web developer tool.
EDIT:
The classes I am selecting in the script remains the same on all pages.
It sounds like you are only adding click events when the page is first loaded. If you are then dynamically adding HTML (with pagination) then you need to re-add the click events to those new objects.
Sounds like you just need to reatache the event. Drupal gives you a great way to do that right in your javascript:
Drupal.attachBehaviors('.behavior_class');
This will cause a lot of headache if you don't have context passed to your behaviors though.
Make sure your code is wrapped in, for drupal 6:
Drupal.behaviors.clikfocus_map = function (context) {
for drupal 7:
(function ($) {
Drupal.behaviors.ajax_example = {
attach:function (context) {
}
}
})(jQuery);
and your selectors should all have
$('.myselector', context');
Turns out I needed to just turn off AJAX on the view. Sorry to over complicate things, but thank you for all your help!
I created the following Greasemonkey script to be executed on Firefox for all websites. Here's the script. The script basically gets all the links on the page and alerts the number of links. This is a small part of a project I am working on.
window.addEventListener("load", function(e) {
var links = window.document.getElementsByTagName("a");
//window.setTimeout(function(){alert(links.length);},3000);
alert(links.length);
}, false);
The script executed fine for some websites, but when I accessed reddit, the script is returning only 2 links, instead of all the links that are present on the page. When I tried to search for divs present on the page, it also returned only 2.
When I researched the page source, there was something related to inline javascript. But I could not understand it perfectly. Can anyone please help me why this is not working?
Thanks,
Sid
It has to be AJAX content loads. If you execute your code from the debugger it works fine. So the only explanation is that the content isn't there after the load event. Try wrapping it in a timeout (ugly, but this should prove my point).
setTimeout(testLinks, 3000);
function testLinks() {
window.addEventListener("load", function(e) {
var links = window.document.getElementsByTagName("a");
//window.setTimeout(function(){alert(links.length);},3000);
alert(links.length);
}, false);
}
Now that you know what the problem is, you can follow the instructions in this SO question to create an AJAX event listener. Then you can recalculate your number of links whenever new content loads.
JavaScript detect an AJAX event
I'm using a JavaScript upload script that says to run the initialize function as soon as the DOM is ready. I currently have it working just fine with either a call to the function with body.onload or directly after the function is defined. The function builds some HTML in a placeholder div that acts as the file uploader tool.
My question is what is the best practice here? Since it works for now, why would the instructions say to run the init function as soon as the DOM is ready? Should I be adding a <script> tag directly after the placeholder DIV for example?
<script>
window.addEventListener("DOMContentLoaded", function() {
// do stuff
}, false);
</script>
You do that so you know all the parsed elements are available in the DOM etc.
The easiest solution is using jQuery and its $(document).ready(function() { .... }); function. Instead of .... you put your own code.
Note that it basically does the same thing #Shadow2531 suggested, but also works in old browsers not supporting that event.
The DOM is usually ready before onLoad runs. onLoad only runs after everything loads - external scripts, images, stylesheets, etc.
But the DOM, i.e. the HTML structure is ready before that. If you run the code at the bottom of the page (or after the parts of the page the script works with) that will work fine as well.
In 2015 you have two options with modern browsers:
document.onload
this fires when the document is loaded, but other resources (most notably images) have not necessarily finished loading.
window.onload
this fires when the document is loaded, AND all other resources (again, most notably images) are loaded.
Both of the above events would be better utilized with window.addEventListener() of course, as multiple listeners would be allowed.
You could also just move the <script> to the bottom of your page like this:
<html>
<body>
<main></main>
<script>
// code
</script>
</body>
</html>
As you probably know you should not run init functions before the DOM is fully loaded.
The reason you must run the init function as soon as the DOM is ready, is that once the page has loaded the user starts hitting buttons etc. You have to minimize the small inavoidable gap where the page is loaded and the init-functions haven't run yet. If this gap gets too big (ie. too long time) your user might experience inappropiate behaviour... (ie. your upload will not work).
Other users have provided fine examples of how to call the init function, so I will not repeat it here... ;)
Get jQuery and use the following code.
$(document).ready(function(){
// Do stuff
});
var Tette =
{
init: function()
{
/* Your HTML code */
}
};
Core.start(Tette);
You can try in this code, registering "Core.start(your object)" on the last line of the script. This is a way to load in safety your functions after the DOM loading.