Why jQuery selector works on Chrome but not on Safari? - javascript

I have the following code:
var l = $("input[name*=hello").length;
$('#result').text(l);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<input name="hello" type="text">
</div>
<div>
<input name="hello" type="text">
</div>
<div id="result">
</div>
Where the jQuery selector is:
input[name*=hello
Check that the selector is not correctly written input[name*=hello since a ] is missing.
On Chrome I get on the div[id=result] the amount of inputs that I have with the name "hello" (2).
But on Safari I get an error on the Console:
Which is correct, so the question is: Why did Chrome "autocorrect" the selector? Is it possible to remove that behaviour?

If the selector doesn't contain any jQuery extensions, jQuery will use the browser's built-in document.querySelectorAll() function. When the selector is invalid, the behavior is unspecified, so it may differ between browsers. Some browsers try to "fix" the selector and return something useful, while other browsers signal an error. You shouldn't depend on this -- write correct selectors.

Related

dynamic window.find not working with jQuery

I can't for the life of me figure out why this isn't working.
I want to search the current page for text using a search box. I googled and found this: http://www.javascripter.net/faq/searchin.htm . I implemented the code into my site, but it doesn't work. the function ( findString() ) works, but only when I hard-code a string (as in i can't use javascript or jquery to get the value of a text input). I made this fiddle: http://jsfiddle.net/alyda/CPJrh/4/ to illustrate the problem.
You can uncomment different lines to see what I've tested.
jQuery has a method :contains() that will make easier what you are looking for.
Take a look here: fiddle
$("button[type='submit']").click(function () {
var string = $('#search').val();
var matched = $('li:contains(' + string + ')');
matched.css('color','red');
console.log(matched);
return false;
});
I found a fix (sort of). It seems that the input needs to be placed well AFTER the content to be searched in the DOM. That means I've done the following:
<section class="content">
<h2>Fire</h2>
<h3>Fire Extinguishers</h3>
<ul>
<li>Model 240</li>
<li>Model C352, C352TS</li>
<li>Model C354, C354TS</li>
</ul>
...
<div id="navbar">
<ul>
...
</ul>
<input id="search" type="text" class="form-control pull-left" placeholder="Search for part number">
<button id="submit" type="submit" class="btn btn-default pull-left" style=" margin-top:6px;">Search</button>
</div>
as you can see, I've moved the input (which is in the navbar div) BELOW all of the text I want to search, and used CSS to programmatically place the navbar at the top of the page. I don't particularly like this setup (as it messes with the flow of content) but since I was looking for the quickest and simplest implementation of a single-page search, it will have to do.
I would still love to know why this happens, when the javascript is at the end of the DOM where it belongs...
In firefox I noticed that the fiddle (v4) as given in the question worked, but not in the way the asker expected it to.
What happens in firefox is that the function does find the value..: you have just entered it in the input-field. Then the browser's find method seems to hang in the 'context' of the input 'control' and doesn't break out of it. Since the browser will continue to search from the last active position, if you select anything after the input-field, the function works as expected. So the trick is not to get 'trapped' in the input-field at the start of your search.
A basic (dirty) example on how to break out of it (not necessarily the proper solution nor pure jquery, but might inspire a useful routine, since you now know the root of the problem in FF):
$( "button[type='submit']" ).click(function(){
var tst=$('#search').val(); //close over value
$('#search').val(''); //clear input
if(tst){ //sanity check
this.nextSibling.onclick=function(){findString( tst );}; //example how to proceed
findString( tst ); //find first value
} else { alert('please enter something to search for'); }
return false;
});
Example fiddle is tested (working) in FF.
PS: given your specific example using <li>, I do feel Sergio's answer would be a more appropriate solution, especially since that would never run line: alert ("Opera browsers not supported, sorry..."), but the proper answer to your window.find question is still an interesting one!
PS2: if you essentially are using (or replicating) the browser's search-function, why not educate the user and instruct them to hit Ctrl+F?
Hope this helps!
I had same problem in an angularjs app and I fix it by changing DOM structure.
my HTML code was something like this:
<body>
<div class="content" >
<input class="searchInput" />
<p>
content ....
</p>
</div>
</body>
and I changed it to something like this:
<body>
<div class="search">
<input class="searchInput" />
</div>
<div class="content">
<p>
content ....
</p>
</div>
</body>
Note: I'm aware that this topic is old.

Issues with jquery id selector

I have this snippet of HTML:
<div class="clearfix" id="menu-file-div">
<label id="menu-file-label" for="id_menu_file">From File</label>
<div class="input">
<div id="file-upload">
<input type="hidden" name="menu_file" id="id_menu_file" />
<script type="text/javascript">var field_id = "id_menu_file";</script>
<script type="text/javascript">var append_to_element_id = "menu-upload";</script>
<script type="text/javascript">var loader_element_id = "newmenu-modal";</script>
<noscript>
<p>Please enable JavaScipt to upload a file.</p>
</noscript>
</div>
</div>
</div>
In my console, when I try to use the jquery id selector, it fails to return the input element:
> $("#id_menu_file")
[]
Any thoughts on why this is so? I feel like I'm missing something simple. Thank you!
EDIT - some other javascript was removing the element, that is why it's not showing up. Thanks all for your help.
To repeat my first answer (which may be applicable to others reading this post later, and which was deleted despite the fact that it "fundamentally answer[ed] the question"):
Is this HTML inside of a frame (iframe or regular)? That could make it difficult for jQuery to find your element, unless you give it the right context.
To add a context to a jQuery selector you just provide that context as an extra argument, for example: $('TD', aFrameElement);
If the element in question is not inside a frame (which is the case for zallarak), the problem is almost certainly a timing issue: the jQuery selection is happening before the element has gotten loaded on the page. You can test this theory by adding the following code (anywhere):
$(function(){
console.log($("#id_menu_file"))
});
If that is the problem, simply wrap your code in $(function(){ to fix matters.
try :
$("#id_menu_file").get(0)
$(selector) return arrays

Jquery Selector not working in IE7

For the following HTML
<div id='parent'>
<input id='child' type=hidden value=''/>
</div>
I am doing
$('#parent #child').val('test')
OR
$('#parent > #child').val('test')
but none of the above is working in IE7. It does work in Firefox though
Any idea why is it not working ?
is it because you've got the HTML wrong? You should use " for attribute values. Sometimes IE is more sensitive to these things than Firefox
Your syntax seems correct. The only stuff I can think of that can muck this up are:
Make sure you've got your code between a $(document).ready() block
Maybe try .prop() instead of .attr() if you're using jQuery 1.6+
Try $('#child').val('test'); which would probably give the same result.

xml() function in jQuery

There is already the html() function in jQuery.
The problem I am having with this function is that, in its returned html string, all the self-closing / are stripped off from the elements. For example,
<div>
<input type="text" name="textbox1" value="" />
</div>
Becomes:
<div>
<input type="text" name="textbox1" value="">
</div>
I know this is normal for this function since this is valid in html.
But I would like to have a function that returns valid xml so that the / is still there in the returned string.
It seems jQuery itself does not provide such a function, so I wonder if anyone knows of any plugin that can make this possible.
Thanks in advance.
I think you are misconceiving how browsers interpret HTML. They don't keep a copy of your source file and modify it according to your Javascript. Rather, a browser reads your HTML and parses it into a DOM representation. This corrects any mistakes you may have made in your HTML. When you try to get the HTML of an element, the element is converted to a string according to the current DOCTYPE. Since you probably have an HTML doctype (it's quite hard to get a browser to genuinely treat your document as XHTML), you get HTML returned to you.
Doing this in Javascript is almost certainly not the way to go.
I think this is what I need.
Thank you very much for everyone's reply.
http://code.google.com/p/jquery-clean/
UPDATE 1: I thought this plugin would work but actually it does not. The way I use it is that, I pass it the html string returned by html() and let it fix the tags which do not properly self-close.
However, the way it corrects the tags is not what I need (seems like a bug).
For example, passing it the following html:
<div><input type="text" id="txt1" name="txt1"><label for="txt1">TextBox1</label></div>
It gives:
<div><input type="text" id="txt1" name="txt1"><label for="txt1">TextBox1</label></input></div>
Rather than:
<div><input type="text" id="txt1" name="txt1" /><label for="txt1">TextBox1</label></div>
UPDATE 2: The bug I mention above is already fixed. This plugin works now. If you want to test it out, feel free to paste your html in this page and see if it works for you:
http://www.antix.co.uk/Content/Demos/jQuery-htmlClean/Test.htm
You could try using the native .innerHTML property (you cen get the native element using .get() in jQuery).

forms.elements.length in ff

I have a form validation routine in JS which cycles through elements of a the first form on the page. I read the size of the elements array like this:
maxi=document.forms[0].elements.length;
This works fine in IE returning 23. In FF it always returns 0 and no validation at all is performed.
Any suggestions?
Thanks!
Move your javascript after the mark up or make sure that it runs after the document is loaded. Sounds like in FF the code is running before the form has been added to the DOM.
You might also consider using a javascript library, such as jQuery (I would recommend this), MooTools, Prototype, etc. to iron out a lot of the inevitable cross-browser issues you will have. Using jQuery, and the validation plugin, the validation code is very simple, using CSS classes to help with validation.
<script type="text/javascript" src="jquery.js" />
<script type="text/javascript">
$(function() { // run on document load
$('form').validate(); // use validation plugin to validate form
});
</script>
<form ...>
<input type="text" id="txt" name="txt" class="required" /> <!-- a required element -->
<input type="text" id="num" name="num" class="required number" /> <!-- a required, numeric element -->
...
</form>
You should try some interactive javascript console to test issues like this -
but, for this particular thing, you could use the "for ...in" form of for to iterate over the elements:
http://en.wikipedia.org/wiki/Foreach#JavaScript
Probably, however, it is the "elements" property which is non-standard there, so you will need to check the DOMs to get to a better way to retrieve the form widgets as objects.
And finally: beware of cleint side verification: it is often a burden to users and, if special care is not taken, it is to ease to have your forms stop working on a variety of browsers/platforms due to a verification which is mostly meaningless anyway (since you must verify the lenght of data entered server side in either case)

Categories

Resources