I'm trying to do some dynamic resizing using javascript. For part of this I need to report the current size of a container. I wrote a function to do this (below) and it works great in chrome... however in firefox the width does not get reported. I have had a read on the offsetWidth method and in theory it should work in firefox.
function currentBoxW() {
return document.getElementById("wrapper").offsetWidth;
}
All this reports is "NaN".
There is more in that function in the actual page, but all the additional code has been commented out for testing... this is the actual line that does the reporting.
Have I missed something or is there a smarter way to report width using JS and the DOM? Is there another way to get the width of a div?
Thanks.
You can have two problems:
Make sure you have explicity set the width of the element (wrapper) through CSS
Make sure javascript code is executing after document is ready.
window.onload() or something similar if you are using any other javascript libaries
If you can use jquery instead
you can easily get it using
$(document).ready(function(){
function currentBoxW() {
return $('#wrapper').width();
or
return $('#wrapper').innerWidth(); //depending on the requirement.
}
});
Related
So I'm currently working on a WordPress website with a Table of Contents plugin. All the plugin do is just detect headings and add them to its contents.
What I am trying to achieve on my current website (https://staging.vladesplana.com/planning-center-vlad-test) is that when the Window is at <= 768px, it should simulate a "click" event on the [ Collapse ] anchor link so that the Contents will be hidden on mobile load and only be Expanded when on Desktop pixels (1280px, etc) load
function tocToggle2() {
if (window.innerWidth <= 768) {
document.getElementsByClassName('lwptoc_toggle_label').click();
}
}
window.onload = tocToggle2;
May I know your thoughts or the proper code for this? I mainly just build websites on Elementor and know only basic Javascript.
Tried a few things as well from my searches and on Stack to no avail.
I use Custom CSS & JS plugin to insert CSS and JS codes into my WordPress website so please, no JQueries
EDIT: Corrected some of the codes.
Oh I think I got it.
I just added [0] on this line:
document.getElementsByClassName('lwptoc_toggle_label')[0].click();
Source:
https://www.geeksforgeeks.org/click-method-not-working-and-console-returns-an-error-message-in-javascript/#:~:text=click%20is%20not%20a%20function,you%20have%20written%20a%20document.
Since it says there:
If you spelled it correctly then probably this error arises because you are not aware that document.getElementsByClassName returns an array of elements, not a single element. In order to avoid the error, you need to access a single element and then perform a click().
I checked in the console as well to check if the function is working as intended but it throws an error there.
final code:
function tocToggle2() {
if (window.innerWidth <= 768) {
document.getElementsByClassName('lwptoc_toggle_label')[0].click();
}
}
Instead of using getElementsByClassName, which will give you a list with every matching element, use querySelector, which will return the first one it finds.
The reason your code isn’t working is because you can’t trigger a click on a list of nodes.
Inserting dynamic SVG content into the DOM does not work as expected, having the SVG element onload attribute (containing JavaScript) regarding: "setInterval()".
As noted in the search tags of this question; this is plain (valilla) JavaScript (not jQuery); here's a breakdown of the issue:
I have some SVG code (plain text) that gets inserted into a <div> as innerHTML
the SVG element has an onload attribute with some JavaScript inside it
the JavaScript contains setInterval(...) - (which does not work at all)
I grab the SVG element from the temporary div and return it as the result of a function.
this result is appended into some element in the live DOM (body)
the strange issue:
any other code inside that onload attribute works fine,
only setInterval & setTimeout is completely ignored
More info:
During runtime (start-up), the SVG code is grabbed from an existing embed element .getSVGDocument() (after it has loaded) and prepared as plain HTML which can just be used as a template to create many others from the same source-code. I'm not using cloneNode(true) -because: the interval is for animation (continuous slow & smooth rotation) - which could have a heavy impact on client-side resources, hence, I thought it best to grab the code and keep it as template - then remove the original from the DOM.
With all the above in mind, everything works fine:
The (new) SVG shows up on screen, all nice and dandy-like
When I console.log the (inline) SVG code that is used, all looks perfect
I get no errors, and there is no error handler that mutes errors (window.onerror == null)
The JavaScript (text) inside the SVG node's onload attribute works for things like: console.log(this) - (which produces the SVG element in the log) - however, as mentioned: setInterval() & setTimeout() is just simply ignored - without any error and no warning.
The following code is a very short example, and (regrettably) it works; however, in my production app it doesn't.
The code:
var html = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" onload="setInterval(function(){ console.log(\'testing\'); },500);">';
var temp = document.createElement('div'); temp.innerHTML = html;
var node = temp.getElementsByTagName('svg')[0];
document.body.appendChild(node);
If you test the above code in a new js file, it works; however, for the life of me I can't find the reason why it breaks in my app; as explained, it's quite simple really.
The question:
Does anyone know if there is some "gotcha" I'm not aware of regarding this? Maybe name-spacing?
If the source-code is required, I can load it up on JSFiddle, or CodePen -if required, but, it's a lot of code, and many files, which may not be necessary for publication.
I'm sure it's just something small; like, how timers register according to scope, and maybe how it's affected in .bind() ?
I'm really stuck with this, and I kinda need it working for a good impression for a job-interview; so if you know anything that could help, I would appreciate your input very much.
Thank you.
embedded content, onload attributes & the DOM
The following may help in related scenarios:
when targeting an asynchronous source, make sure the contentDocument or getSVGDocument() contains the resources you need to access. The window.onload, or the DOMContentLoaded event is relative to the current DOM, so it may help constructing your own listener->trigger for a cross-browser solution, because the contents you need may not be ready in a synchronous fashion.
the onload attribute/event is not triggered when inserting dynamic content that is not asynchronously loaded, but may fire under certain circumstances, so, again, a custom:
listen->trigger will solve that.
question specific
The question is directly related to the 2nd point above, and the answer is quite simple really:
in the "onload" attribute of said SVG, set a simple value as property of this like:
<svg onload="this.ready = true; setTinterval(...)"
in the constructor function, after the element was dynamically created, simply check if the svg-node's onload event was fired like so:
if (!svgNode.ready){ svgNode.onload(); }
If there is an error in your code, but no error is shown, make sure window.onerror is either null -or if it's a function, make sure it does NOT return true - else it may suppress errors and you'll have a hard time tracking down what's wrong.
Please feel free to either improve this answer, or comment and I'll improve it accordingly; however, better answers will be appreciated.
6 years later...
With vanilla JavaScript Web Components you can do:
<load-svg></load-svg>
<script>
customElements.define("load-svg", class extends HTMLElement {
connectedCallback() {
this.innerHTML = `<svg></svg>`;
setInterval(() => {
console.log("testing");
}, 500);
}
});
</script>
I've been doing some web stuff with jQuery and css, and came across a problem, which I'm unable to find a solution to. I've written a code, where using jQuery, I get data from server and according to that data I add new elements. The elements have a lot of absolute positioning in them, and it messes up whenever I add them via jQuery.
My code is here:
function output(progress, data) {
$("#lookup .bar").css('width', (100/3*progress) + '%');
if (progress === 3) {
$("#lookup div.container").html(data);
$('#lookup').css("text-align", "left");
}
}
Basicly, I just remove the progress bar, and set my text-align to left, because of otherwise even more messed up aligning, this is the only workaround I found... The problem I'm having looks like this:
Although normally, it should look like this:
The strange thing is that the problem fixes itself whenever I refresh styling, for example with firebug, I would just delete some padding, then restore it, and the problem is gone... I feel that it has to do something with jQuery part. I'm pretty sure styling is fine, but if you need me to paste a code here, just ask, and I'll update the post.
UPDATE: Live preview on jsbin: http://jsbin.com/awomen/5/
I know the code is ugly ;)
I have an app built using jQuery (and using various jQuery-UI tools).
For some reason, i have to port it to smartphones/tablet computer, and decided to use jQuery Mobile for that (in order to minimize the number of changes).
In my vanilla app, I created some elements of the page on the fly, depending of user interactions.
For example a slider could be created like that (p is an object with a bunch of params):
function createSlider(p){
return $("<div/>",{
"id":p.id,
"class":p.divClass,
}).slider({
"orientation": p.align,
"min":p.constraint.min,
"max":p.constraint.max,
"step":p.step,
"value":p.curVal,
"animate":"normal"
/*and some event handling here, but it doesn't matter*/
});
}
And it will produce a nice looking slider. Now it looks like:
function createSlider(p){
return $("<range/>",{
"id":p.id,
"class":p.divClass,
"min":p.constraint.min,
"max":p.constraint.max,
"step":p.step,
"value":p.curVal,
});
}
But as it's created on the fly, all the stuff done by jQuery Mobile on the page load isn't done on it.
Is there a way to force that initialization without writing the slider in the html?
Thanks.
EDIT: I found in the doc that it could be achieved using container.trigger("create");
However this does not work yet.
EDIT2: Ok create was the solution.
According to the documentation (see edit in the question), using trigger("create") on the containing element works.
And to make that work, you also need to remember that range is an input type and not a tag...
Working solution:
function createSlider(){
return $("<input/>",{
"type":"range",
"id":"sl",
"min":0,
"max":15,
"step":1,
"value":1,
});
}
function appendSlider(){
$("#yourdiv").append(createSlider()).trigger("create");
}
As a sidenote, the documentation for jQuery mobile lacks a search option.
Try calling .page() on the container the content is being added to. Alternatively, adding .page() to the content you're returning may also work.
So, I have this pretty complex ajax thing going.
It loads new html (including div tags and all) to show up on the page.
I included a 'more' link to load additional data.
This more link links to my javascript function. The 'more' link is located in a div, which I gave a unique id. The next time the load function is called, I use document.getElementById(the id).style.display="none"; to "remove" this div from the look of the page.
I set error traps for this, the div with that id is found without problems, but javascript fails to change my style property.
I tested alert(document.getElementById(the id).innerHTML); and that worked without problems - hence the title of the question.
So, does anyone have any ideas/do I need to offer more information? The main problem is that it doesn't throw any errors anywhere, yet it fails to complete the task I asked...
Here's a bit of code to go with it -
try
{
var myidthing = "morelink" + ContentStart.toString(); //the id is correct
var div = document.getElementById(myidthing);
if (!div)
{
}
else
{
div.style.display="none"; //this doesn't work, but doesn't raise an error
alert(div.innerHTML); //this works without problem
}
}
catch(theerr)
{
alert(theerr);
}
------------------------->EDIT<-------------------------
I'm incredibly sorry if I upset any people.
I'm also angry at myself, for it was a stupid thing in my code. Basically, I had a variable that stored the contents of a parent div. Then I (succesfully) removed the div using the removeChild() method. Then my code pasted the contents of that vaiable (including the div I wanted gone) back into the parent div.
I switched around the order and it works fine now.
Again, excuse me for this.
Throwing out a few ideas of things to look for:
You said the div is generated by javascript. Is it possible the div you are targeting is not the one you think you are? It could be you are targeting another div, which is already hidden, or obstructed... or maybe the innerHTML you are displaying goes with a different element than the one you intend to target. Put an alert or script breakpoint in the if(!div) case, also, and see if it's going down that path.
If the above code is only a stripped-down version of your actual code, check your actual code for typos (for example: style.display = "none;";)
Using the FireBug plugin for FireFox, inspect the target element after the operation completes, and make sure that the display: none appears in the style information. If not, use FireBug's debugger to walk through your javascript, and see if you can figure out why.
Use FireBug to break on all script errors, in case there is another error causing this behavior.
Try empty quotes instead of 'none' and see if that works?:
document.getElementById('element_id').style.display="";
Failing that, don't change the style, just add a class which hides the element.