Why a missing function parameter has a value of "[object Object]"? - javascript

I have a signup modal window, that should appear under two circumstances:
a) a button is clicked on the webpage;
b) the webpage has "#modal" in the URL (e.g. mydomain/mypage.html#modal) - in this case the webpage should load with the modal window above it.
Scenario A works as follows:
Html
<a href='#' class='button signup' data-target='.signup-modal'>Find out more</a>
JS + JQuery
$(function() {
$('.signup').on('click', showModal);
});
Scenario B:
JS
$(document).ready(function(){
var hash = window.location.hash;
if(hash === '#modal'){
showModal('.signup-modal');
}
});
The showModal function works as follows:
function showModal(modalType) {
var getTarget = $(this).data('target');
if (!getTarget) {
var target = modalType;
} else {
var target = getTarget;
}
$(target).show();
return false;
}
This works.
However, my previous attempt to this function was slightly different:
function showModal(modalType) {
if (!modalType) {
var target = $(this).data('target');
} else {
var target = modalType;
}
$(target).show();
return false;
}
This didn't work with Scenario A.
I thought, that if the function has no parameter specified, it will get modalType = undefined, and then var target = $(this).data('target');. I added alert(target) and found out, that after clicking on the button, I was getting [object Object] as the value of target.
Can anyone please explain why?

First argument of an event handler callback is the event object. So if (!modalType) will never be true.
You could check if it is a string for the selector version. Something like:
if ( typeof modalType !== 'string' )
Here's a simplified example:
function doStuff(thing){
if(!thing){
// won't get called in the two scenarios used
console.log('no thing');
return
}
if(typeof thing === 'string'){
console.log('Argument is string:', thing)
}else{
// thing is event object
const event = thing;
console.log('Event type:', event.type);
console.log('Target:', event.target)
// also `this` will be the element instance event occurred on
console.log('Tagname:', this.tagName);
}
}
$('button').on('click', doStuff);
doStuff('SomeString')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Click me</button>

Related

jquery mobile toPage select attribute doesn't work

i have a jquery mobile app with some pages. the first page is a login page and after the user logged in i dont want the user to go back to the login page again.
after the user logged in a div called #map will be shown.
to prevent this is have the following code:
$(document).on('pagecontainerbeforechange', function (e, ui) {
var activePage = $(':mobile-pagecontainer').pagecontainer('getActivePage');
if(activePage.attr('id') === 'map') {
var test = ui.toPage;
console.log(test.attr('id');
// if(test.attr('id') === 'login' && login.status === true) {
// console.log('you are alrady logged in');
// e.preventDefault();
// e.stopPropagation();
// }
}
});
When i click previous page to go to the login page again i get this error: Uncaught TypeError: test.attr is not a function
What is wrong and how can i select the attr id of test
Sometimes the ui.toPage is a string and sometimes it is a jQuery object representing the page. Sometimes the pagecontainerbeforechange runs twice, once with the string and once with the object. So try this:
$( document ).on( "pagecontainerbeforechange", function( e, ui ) {
var from = ui.prevPage ? ui.prevPage.prop("id") : '';
var to = '';
if (typeof ui.toPage === 'string') {
var u = $.mobile.path.parseUrl(ui.toPage);
to = u.hash || '#' + u.pathname.substring(1);
} else {
to = '#' + ui.toPage.prop("id");
}
if (from === 'map' && to === '#login') {
alert('Cannot change to login from map');
e.preventDefault();
// remove active class on button
// otherwise button would remain highlighted
$.mobile.activePage
.find('.ui-btn-active')
.removeClass('ui-btn-active');
}
});
DEMO
Also, .attr("id") will work, but in newer versions of jQuery it is more correct to use .prop("id"): http://api.jquery.com/prop/

jQuery - how to trigger a function whenever a element enabled?

I am looking to fix my function to work, whenever the element enabled. at present it's not working..
here is my try:
var x = function () {
input = $('#username');
if (input.prop('disabled')) {
console.log('i am enabled'); // how to trigger this?
}
}
x();
$('#enable').on('click', function(){
$('#username').removeAttr('disabled');
})
Live Demo
Note: my App always remove the attribute disabled
I have created a fiddle (modified your fiddle) Hope this is the solution you require
fiddle
Code Snippet:
if (typeof attr !== 'undefined' && attr !== false) {
console.log('i am disabled'); // how to trigger this?
}

JavaScript for handling Tab Key press

As we know, when we click on TAB key on keyboard, it allows us to navigate through all active href links present open webpage. Is it possible to read those urls by means of JavaScript?
example:
function checkTabPress(key_val) {
if (event.keyCode == 9) {
// Here read the active selected link.
}
}
You should be able to do this with the keyup event. To be specific, event.target should point at the selected element and event.target.href will give you the href-value of that element. See mdn for more information.
The following code is jQuery, but apart from the boilerplate code, the rest is the same in pure javascript. This is a keyup handler that is bound to every link tag.
$('a').on( 'keyup', function( e ) {
if( e.which == 9 ) {
console.log( e.target.href );
}
} );
jsFiddle: http://jsfiddle.net/4PqUF/
Having following html:
<!-- note that not all browsers focus on links when Tab is pressed -->
Link
<input type="text" placeholder="Some input" />
Another Link
<textarea>...</textarea>
You can get to active link with:
// event listener for keyup
function checkTabPress(e) {
"use strict";
// pick passed event or global event object if passed one is empty
e = e || event;
var activeElement;
if (e.keyCode == 9) {
// Here read the active selected link.
activeElement = document.activeElement;
// If HTML element is an anchor <a>
if (activeElement.tagName.toLowerCase() == 'a')
// get it's hyperlink
alert(activeElement.href);
}
}
var body = document.querySelector('body');
body.addEventListener('keyup', checkTabPress);
Here is working example.
Only one suggestion instead of 9 you can use KeyCodes.TAB.
Given this piece of HTML code:
<a href='https://facebook.com/'>Facebook</a>
<a href='https://google.ca/'>Google</a>
<input type='text' placeholder='an input box'>
We can use this JavaScript:
function checkTabPress(e) {
'use strict';
var ele = document.activeElement;
if (e.keyCode === 9 && ele.nodeName.toLowerCase() === 'a') {
console.log(ele.href);
}
}
document.addEventListener('keyup', function (e) {
checkTabPress(e);
}, false);
I have bound an event listener to the document element for the keyUp event, which triggers a function to check if the Tab key was pressed (or technically, released).
The function checks the currently focused element and whether the NodeName is a. If so, it enters the if block and, in my case, writes the value of the href property to the JavaScript console.
Here's a jsFiddle
try this
<body>
<div class="linkCollection">
<a tabindex=1 href="www.demo1.com">link</a>
<a tabindex=2 href="www.demo2.com">link</a>
<a tabindex=3 href="www.demo3.com">link</a>
<a tabindex=4 href="www.demo4.com">link</a>
<a tabindex=5 href="www.demo5.com">link</a>
<a tabindex=6 href="www.demo6.com">link</a>
<a tabindex=7 href="www.demo7.com">link</a>
<a tabindex=8 href="www.demo8.com">link</a>
<a tabindex=9 href="www.demo9.com">link</a>
<a tabindex=10 href="www.demo10.com">link</a>
</div>
</body>
<script>
$(document).ready(function(){
$(".linkCollection a").focus(function(){
var href=$(this).attr('href');
console.log(href);
// href variable holds the active selected link.
});
});
</script>
don't forgot to add jQuery library
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
Use TAB & TAB+SHIFT in a Specified container or element
Source
we will handle TAB & TAB+SHIFT key listeners first
$(document).ready(function() {
lastIndex = 0;
$(document).keydown(function(e) {
if (e.keyCode == 9) var thisTab = $(":focus").attr("tabindex");
if (e.keyCode == 9) {
if (e.shiftKey) {
//Focus previous input
if (thisTab == startIndex) {
$("." + tabLimitInID).find('[tabindex=' + lastIndex + ']').focus();
return false;
}
} else {
if (thisTab == lastIndex) {
$("." + tabLimitInID).find('[tabindex=' + startIndex + ']').focus();
return false;
}
}
}
});
var setTabindexLimit = function(x, fancyID) {
console.log(x);
startIndex = 1;
lastIndex = x;
tabLimitInID = fancyID;
$("." + tabLimitInID).find('[tabindex=' + startIndex + ']').focus();
}
/*Taking last tabindex=10 */
setTabindexLimit(10, "limitTablJolly");
});
In HTML define tabindex
<div class="limitTablJolly">
<a tabindex=1>link</a>
<a tabindex=2>link</a>
<a tabindex=3>link</a>
<a tabindex=4>link</a>
<a tabindex=5>link</a>
<a tabindex=6>link</a>
<a tabindex=7>link</a>
<a tabindex=8>link</a>
<a tabindex=9>link</a>
<a tabindex=10>link</a>
</div>
You should be able to do this with the keydown event. To be specific, event.target should point at the selected element and event.target.href will give you the href-value of that element. See mdn for more information.
The following code is jQuery, but apart from the boilerplate code, the rest is the same in pure javascript. This is a keydown handler that is bound to every link tag.
$('a').on( 'keydown ', function( e ) {
if( e.which == 9 ) {
console.log( e.target.href );
}});
event.keyCode has been deprecated.
Use event.key instead.
Here are the values you can use to assert against event.key:
https://www.w3.org/TR/uievents-key/#named-key-attribute-values
Use this JavaScript solution:
function keyPress(event) {
if (event.key === "Tab") {
// ...
}
}
You need to use Regular Expression
For Website URL it is
var urlPattern =
/(http|ftp|https)://[\w-]+(.[\w-]+)+([\w.,#?^=%&:/~+#-]*[\w#?^=%&/~+#-])?/
Use this Expression as in example
var regex = new RegExp(urlPattern ); var t = 'www.google.com';
var res = t.match(regex /g);
For You have to pass your web page as string to this javascript in variable t and get array

Capturing all the <a> click event

I am thinking of to add a javascript function to capture all the <a> click events inside a html page.
So I am adding a global function that governs all the <a> click events, but not adding onclick to each (neither using .onclick= nor attachEvent(onclick...) nor inline onclick=). I will leave each <a> as simple as <a href="someurl"> within the html without touching them.
I tried window.onclick = function (e) {...}
but that just captures all the clicks
How do I specify only the clicks on <a> and to extract the links inside <a> that is being clicked?
Restriction: I don't want to use any exra libraries like jQuery, just vanilla javascript.
Use event delegation:
document.addEventListener(`click`, e => {
const origin = e.target.closest(`a`);
if (origin) {
console.clear();
console.log(`You clicked ${origin.href}`);
}
});
<div>
some link
<div><div><i>some other (nested) link</i></div></div>
</div>
[edit 2020/08/20] Modernized
You can handle all click using window.onclick and then filter using event.target
Example as you asked:
<html>
<head>
<script type="text/javascript">
window.onclick = function(e) { alert(e.target);};
</script>
</head>
<body>
google
yahoo
facebook
</body>
</html>
​window.onclick = function (e) {
if (e.target.localName == 'a') {
console.log('a tag clicked!');
}
}​
The working demo.
your idea to delegate the event to the window and then check if the "event.target" is a link, is one way to go (better would be document.body). The trouble here is that it won't work if you click on a child node of your element. Think:
<b>I am bold</b>
the target would be the <b> element, not the link. This means checking for e.target won't work. So, you would have to crawl up all the dom tree to check if the clicked element is a descendant of a <a> element.
Another method that requires less computation on every click, but costs more to initialize would be to get all <a> tags and attach your event in a loop:
var links = Array.prototype.slice.call(
document.getElementsByTagName('a')
);
var count = links.length;
for(var i = 0; i < count; i++) {
links[i].addEventListener('click', function(e) {
//your code here
});
}
(PS: why do I convert the HTMLCollection to array? here's the answer.)
You need to take into account that a link can be nested with other elements and want to traverse the tree back to the 'a' element. This works for me:
window.onclick = function(e) {
var node = e.target;
while (node != undefined && node.localName != 'a') {
node = node.parentNode;
}
if (node != undefined) {
console.log(node.href);
/* Your link handler here */
return false; // stop handling the click
} else {
return true; // handle other clicks
}
}
See e.g. https://jsfiddle.net/hnmdijkema/nn5akf3b/6/
You can also try using this:
var forEach = Array.prototype.forEach;
var links = document.getElementsByTagName('a');
forEach.call(links, function (link) {
link.onclick = function () {
console.log('Clicked');
}
});
It works, I just tested!
Working Demo: http://jsfiddle.net/CR7Sz/
Somewhere in comments you mentioned you want to get the 'href' value you can do that with this:
var forEach = Array.prototype.forEach;
var links = document.getElementsByTagName('a');
forEach.call(links, function (link) {
link.onclick = function () {
console.log(link.href); //use link.href for the value
}
});
Demo: http://jsfiddle.net/CR7Sz/1/
Try jQuery and
$('a').click(function(event) { *your code here* });
In this function you can extract href value in this way:
$(this).attr('href')
Some accepted answers dont work with nested elements like:
<font><u>link</u></font>
There is a basic solution for most cases:
```
var links = document.getElementsByTagName('a');
for(var i in links)
{
links[i].onclick = function(e){
e.preventDefault();
var href = this.href;
// ... do what you need here.
}
}
If anybody is looking for the typed version (TypeScript, using Kooilnc's answer), here it is:
document.addEventListener("click", (e: Event) => {
if(!e.target) { return; }
if(!(e.target instanceof Element)) { return; }
const origin = e.target.closest("a");
if(!origin || !origin.href) { return; }
console.log(`You clicked ${origin.href}`);
});
I guess this simple code will work with jquery.
$("a").click(function(){
alert($(this).attr('href'));
});
Without JQuery:
window.onclick = function(e) {
if(e.target.localName=='a')
alert(e.target);
};
The above will produce the same result.
Very simple :
document.getElementById("YOUR_ID").onclick = function (e) {...}
The selector is what you want to select so lets say you have button called
Button1
The code to capure this is:
document.getElementById("button1").onclick = function (e) { alert('button1 clicked'); }
Hope that helps.

Custom "mouseenter" function doesn't fire

Here's the JSFiddle.
I'm trying to make mouseenter work on Chrome, Firefox, etc. using the following function:
var addMouseenter = (function () {
var contains = function (parent, elem) {
return parent.contains ? parent.contains(elem) :
!!(parent.compareDocumentPosition(elem) & 16);
},
wrap = function (elem, method) {
return function (e) {
if (elem === e.target && !contains(elem, e.relatedTarget)) {
method.call(elem, e);
}
};
};
return function (elem, listener) {
var listener2 = wrap(elem, listener);
elem.addEventListener('mouseover', listener2, false);
};
}());
Everything worked fine until I ran into this specific situation:
Element A has one of these custom mouseenter listeners
Element A contains Element B
Element B is right up against the edge of Element A
You enter Element A at that same edge
My expectation was that the mouseover event would be triggered on Element B and bubble up to Element A. However, that does not appear to be the case. I tested with Chrome 13 and Firefox 3.6 and got the same result. Did I mess something up?
If you don't oppose using jQuery:
$(document).ready(function() {
$('#first').mouseover(function (e) {
if ($(e.target).attr('id') != 'second') {
alert('hello');
}
});
});
Tried that in your JSFiddle and it works:
when you enter the green square it doesn't fire; when you enter red square from outside it fires; when you enter red square from green square it fires. That's what you wanted right?
new JSFiddle
Or keeping your javascript approach:
// Misc set-up stuff
var greet = function () { alert('Hi, my name is "' + this.id + '."'); },
first = document.getElementById('first'),
second = document.getElementById('second');
// The Actual Function
var addMouseenter = (function () {
var contains = function (parent, elem) {
return parent.contains ? parent.contains(elem) :
!!(parent.compareDocumentPosition(elem) & 16);
},
wrap = function (elem, method) {
return function (e) {
//if (elem === e.target && !contains(elem, e.relatedTarget)) {
if (elem === e.target && (e.target != second)) {
method.call(elem, e);
}
};
};
return function (elem, listener) {
var listener2 = wrap(elem, listener);
elem.addEventListener('mouseover', listener2, false);
};
}());
// GOGOGO
addMouseenter(first, greet);
http://jsfiddle.net/AUc88/
The reason my custom function wasn't firing is because it didn't work.
I updated the fiddle showing that all is as it should be.
My mistake was only checking to see if e.target was the same as the element I had attached the listener to. What I needed to be checking was if they were the same or if e.target was a child of the element.
When you mouse over the two squares really quickly, it only registers the mouseover event on the inner one, and because my listener was attached to the outer one, the elem === e.target test was failing.
So I changed the if code in the wrap function to this:
if ((elem === e.target || contains(elem, e.target)) &&
!contains(elem, e.relatedTarget)) {
e.stopPropagation();
method.call(elem, e);
}

Categories

Resources