I have a function like :
function test(element_name){
$("#"+element_name).show();
}
Now, this $("#"+element_name).show(); is giving some security concern. So, is there a better way to select the element using the element_name passed. That can be used as an alternative.
An automated code review application is marking this as concern : "This may enable a DOM XSS attack."
Since the javascript (and the "hidden" content) is client-side, there's no security worth mentioning anyway. The client cannot be trusted.
If you need the string provided to the function to not be parsed, use document.getElementById instead:
function test(element_name){
$(document.getElementById(element_name)).show();
}
You can check if the element is a child of a certain object or you can add custom tags to the elements that should be able to .show() and check for them but I guess there is no other "secure way" to allocate an object via ID.
Related
I have some text that I wish to display, or not, based on a test. I have placed the text in a <span /id="..."> block, and have found examples that show referencing the id directly (if...then below) or by using the document.getElementById function (...else below).
Both seem to work in my test case. I gather that using the getElementById function is correct. Is it also correct to reference without calling that function, or is this just a case where it works in this browser now, but may break using a different browser or browser version?
Is there a better method do accomplish this?
<span id="myText">Some text to display or hide</span>
<script type="text/javascript">
function SetVisibility()
{
if (button.checked)
{
myText.style.visibility="visible";
}
else
{
document.getElementById("myText").style.visibility="hidden";
}
}
According to this answer, it is a bad idea to use inline HTML event attributes.
You can also add an event listener by using getElementById then adding addEventListener() to your button element like this:
document.getElementById("myButton").addEventListener("click", function() {
var myText = document.getElementById("myText");
myText.style.visibility = myText.style.visibility === "hidden" ? "visible" : "hidden";
})
<span id="myText">Some text to display or hide</span>
<button id="myButton">SetVisible</button>
It would be best to use eventListener() to set up event handlers.
As mentioned in the comments, the support for this seems pretty widespread -- it started in IE and seems to work across Chrome/Firefox/Safari as of my testing just now. However, using global variables is often considered an anti-pattern outside of exceptional cases where it makes sense -- native web APIs or situations where you need to be able to access something globally, for example. Otherwise you run the risk of overwriting or being overwritten by other code trying to compete for those names. In short -- in this case, it is almost always better to use getElementById, although it is good to be aware that this feature exists.
Whenever I want to find if an element exist in the DOM I use the following code.
if($('#target').length){
// do stuff.
}
This works well and I use it quite a lot on client sites.
Question:
How fast is this method? What are the speed implications when this is used a lot in a project?
You would be much better off using if(document.getElementById('target')) instead. JavaScript is always faster than jQuery (since jQuery is just a bunch of JavaScript hidden under the carpet)
EDIT: If you use it a lot, you can make a custom function:
function idExists(id) {return !!document.getElementById(id);}
Native JS is always faster than a query through jQuery. It just may not be as friendly.
After running a query through jsperf.com, native (querySelectorAll) is 57% faster than jQuery
However, if you use id, jQuery will be faster than querySelectorAll. In any case of id, use document.getElementById to test for an elements existence.
http://jsperf.com/jquery-obj-length
Try searching a DOM element with JQuery context say:
if an element u search say, an Input control, lies with in a table, pass table as your context:
A simple example:
$(function(){
var name= $('#Name','#mytab').val();
alert(name);
});
the jquery engine find the element 'Name' with in 'mytab' and not the entire form
follow this fiddle link : http://jsfiddle.net/NzbJr/10/
i have an element in html as shown below.
<tr><td class="HELPTEXT"><span lang="HLPMTXT1" id="HLPMTXT1"></span></td></tr>
i want to change the value of lang according to particular condition.
I tried as given below.but its not working.
<script>
document.getElementById("HLPMTXT1").lang ="HLPMTXT2"
</script>
Could anyone help me for changing the value of lang attribute of span?
You should use setAttribute(name, value) to do that, so your code would look like:
document.getElementById("HLPMTXT1").setAttribute("lang", "HLPMTXT2");
You can also use getAttribute(name) to retrieve the value using JavaScript.
https://developer.mozilla.org/en/DOM/element.setAttribute
https://developer.mozilla.org/en/DOM/element.getAttribute
Edit: It's also possible that your script is not working because you're trying to access the element before it exists in the DOM. Best way to insure that your element exists is by either: a) putting your script tag after the element, b) using the unload event to delay execution of your JS until everything is loaded, or c) use the DOMContentLoaded event. The latter, however, is a bit tricky to get to work cross-browser (without reusing somebody else's code that already addresses those problems) so you might want to read up on it first.
document.getElementById('HLPMTXT1').setAttribute('lang', 'HLPMTXT2');
Not all attributes can be accessed through the object properties
How can I find out which FORM an HTML element is contained within, using a simple/small bit of JavaScript? In the example below, if I have already got hold of the SPAN called 'message', how can I easily get to the FORM element?
<form name="whatever">
<div>
<span id="message"></span>
</div>
</form>
The SPAN might be nested within other tables or DIVs, but it seems too long-winded to iterate around .parentElement and work my way up the tree. Is there a simpler and shorter way?
If it wasn't a SPAN, but an INPUT element, would that be easier? Do they have a property which points back to the containing FORM? Google says no...
The form a form element belongs to can be accessed through element.form.
When the element you are using as reference is not a form element, you'd still have to iterate through the parentElement or use some other kind of selector.
Using prototype, you could simplify this by using Element.up():
$(element).up('form');
Other answers to this question have pointed out how to do the same in jQuery.
Why not just use:
var nodesForm = node.form;
?
It works on FF3, FF4, google chrome, Opera, IE9 (I tested myself)
Guess you have to iterate through all elements then.
You can try using jQuery:
$("input").parent("form")
http://docs.jquery.com/Traversing/parent#expr
Regarding Gumbo's Post:
As much as prototype and jQuery are useful, some people don't implement them into their projects.
Could someone please explain why Gumbo's solution was downgraded, other than the fact that he repeated what the OP was originally trying to avoid?
node = document.getElementById(this.id);
while (node.nodeName != "FORM" && node.parentNode) {
node = node.parentNode;
}
To answer the OP's question:
Traversing the DOM is the fastest way to achieve this effect - perceived speed is accomplished by 1) better written JS code, or 2) execution time (if you store the form on page load for that element, you'll still be traversing, but you'll have a quicker call to a stored variable when you need to retrieve that information).
There are no attributes nested in non-form elements that would associate it with the form (span.form does not exist).
If you are using a script (php/perl) to generate your page, and you're going to be making a lot of calls to the form, you could embed the form id in the HTML for that element. Still, a look up would need to occur.
I hope this helps,
vol7ron
You could backtrack in the DOM tree until you get to the right node:
node = document.getElementById("message");
while (node.nodeName != "FORM" && node.parentNode) {
node = node.parentNode;
}
Or a small jQuery (ignoring jQuery itself):
$("#message").parents("form:first")
Other than node.parentNode, I don't believe there is a way to find a specific ancestor of a given node. Most libraries usually do what you describe and iterate up through parentNode.
If you're not using a library like prototype, jquery or Ext, it would probably be a good idea. By now, they've resolved all the incompatibilities and quirks in the DOM to make most operations like this a trifle.
Can I add a custom JavaScript as some DOM node attribute to perform when it's ready like JavaScript added as "onClick" attribute performed when you click on it?
Suppose i need to process a div element with some funcMyTransform function.
I think it'll be more elegant to write smth like this
<div onReady=funcMyTransform(this)>...</div>
Instead of
<div id="MyElement">...</div>
<script type="text/javascript">
$(document).ready(function(){$("#MyElement").funcMyTransform()});
</script>
Is there such "onReady" attribute or something?
There is no onReady event. Depending on the functionality, you may want to abstract funcMyTransform out to a jQuery plugin. E.g.
jQuery.fn.funcMyTransform = function() {
alert(this.id);
};
jQuery(document).ready(function(){
jQuery("#MyElement").funcMyTransform(); // Alerts => "MyElement"
});
If you want access to the element as soon as its "ready", then placing your script at the bottom the document (before </body>) would probably be a better idea, and is definitely faster (albeit slightly) to initiate than jQuery's pseudo "ready" event.
As others have said, onWhatever attributes are "like so 1999" ;-). The general consensus among the modern Javascript community is that you should avoid using them as much as possible (for maintainability and other reasons).
That being said, there is a way to get something very similar to what you want in a much more maintainable fashion:
<div class="onReadyDoMyTransform">...</div>
<script type="text/javascript">
$(function(){$(".onReadyDoMyTransform").funcMyTransform()});
// $(someFunction) == $(document).ready(someFunction);
</script>
This approach will give you all the benefits of being able to decide what "transforms onReady" in your HTML layer, but without all the failings of an "onReady" attribute. The script part can just go in to a common JS include that you use throughout your site, so you don't have to worry about adding it along with every DIV.onReadyDoMyTransform.
Have you tried the jQuery ready?
$("#MyElement").ready(function(){$(this).funcMyTransform()});
I'm guessing this won't work but worth a shot?
Your suggestion that mixing code with the HTML as ... more elegant is arguable.
<div onReady=funcMyTransform(this)>...</div>
In general this is discouraged as it leads to maintenance problems. If I understood you correctly, on the onReady event being activated you want to call all these functions. One way to do it actually is to use a REL or anything else you might want to use as an expando attribute.
On document ready capture all the elements and read the attribute's value, then eval(). (People will tell you eval() is evil, but is quite harmless here).
$(document).ready(function(){
var v= $('.class_name').attr('rel');
eval(v);
})
It will actually eval() and activate all your javascript within your REL attributes.
I have used er (element-ready) by Stuart Colville before that is somewhat similar to what you are talking about, except for it's not an element attribute.
http://muffinresearch.co.uk/archives/2006/04/12/element-ready/
I have used this in an instance where I was returning some html via an XHR request and I wanted it to execute some javascript, but the dom had to be finished loading before I could execute it. Of course document ready didn't work, since the main document was already loaded.