I want to change the first element with class .viewer's src attribute to the value of it's data-src attribute. The obvious code doesn't work:
$(".viewer").first().show().attr('src', $(this).attr('data-src'));
From reading other question on SO, I find you have to do this:
$(".viewer").first().show().each(function(){
$(this).attr('src', $(this).attr('data-src'));
});
It does work, and I do understand why (this doesn't refer to the element outside of the scope of the .each) - but it seems very weird to run .each() after you've already used .first().
Is there a cleaner way to write the above code?
Store data you want to reuse in a variable.
var viewer = $(".viewer").first().show();
viewer.attr('src', viewer.data('src'));
You can always just use a variable:
var elem = $(".viewer").first();
elem.show().attr('src', elem.attr('data-src'));
Related
I'm using PHPStorm and have the following js code
$('#id'.val($('#id'.attr('default'));
The idea is to reset the value of a input field to it's default which is set in default attribute of the input element.
Now the IDE is suggesting me to avoid duplicate selectors.
Though it is working I'm interested in finding out what is the best way to optimize this code line?
Not exactly what you asked for but more future proof using data and not an attribute. You could even store complex data or other information in there as well like "originalvalue" or "lastchangedvalue" etc.
Storing in an attribute is fine however I prefer to store things like this in the data of the element like:
<myelementtag id="myid" data-defaultvalue="defaultvalue" />
You then access it like:
$('#myid').data("defaultvalue");
For example:
var myElement = $('#myid');
myElement.value = myElement.data('defaultvalue');
Want to reset the default?
var mynewdefault = "mynewvalue";
myElement.data('defaultvalue', mynewdefault);
Since you asked only one selector and one line code, please use like this as stated in jQuery documentation (middle section):
$("#id").val(function(index,value) {
return $(this).attr('default');
});
or if you want to avoid $(this):
$("#id").val(function (index, value) {
return this.getAttribute('default');
});
JSFiddle
And yes, as other members have pointed out, it would be better if you use data attribute (data-defaultValue) instead.
This is a more compact solution:
var id = $('#id');
id.val(id.attr('default'));
You really don't need to use $(...) every time.
Store your jQuery element in a variable:
var $id = $('#id');
$id.val($id.attr('default'));
jQuery currently uses window as its default element so any call like $('div') will look for div tags inside window.
Is there any way to change defaults on jQuery like:
$.defaultRoot = $('.anyOtherRootElement');
$('div').text("Hello");
this will select any div inside the elements containing .anyOtherRootElement class.
Thanks in advance
Upate
just an update refining the question a bit more here:
I would like to perform the actions above based on external queries coming from external script which won't know what defaultRoot is so they can still be calling what is supposed to be the current base, so in this instance, I'm afraid adding the a second parameter wouldn't be an option, unfortunately.
And at the same time creating a function which returns defaultRoot.find(el) would prevent me of using first-level methods such $.trim, $.each, etc… so unfortunately that would not be possible as well.
Ideally (for performance reasons) you'd want to use find()
$.defaultRoot.find("div");
Otherwise you can use the 2 argument form that sets a context
$("div", $.defaultRoot);
In general you don't want to do these types of things implicitly since someone else could easily end up thoroughly confused when having to work with your code later. If you want to do it consistently and make it shorter you should create your own function to do so like:
var $s = function(selector) {
return $.defaultRoot.find(selector);
}
and then you'd just be able to use
$s("div")
or you could also do a scoped higher order function with something like
var withScope = function(scope$) {
return function(selector) {
return scope$.find(selector);
}
}
var $s = withScope($.defaultRoot);
$s("div")
If for some reason you really want to screw around with the default state for client code (begging for chaos IMO), you should look at the functional practice: currying.
$('SELECTOR', 'CONTEXT')
You can use context. As in your case $('div', '.anyOtherRootElement')
For more details, visit http://api.jquery.com/jQuery/
Given that you can pass the context as a second argument, you can easily overwrite the $() operator in Javascript with a version which internally calls JQuery using jQuery.noConflict(); and always passes your new root as the second argument.
I don't think jQuery provide such method or variable. But you can pass second parameter in jQuery method to set context.
$.defaultRoot = $('.anyOtherRootElement');
$('div', $.defaultRoot ).text("Hello"); // all div inside $('.anyOtherRootElement')
$('div' ).text("Hello"); //all div inside body tag
In JS, I am creating a link where the href attribute runs a function. The function simple opens an alert window with a given variable.
function alerter(str){
alert(str);
}
When I create the link, I use the following code.
var link = document.createElement('a');
link.setAttribute('href','javascript:alerter("hi")');
link.innerHTML = "Sauce";
If I do that, it works. However, what I want to do is alert a previously defined variable. But when i use
link.setAttribute('href','javascript:alerter(myvar)');
the popup no longer works. Also, is there a way to simply embed the alert in the href instead of writing a separate function?
It should be
link.setAttribute('href','javascript:alerter("' + myvar + '")');
You're using string concatenation to put myvar into that string. The way you had it, the whole thing is a string "javascript:alerter(myvar)"
Try this
link.setAttribute('href','javascript:alerter('+myvar+')');
The myvar variable has to be in the global scope. Be sure you can also access it as window.myvar.
for your first question use :
link.setAttribute('href','javascript:alerter(' + somevar + ')');
and for your second question use:
link.setAttribute('href','javascript:alert(' + somevar + ')');
cheers.
http://jsfiddle.net/xmBbw/2/
Just modify the onclick event of your anchor. If you are not going to link anywhere, you need not use the href attribute. Rather use onclick and assign any function you like to it. Besides, it's awfully bad practice to write javascript inside an html tag. Please don't.
A nice article regarding good practices
Supposing I have the correct location of an element whats the best way to replace all the html including the tags of a given block of HTML code using jQuery()? I'm looking to do something similar to the following. Is this a good way to do this? What other ways are available or useful to know about?
var location = 'td[id^="A0.R0.Work"]';
var element = jQuery(location).prev();
element.html('<h1>some code</h1>');
Thanks.
Try .replaceWith()
$(element).replaceWith(other_stuff);
The code you provide will try to assign the HTML to whatever jQuery's html function returns. Instead, pass your html as the argument to the html function:
var location = 'td[id^="A0.R0.Work"]';
var element = jQuery(location).prev();
element.html('<h1>some code</h1>');
JQUERY is sometimes too much overhead.
var location = document.getElementById('A0.R0.Work');
location.innerHTML = '<h1>some code</h1>';
Does anyone know an easy way to use jQuery (or other Javascript if necessary) to extract only the Javascript portion of an anchor tag's href attribute (like the one below), so it can be assigned to another event at runtime?
<a id="FancyLink" href="javascript:DoSomething('Input1')">Do</a>
I know how to get the anchor's whole attribute value using jQuery, and I suppose I could just do that and then chop off the "javascript:" prefix manually, but I'm wondering if there is a better way to obtain a JavaScript function object from the above example.
Thanks for the help!
Brian
Like this:
var code = $('#FancyLink').attr('href').replace(/^javascript:\s*/, '');
This will return a stringm which you'll need to eval in order to execute.
For better performance, you can call eval once and create a function, like this:
var executor = eval('[ function() { ' + code + ' } ]')[0];
The array is necessary because IE cannot directly return a function from eval.
For even better performance, don't do this at all.
Assuming you can't refactor the <a href="javascript:..."> code, which is the problem here, you could also assign the href to location, which is roughly what happens when user clicks the link anyway. That would save you chopping off the 'javascript:' portion and would be a bit more natural.