JavaScript: AreaText split per line error - javascript

What is the problem with this code?
var lines = document.getElementById('id="summoners"').val().split('\n');
//I get error above "Cannot call method val of null
for(var i = 0;i < lines.length;i++)
{
//other code using lines[i] not necessary to show it
}

document.getElementById('summoners') is the syntax you'd want to access the element and is why you're getting the null reference exception.
.val() is a jQuery-like method, though, and will fail on a raw HTML element. You'd need to use something like document.getElementById('summoners').value, assuming it's a textarea element, or use jQuery and do $('#summoners').val().

Your getElementById is malformed. You need not specify the "id" key in the method argument. Go with:
document.getElementById('summoners').val().split('\n');

Related

How to use indexOf() method on parameter?

I am using dragula.js, and using ondrop event in mycode,
drake.on('drop', function (el) {
console.log(el); //result <div>foo bar</div>
var n = typeof(el); //return object
var x = el.indexOf("test"); //error TypeError: el.indexOf is not a function(…)
// do another code
})
I want to check if "test" exist on el parameter, but error occur. thx.
I think it should be as easy as if ('test' in el)
Use the dom. Roughly: el.parentElement.children.indexOf(el)
Solved - https://github.com/bevacqua/dragula/issues/209
indexOf works on strings, so you need to call it using the element's text, rather than the element itself, like so:
el.textContent.indexOf("test");
Edit:
Looks like you want the index of the dragged element rather than matching its text:
[].slice.call(el.parentElement.children).indexOf(el)

Yet Another Uncaught TypeError: : Cannot read property 'replace' of undefined

