简体   繁体   中英

Add event listener to element in React from external script

I am working on a React app, but I can't change the actual React code. The only thing I can do: I can add an external script to the footer of page. The script I want to insert into the app is the following:

 $('input').keyup(function(event) { // skip for arrow keys if(event.which >= 37 && event.which <= 40) return; // format number $(this).val(function(index, value) { return value .replace(/\\D/g, "") .replace(/\\B(?=(\\d{3})+(?!\\d))/g, ","); }); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p>Imagine a big react app with some input fields and the above script loaded in the footer using a script tag.</p> <input />

It adds decimal separators to all input elements. I've taken it from https://codepen.io/kdivya/pen/oxVeWz . However, it doesn't work that way, because when the script is loaded, the DOM hasn't been constructed yet. Thus, according to the dev tools, the event listener isn't added to the input elements.

I researched a lot, but all related answers use some React lifecycle stuff, but afaik I can't utilize that from an external script. I also tried adding the event listener within $(document).ready(...), but it didn't work either. I'm open to all ideas (with or without JQuery, it can also use React I just don't know how to get into React structures from "outside").

The main issue is that event if you bound event handlers to the input elements, you have no idea when React will rerender, creating new input elements that don't have your event handlers bound to them. What I would do is use jQuery event delegation to bind to the body , but only listen for events originating from input elements:

 $('body').on('keyup', 'input', function(event) { // skip for arrow keys if(event.which >= 37 && event.which <= 40) return; // format number $(this).val(function(index, value) { return value .replace(/\\D/g, "") .replace(/\\B(?=(\\d{3})+(?!\\d))/g, ","); }); }); // Example class component class Thingy extends React.Component { render() { return ( <input /> ); } } // Render it ReactDOM.render( <Thingy />, document.getElementById("root") );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"/>

But, you may need to manually trigger the change event or something, so that React will "know" that you changed the input's value.

Something like:

$('body').on('keyup', 'input', function(event) {
    // ...
    $(this).trigger('change');
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM