Two function in onMouseOver React.js - javascript

render: function() {
return (
<td>
<img src={this.props.image.path} width="40" height="40" id={this.props.image.id}
onMouseOver={()=>document.getElementById(this.props.image.id).height="80", ()=>document.getElementById(this.props.image.id).width="80"}
onMouseOut={()=>document.getElementById(this.props.image.id).height="40", ()=>document.getElementById(this.props.image.id).width="40"}/>
</td>
);
}
I want to change image size when onMouseOver but it only width changed.
How can I use two function in onMouseOver. Thank you.

use it like this:
onMouseOver={() => {
document.getElementById(this.props.image.id).height = "80";
document.getElementById(this.props.image.id).width = "80";
}
}
But better to use function
onMouseOver={this.someFunction}
someFunction = () => {
document.getElementById(this.props.image.id).height = "80";
document.getElementById(this.props.image.id).width = "80";
}

Easy one. You can define a new function to call them at once.
function changeWidthAndHeight() {
document.getElementById(this.props.image.id).height="80"
document.getElementById(this.props.image.id).width="80"
}
Then, replace the content of onMouseOver with it.
onMouseOver={changeWidthAndHeight}

Merge them into 1 function
onMouseOver={()=> {
let obj = document.getElementById(this.props.image.id);
obj.height="80";
obj.width="80";
}}
Or you can make those style a variable then update that using onMouseOver.

Related

How to alert when element in a list is clicked?

function whatami(img){
console.log(img.key);
}
let animals = ["frog","frog","sheep","sheep","snail","snail","mouse","mouse","bat","bat","walrus",
"walrus","giraffe","giraffe","zebra","zebra","dog","dog","octopus","octopus","hippo",
"hippo","camel","camel","pig","pig","rhino","rhino","rooster","rooster","panda","panda",
"turtle","turtle","raccoon","raccoon","polar bear","polar bear","lion","lion","bison",
"bison","orca","orca","snake","snake","shark","shark","toucan","toucan","butterfly",
"butterfly","anteater","anteater","seal","seal","armadillo","armadillo","rooster","rooster"]
var array = shuffle(animals);
let images = array.map(image => {
return <img onClick = {whatami(image)} key={image} src={"/animalgameback.jpg"} alt="" className="img-responsive"/>
});
return (
<div>
<div>
{images}
</div>
</div>
)
}
}
I have this list of images and I need a way to find which one is clicked when I press one of them. How do I do this?
The click must receive a callback function. Try writing the onClick with a arrow function like this
onClick = { () => { whatami(image)} }
I would write ()=>{whatami(image)} instead of whatami(image). LEt me know if it works.

Mixin functions only work in render()