I am writing a bit of JS code to switch classes for certain DOM elements.
Everything is working as it should, but I am also getting this error and this
prevents the code that follows to be executed.
I added a check to make sure that the array of elements is not empty as I thought
this was the problem. But still the error occurs. Debugging always showed a value for old_name when replace is called on it. Am I missing something JS-esque?
This is the part of the code that causes the error, specifically line 31:
if (w > MOBILE_THRESHOLD) {
responsive_elements = document.getElementsByClassName("desktop");
if (responsive_elements.length > 0) {
for (i in responsive_elements) {
var old_name = responsive_elements[i].className;
var new_name = old_name.replace("desktop", "mobile");
responsive_elements[i].className = new_name;
}
}
When necessary I will be happy to provide more code, or whatever information is needed. Thanks!
Never use for...in loops to iterate array-like objects!!!!!
In this case, the HTMLCollection has enumerable properties like item or namedItem. Accessing these won't return an HTML element, so className will be undefined.
To iterate properly, you can use one of these
for(var i=0; i<responsive_elements.length; ++i) {
// ...
}
[].forEach.call(responsive_elements, function(element, index, collection) {
// ...
});

document.getElementsByTagName:Cannot read property 'style' of undefined

I wanna make a varible shortcut $$() so that i can use shortcut like $() [jquery] to save code in my project(ALL MY CODE IS PURE JAVASCRIPT).
when i put the string of id or class, it works all right, but when i put the tagName, it shows Cannot read property 'style' of undefined, it seems that the code is right,help,thanks
One more, is that way to defined a shortcut variable $$() to use in pure javascript environment right way? or is there any best practice to define a global variable like this?
window.onload = function(){
function $$(ele){
var pattern1 = /#/g;
var pattern2 = /\./g;
var pattern3 = /!/g;
var matches = ele.match(/[^#\.!]/g);//array
var elementS = matches.join("");
//alert(matches+elementS);
// console.log(document.getElementsByTagName(elementS));
var spaceExist = /\s/.test(elementS)
if(pattern1.test(ele)){
return document.getElementById(elementS);
}else if(pattern2.test(ele)){
//console.log(elementS);
return document.getElementsByClassName(elementS);
}else if(pattern3.test(ele)){
alert('hi');
console.log(elementS);
return document.getElementsByTagName(elementS);
}else if(spaceExist){
return document.querySelectorAll(elementS);
}
}
$$('#hme').style.backgroundColor = 'red';
$$('.myp')[0].style.backgroundColor = 'green';
$$('!h2')[0].style.display = 'none';//this not work,shows Cannot read property 'setAttribute' of undefined
}
<h1 id="hme">hi,friend</h1>
<p class="myp">mmdfdfd</p>
<h2>hhhhhh</h2>
Have you stepped through your code? Look at pattern #2:
var pattern2 = /./g;
That pattern will match any character at all given that's what the period represents in regular expressions - ref: http://www.regular-expressions.info/dot.html.
Therefore, this conditional is satisfied and returns its result:
else if(pattern2.test(ele)){
return document.getElementsByClassName(elementS);
}
Given there appears to be no element with a class name of h2 (which is the value of elementS), the return value is undefined.
Given that undefined has no properties, interrogating for the style property will produce the error you are seeing.
My advise is use one shortcut since you already using querySelectorAll:
window.$ = document.querySelectorAll.bind(document)
or if you rather need first element
window.$ = document.querySelector.bind(document)
this way you'll be able to do everything you are doing with normal css selectors and not obfuscated !tag for just tag
If speed actually matters, you will save some ticks by just having two aliases:
window.$ = document.querySelector.bind(document)
window.$el = document.getElementById.bind(document)
and calling $el when you need it specifically, instead of trying to make method polymorph.
Mister Epic's answer spots the main issue. Your h2 call is getting caught in that if statement, and that's why your error is happening. You need to make sure it doesn't get caught there, either by creating another pattern, or specifying in your second if statement that your 'ele' doesn't contain an '!'.
After that, in your third if statement:
else if(pattern3.test(ele)){
alert(hi); <---
console.log(elementS);
return document.getElementsByTagName(elementS);
The problem with this is you're going to alert(hi), but hi isn't defined. Make sure you wrap it in quotes.
Should be looking good after that.

Javascript Getting specific element (of parent) by name

I'm using custom tags to define sections in an application, so I have something like this:
<mysection>
<form>
<input name="myfield">
</form>
</mysection>
I'm using the following and able to get the tag (printed to console, everything is groovy)
var parent = document.getElementsByTagName('mysection');
The issue I'm having is finding the child field by name:
var myfield = parent.getElementsByName("myfield");
...as I don't want to pick up on any other 'sections' that might have an input with the name 'myfield'.
EDIT:
var parent = document.getElementsByTagName('mysection')[0];
was suggested and returns to console the section contents, however, getElementsByName throws an error:
Uncaught TypeError: Object #<NodeList> has no method 'getElementsByName'
Using getElementsByTagName() and getElementsByName() will return a NodeList, you need to get the first element of the list like this:
var parent = document.getElementsByTagName('mysection')[0];
var myfield = parent.getElementsByName("myfield")[0];
Edit
You were correct, getElementsByName is not valid for an element. I am unsure how to localize the functionality of it as you are trying to do. It seems that it will only work for document. You may have to write your own implementation of getElementsByName if you want to use it in a localized scope.
Second Edit
To be nice, I made that implementation for you :D Here it is in all its "glory".
Element.prototype.getElementsByName = function (arg) {
var returnList = [];
(function BuildReturn(startPoint) {
for (var child in startPoint) {
if (startPoint[child].nodeType != 1) continue; //not an element
if (startPoint[child].getAttribute("name") == arg) returnList.push(startPoint[child]);
if (startPoint[child].childNodes.length > 0) {
BuildReturn(startPoint[child].childNodes);
}
}
})(this.childNodes);
return returnList;
};
var parent = document.getElementsByTagName('mysection')[0];
var myfield = parent.getElementsByName("myfield")[0];
Small fix
I was incorrectly passing the element and not its children into the recursion. The code above has been edited with the proper argument passed now. See working fiddle: http://jsfiddle.net/js6NP/5/
I actually found a much more simple way to handle this:
document.querySelectorAll('mysection [name="myfield"]');
Here you can see an example where it only modifies the field inside the section specified: http://jsfiddle.net/fluidbyte/kph6H/
qSA supports modern browsers and is compatible down to IE8, Here's a polyfill to support back to IE7: https://gist.github.com/2724353
getElementsByName won't work on a DOM element reference. Use querySelector or querySelectorAll instead. In example:
var parent = document.getElementsByTagName('mysection')[0];
var myfield = parent.querySelector("[name='myfield']");
Just use an ID instead:
<mysection>
<form>
<input name="myfield" id="fieldName">
</form>
</mysection>
var myfield = document.getElementById("fieldName");
ID's are supposed to be unique on a page. So you shouldn't have trouble accessing the right element.
If you really have to use name/tagname, getElementsByTagName and getElementsByName both always return a array (A empty one if no element was found). you can access the right element, just like you'd access elements in arrays:
document.getElementsByTagName('mysection')[0]; For the first element with tagname mysection.

Viewing an object

I am learning JS and after fiddling around with adding elements etc I tried to do an alert() with the object but instead got this error: [object htmltableelement]
so I then tried:
alert(t.toString());
and got the same error... how can I see the contents of the object?
you can use firebug:
console.log(t);
or you can use innerHTML;
alert(t.innerHTML);
The way I normally do this is by using FireBug firefox add-on.
Add a break point in your JavaScript then you can view any object and all its keys/values.
See everything:
for(var key in t)
alert('key:' + key + ', value: ' + t[key]);
You may want to replace alert with console to avoid 100s of alerts
function domObjectToString(domObject){
if(typeof(domObject) ==='object'){
var divElement = document.createElement('div') ;
divElement.appendChild(domObject);
return divElement.innerHTML;
}else{
return domObject.toString();
}
}
---- steps follow -----
1. check the domObject Type [object]
2. If Object than
a. Create an "Div" element
b. append DomObject To It
c. get The innerHTML of the "div" it Gives The String
3. If Not an Object than convert to String and return it .
That is not an error. That is the default string representation of an object.
Either iterate through the object's properties and output them one by one, or use a proper debugging tool like Firebug that'll give you the ability to really examine your variables.

Categories