For some reason, it appears that mixin functions in my code only work properly in render() function. It could be that I'm not calling them in the right manner outside of the render(), but shouldn't it be exactly the same way?
This way everything works fine (but I can't stick with this since I have to add some extra stuff to click handling, at the same time not altering the mixin):
var Row = React.createClass({
mixins: [someMixin]
},
render: function () {
var clickHandler = null;
var btn = null;
if (firstCase) {
clickHandler = this.order(this.props.name, this.props.else);
btn = (<a href="" onClick={clickHandler}>Order</a>);
} else if (secondCase) {
clickHandler = this.noOrder(this.props.name, this.props.else);
btn = (<a href="" onClick={clickHandler}>No order</a>);
}
return (
<div>
{btn}
</div>
);
}
});
But when I do the obvious and include the mixin functions in another function to handle the click - like this - everything fails and even 'test' is not printed in the console:
var Row = React.createClass({
mixins: [someMixin]
},
handleOrderClick(type) {
console.log('test');
if (type == 'order') {
this.order(this.props.name, this.props.else);
} else if (type == 'no-order') {
this.noOrder(this.props.name, this.props.else);
}
},
render: function () {
var clickHandler = null;
var btn = null;
if (firstCase) {
clickHandler = this.handleOrderClick('order');
btn = (<a href="" onClick={clickHandler}>Order</a>);
} else if (secondCase) {
clickHandler = this.handleOrderClick('no-order');
btn = (<a href="" onClick={clickHandler}>No order</a>);
}
return (
<div>
{btn}
</div>
);
}
});
EDIT:
order and noOrder functions look like this:
order: function (name, else) {
return function (event) {
event.preventDefault();
var term = name + '&&¤%' + else;
Order.order(name, else, period, function (data) {
if (term === (global || window).MAIN_NAME + '.' + (global || window).MAIN) {
$(window).trigger('Name:update');
}
}.bind(this));
}.bind(this);
},
noOrder: function (name, else) {
return function (event) {
event.preventDefault();
if (!this.state.transferModalOpen) {
this.toggleTransferModal();
}
}.bind(this);
}
In order to use this.setState in handleOrderClick you'll have to use the bind method in your render method. Therefore handleOrderClick will become:
handleOrderClick(type, event) {
this.setState({foo: 'bar'});
if (type == 'order') {
this.order(this.props.name, this.props.else)(event);
} else if (type == 'no-order') {
this.noOrder(this.props.name, this.props.else)(event);
}
},
and your render method becomes:
render: function () {
var clickHandler = null;
var btn = null;
if (firstCase) {
clickHandler = this.handleOrderClick.bind(this, 'order');
btn = (<a href="" onClick={clickHandler}>Order</a>);
} else if (secondCase) {
clickHandler = this.handleOrderClick(this, 'no-order');
btn = (<a href="" onClick={clickHandler}>No order</a>);
}
return (
<div>
{btn}
</div>
);
}
You'll notice that the functions that are returned by this.order and this.noOrder are no longer returned by handleOrderClick, but are instead executed immediately. This should provide the effect you desire.
I've put the code in your example into a jsfiddle and it now seems to be working correctly. I've had to change the prop 'else' to 'alt' because 'else' is a reserved word. I've also just applied the mixin to the class directly for simplicity. I have simpilfied the order and noOrder functions as I don't have access to the Order object and we are only interested in them firing at the correct time. I've also added a second button that you can click to flip the cases so the other button is rendered, causing the component to render again. I've added a label that will display which function had been called when the button was last pressed.
for reference, you can find more information about the bind method here.
Hope this helps ^_^

Can I add onmouseover attribute to run only once?

Say I have a link like the following:
<a class="link" href="www.rich.com" onmouseover="go(this)">Link</a>
Is there a way to configure the onmouseover event, calling go(this) to run only a single time while still using the inline onmouseover=<some code> notation? I want it defined inline, not with a JavaScript call.
Currently, I have this, but it is not what I want:
$(".link").one('mouseover', function(e) {
// do something
});
You can nullify the onmouseover binding afterwards:
<a class="link" href="www.rich.com" onmouseover="go(this); this.onmouseover = null;">Link</a>
Using Vanilla JS:
const link = document.querySelector('.link');
link.addEventListener('mouseover',
() = window.open('your url'),
{ once : true }
);
ref: How can I add an event for a one time click to a function?
You could set a var that indicates whether it has been triggered or not...
var triggered = false;
$(".link").one('mouseover', function(e) {
// do something
if(!triggered)
{
triggered = true;
// and whatever else you want to do
}
});
Alternatively you can do something like this :
var check = 0;
$(".link").on('mouseover', function(e) {
if(check == 0 ){
// do something
check = 1;
}else {
return false;
}
});

repeating jquery function many times

I need to improve my jquery code where I repeat my function 6 times!!!
is there away to do a loop to shorten the code ?
(function( jQuery ){
jQuery.fn.vesta = function(imgN){
var imgPath = "http://localhost:8080/mhost/media/magentohost/vesta/vesta"
var currImg = imgPath + imgN + ".png";
var targetImg = jQuery('.img-browser img');
jQuery('.img-browser img').attr('src', currImg);
}
})( jQuery );
jQuery('.vesta1').on('click', function (e) {
jQuery('.vesta1').vesta(1);
});
jQuery('.vesta2').on('click', function (e) {
jQuery('.vesta2').vesta(2);
});
jQuery('.vesta3').on('click', function (e) {
jQuery('.vesta3').vesta(3);
});
jQuery('.vesta4').on('click', function (e) {
jQuery('.vesta4').vesta(4);
});
jQuery('.vesta5').on('click', function (e) {
jQuery('.vesta5').vesta(5);
});
jQuery('.vesta6').on('click', function (e) {
jQuery('.vesta6').vesta(6);
});
You can DRY this up by using a common class, and a data attribute to specify the parameter to send to your vesta function:
<div class="vesta" data-vesta="1">1</div>
<div class="vesta" data-vesta="2">2</div>
<div class="vesta" data-vesta="3">2</div>
Then there is no need to loop at all:
$('.vesta').on('click', function (e) {
$(this).vesta($(this).data('vesta'));
});
Use a common class and a data attribute
jQuery('.vesta').on('click', function (e) {
var elem = $(this);
elem.vesta(elem.data("ind"));
});
and the HTML
<div class="vesta vesta1" data-ind="1">
Just put it into a for loop, and take advantage of the dynamic nature of JavaScript:
for (var i = 1; i <= 6; i++) {
$('.vesta' + i).on('click', (function (index) {
return function (e) {
$('.vesta' + index).vesta(index);
};
})(i));
}
I suppose you need the this reference along with some hack kind of thing
$('[class*=vespa]').on('click', function(e){
$(this).vesta(+(this.className.match(/vespa(\d+)/)[1]))
});
Here, we capture elements which have a class that matches at least vespa and then we use some bit of regex to match the digits after vespa and + unary operator changes the String version of numbers into actual numbers.
It would be quite easy if you can alter the structure of the HTML.
You would give all elements the same class, say vesta. But you also give them an attribute, say data-number. For example, like this:
<div class="vesta" data-number="4"></div>
Then, your jQuery code would be as simple as:
$(document).on({
click: function() {
var $this = $(this),
number = +$this.data('number');
$this.vesta(number);
}
}, '.vesta');
Edit:
I was a bit lazy with explaining the code snippet that I have provided an hour ago, but I am modifying my post now in response to the comments.
This code snippet will allow you to apply listeners from '.vesta1' elements to '.vestaN'
[#Variable]
NumberOfClasses - is the positive integer after 'vesta'. Eg: vesta1 ,vesta2, vesta100 ... etc
var NumberOfClasses=6;
for(var i=1;i<=NumberOfClasses;i++){
var className = '.vesta'+(i+1);
jQuery(className ).on('click', function (e) {
$(this).vesta(i);
});
}

Eventhandlers in a separate document

I'd like to keep all my JavaScripts in a separate document and I like it that way. Now I've had problems with the last bit of code to move from my HTML-code into my separate JavaScript document.
I got two eventhandlers that looked like this:
<a href="http://www.commercial.se" onclick="confirmLeave()" target="_blank">
and
<IMG SRC="folder/pic_small.jpg" alt="Description" onClick="view(this);">
This is the javascript code for the two eventhandlers:
function confirmLeave()
{
if(confirm("Vill du lämna Blomstermåla-Bladet?")) {
return true;
} else {
if(window.event) {
window.event.returnValue = false;
} else {
e.preventDefault();
}
return false;
}
}
And
function view(img) {
imgsrc = img.src.split("_")[0] + "_big.jpg";
viewwin = window.open(imgsrc,'viewwin', "width=790,height=444,location=0");
viewwin.focus();
}
I've managed to solve my problem of not having the javascript code in my HTML document for the first onClick eventhandler by changing my HTML to this:
<a href="http://www.commercial.com" id="external-link" target="_blank">
And adding this to my javascript document:
function init()
{
var link = document.getElementById("external-link");
link.onclick = confirmLeave;
}
window.onload = init;
I've tried adding a similar solution to the other eventhandler but I can't figure out the code I need to use for it to work. I would like to know how to add that event handler into the init function as well.
Try this
<a href="http://www.commercial.com" class="external-link" target="_blank">
<IMG SRC="folder/pic_small.jpg" alt="Description" id = "external-image">
function init() {
var link = document.getElementById("external-link");
var links = document.getElementsByClassName("external-link");
for (var i = 0; i < links.length; i++) {
links[i].onclick = confirmLeave;
}
var image = document.getElementById("external-image");
image.onclick = view;
}
window.onload = init;​
Instead of img in your function just use this
function view() {
imgsrc = this.src.split("_")[0] + "_big.jpg";
viewwin = window.open(imgsrc,'viewwin', "width=790,height=444,location=0");
viewwin.focus();
}
If you don't want to change the view function, you can do something similar, with the slight difference that you need to pass the image as an argument to the view function. You can do this by setting an anonymous function as the click handler.
<IMG SRC="folder/pic_small.jpg" alt="Description" id="some-img">
function init()
{
var img = document.getElementById("some-img");
img.onclick = function(){
view(this);
};
}

Categories

Resources